-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7815f15
commit edc3bf8
Showing
16 changed files
with
651 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard1.6</TargetFramework> | ||
<!-- Suppresses the warnings about the package not having assemblies in lib/*/.dll.--> | ||
<NoPackageAnalysis>true</NoPackageAnalysis> | ||
<!-- Change the default location where NuGet will put the build output --> | ||
<BuildOutputTargetFolder>tasks</BuildOutputTargetFolder> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<Authors>Mister Magoo</Authors> | ||
<Copyright>2019 SQL-MisterMagoo</Copyright> | ||
<DevelopmentDependency>true</DevelopmentDependency> | ||
<Description>The easiest way to turn your Client Side Blazor application into a PWA with offline capabilities. | ||
Add this package to your build process and it will generate the files you need to become PWA compatible. | ||
This does not make your application ready for distribution through "App Stores" - it just provides basic PWA functionality.</Description> | ||
<PackageId>Blazor.PWA.MSBuild</PackageId> | ||
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile> | ||
<PackageLicenseExpression></PackageLicenseExpression> | ||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance> | ||
<PackageProjectUrl>https://github.com/SQL-MisterMagoo/Blazor.PWA.MSBuild/src/Blazor.PWA.MSBuild</PackageProjectUrl> | ||
<PackageTags>Blazor,Build,MSBuild,PWA,Manifest,ServiceWorker,C#,DotNET,Web,Client</PackageTags> | ||
<Product>Blazor.PWA.MSBuild</Product> | ||
<RepositoryUrl>https://github.com/SQL-MisterMagoo/Blazor.PWA.MSBuild</RepositoryUrl> | ||
<PackageIconUrl>https://github.com/SQL-MisterMagoo/Blazor.PWA.MSBuild/src/Blazor.PWA.MSBuild/Blazor.PWA.MSBuild-NuGet-Icon.png</PackageIconUrl> | ||
<RepositoryType>git</RepositoryType> | ||
<PackageReleaseNotes>This is a beta release of a very basic PWA build target. | ||
Just by including this in the build, it can generate the basic requirements for an installable PWA for client side Blazor. | ||
The result is not an App Store package, it is simply the basic requirements for PWA. | ||
I will add more network caching strategies, but for now it has just one - cache all local assets.</PackageReleaseNotes> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Update="@(PackageReference)" PrivateAssets="All" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Include="..\LICENSE.txt;..\README.md;"> | ||
<Pack>True</Pack> | ||
<PackagePath></PackagePath> | ||
</None> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="build\Blazor.PWA.MSBuild.Manifest.targets"> | ||
<PackagePath>build\</PackagePath> | ||
<Pack>True</Pack> | ||
</Content> | ||
<Content Include="build\Blazor.PWA.MSBuild.ServiceWorker.targets"> | ||
<PackagePath>build\</PackagePath> | ||
<Pack>True</Pack> | ||
</Content> | ||
<Content Include="build\Blazor.PWA.MSBuild.ServiceWorkerRegister.targets"> | ||
<PackagePath>build\</PackagePath> | ||
<Pack>True</Pack> | ||
</Content> | ||
<Content Include="build\Blazor.PWA.MSBuild.targets"> | ||
<PackagePath>build\</PackagePath> | ||
<Pack>True</Pack> | ||
</Content> | ||
<Content Include="Templates\**\*.js"> | ||
<Pack>True</Pack> | ||
<PackagePath>Templates\</PackagePath> | ||
</Content> | ||
<Content Include="Templates\Images\**\*.*"> | ||
<Pack>True</Pack> | ||
<PackagePath>Templates\</PackagePath> | ||
</Content> | ||
|
||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Folder Include="Templates\Images\" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<Project> | ||
<PropertyGroup> | ||
<VersionPrefix>0.0.1</VersionPrefix> | ||
<VersionSuffix>beta$([System.DateTime]::Now.ToString("yyyyMMdd-HHmmss"))</VersionSuffix> | ||
<VersionSuffix Condition="'$(Configuration)' == 'Release'">beta$([System.DateTime]::Now.ToString("yyyyMMdd-HH"))</VersionSuffix> | ||
</PropertyGroup> | ||
</Project> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions
30
Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_fetch-offline-first.template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
self.addEventListener(networkFetchEvent, event => { | ||
const requestUrl = new URL(event.request.url); | ||
if (requestUrl.origin === location.origin) { | ||
if (requestUrl.pathname === baseURL) { | ||
event.respondWith(caches.match(indexURL)); | ||
return; | ||
} | ||
} | ||
event.respondWith( | ||
caches.match(event.request) | ||
.then(response => { | ||
if (response) { | ||
return response; | ||
} | ||
return fetch(event.request) | ||
.then(response => { | ||
if (response.ok) { | ||
if (requestUrl.origin === location.origin) { | ||
caches.open(staticCacheName).then(cache => { | ||
cache.put(event.request.url, response); | ||
}); | ||
} | ||
} | ||
return response.clone(); | ||
}); | ||
}).catch(error => { | ||
console.error(error); | ||
}) | ||
); | ||
}); |
23 changes: 23 additions & 0 deletions
23
Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_install.template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// * listen for the install event and pre-cache anything in filesToCache * // | ||
self.addEventListener(swInstallEvent, event => { | ||
self.skipWaiting(); | ||
event.waitUntil( | ||
caches.open(staticCacheName) | ||
.then(cache => { | ||
return cache.addAll(requiredFiles); | ||
}) | ||
); | ||
}); | ||
self.addEventListener(swActivateEvent, function (event) { | ||
event.waitUntil( | ||
caches.keys().then(function (cacheNames) { | ||
return Promise.all( | ||
cacheNames.map(function (cacheName) { | ||
if (staticCacheName !== cacheName && cacheName.startsWith(staticCachePrefix)) { | ||
return caches.delete(cacheName); | ||
} | ||
}) | ||
); | ||
}) | ||
); | ||
}); |
93 changes: 93 additions & 0 deletions
93
Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register.template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
window.updateAvailable = new Promise(function (resolve, reject) { | ||
if ('serviceWorker' in navigator) { | ||
navigator.serviceWorker.register(serviceWorkerFileName) | ||
.then(function (registration) { | ||
console.log('Registration successful, scope is:', registration.scope); | ||
registration.onupdatefound = () => { | ||
const installingWorker = registration.installing; | ||
installingWorker.onstatechange = () => { | ||
switch (installingWorker.state) { | ||
case swInstalledEvent: | ||
if (navigator.serviceWorker.controller) { | ||
resolve(true); | ||
} else { | ||
resolve(false); | ||
} | ||
break; | ||
default: | ||
} | ||
}; | ||
}; | ||
}) | ||
.catch(error => | ||
console.log('Service worker registration failed, error:', error)); | ||
} | ||
}); | ||
window['updateAvailable'] | ||
.then(isAvailable => { | ||
if (isAvailable) { | ||
alert("Update available. Reload the page when convenient."); | ||
} | ||
}); | ||
|
||
window.addEventListener('beforeinstallprompt', function (e) { | ||
// Prevent Chrome 67 and earlier from automatically showing the prompt | ||
e.preventDefault(); | ||
// Stash the event so it can be triggered later. | ||
window.PWADeferredPrompt = e; | ||
|
||
showAddToHomeScreen(); | ||
|
||
}); | ||
|
||
function showAddToHomeScreen() { | ||
var pwaInstallPrompt = document.createElement('div'); | ||
var pwaInstallButton = document.createElement('button'); | ||
var pwaCancelButton = document.createElement('button'); | ||
|
||
pwaInstallPrompt.id = 'pwa-install-prompt'; | ||
pwaInstallPrompt.style.position = 'absolute'; | ||
pwaInstallPrompt.style.bottom = '0'; | ||
pwaInstallPrompt.style.display = 'flex'; | ||
pwaInstallPrompt.style.width = '100vw'; | ||
pwaInstallPrompt.style.backgroundColor='darkslategrey'; | ||
pwaInstallPrompt.style.color='white'; | ||
pwaInstallPrompt.style.fontSize='2rem'; | ||
|
||
pwaInstallButton.style.marginLeft='auto'; | ||
pwaInstallButton.style.width='4em'; | ||
pwaInstallButton.style.backgroundColor='green'; | ||
pwaInstallButton.style.color='white'; | ||
|
||
pwaCancelButton.style.marginLeft='0.3rem'; | ||
pwaCancelButton.style.backgroundColor='darkslategray'; | ||
pwaCancelButton.style.color='white'; | ||
|
||
pwaInstallPrompt.innerText = 'Add to your homescreen!'; | ||
pwaInstallButton.innerText = 'OK'; | ||
pwaCancelButton.innerText = 'Ignore'; | ||
|
||
pwaInstallPrompt.appendChild(pwaInstallButton); | ||
pwaInstallPrompt.appendChild(pwaCancelButton); | ||
document.body.appendChild(pwaInstallPrompt); | ||
|
||
pwaInstallButton.addEventListener('click', addToHomeScreen); | ||
pwaCancelButton.addEventListener('click', hideAddToHomeScreen); | ||
setTimeout(hideAddToHomeScreen, 10000); | ||
} | ||
|
||
function hideAddToHomeScreen() { | ||
var pwa = document.getElementById('pwa-install-prompt'); | ||
if (pwa) document.body.removeChild(pwa); | ||
} | ||
|
||
function addToHomeScreen(s, e) { | ||
hideAddToHomeScreen(); | ||
if (window.PWADeferredPrompt) { | ||
window.PWADeferredPrompt.prompt(); | ||
window.PWADeferredPrompt.userChoice | ||
.then(function (choiceResult) { | ||
window.PWADeferredPrompt = null; | ||
}); | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
Blazor.PWA.MSBuild.Tasks/build/Blazor.PWA.MSBuild.Manifest.targets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<Project> | ||
<Target Name="BuildServiceWorkerManifest" Condition="!Exists('$(WWWRoot)$(ManifestFileName)') Or '$(ManifestForce)'=='true'"> | ||
<!-- bit of info in the build output --> | ||
<Message Importance="high" Text="Building Manifest $(ManifestFileName)" Condition="!Exists('$(WWWRoot)$(ManifestFileName)')"/> | ||
<Message Importance="high" Text="Re-Building Manifest $(ManifestFileName)" Condition="Exists('$(WWWRoot)$(ManifestFileName)')"/> | ||
|
||
<PropertyGroup Label="Manifest"> | ||
|
||
<!-- A manifest needs names - if none were provided, use the Solution/Project names --> | ||
<ManifestShortName Condition="'$(ManifestShortName)' == ''">$(SolutionName)</ManifestShortName> | ||
<ManifestLongName Condition="'$(ManifestLongName)' == ''">$(ProjectName)</ManifestLongName> | ||
|
||
<!-- Base URL for the app --> | ||
<ManifestBaseUrl Condition="'$(ManifestBaseUrl)' == ''">/</ManifestBaseUrl> | ||
|
||
<!-- Please see https://developers.google.com/web/fundamentals/web-app-manifest/#display for options --> | ||
<ManifestDisplay Condition="'$(ManifestDisplay)' == ''">standalone</ManifestDisplay> | ||
|
||
<!-- Icons to use if none are supplierd - manifest requires 192x192 and 512x512 --> | ||
<ManifestTemplatePath Condition="'$(ManifestTemplatePath)' == ''">$(MSBuildThisFileDirectory)..\Templates\</ManifestTemplatePath> | ||
<ManifestDefaultIcon192 Condition="'$(ManifestDefaultIcon192)' == ''">$(ManifestTemplatePath)default-icon-192x192.png</ManifestDefaultIcon192> | ||
<ManifestDefaultIcon512 Condition="'$(ManifestDefaultIcon512)' == ''">$(ManifestTemplatePath)default-icon-512x512.png</ManifestDefaultIcon512> | ||
</PropertyGroup> | ||
|
||
|
||
|
||
<!-- Find required icons @ 192x192 and 512x512 --> | ||
<ItemGroup> | ||
<ImageFiles Include="$(ServiceWorkerPreCacheImageFiles);" /> | ||
<IconFiles192 Include="$(WWWRoot)**\*icon*192*.*;"> | ||
<Size>192x192</Size> | ||
</IconFiles192> | ||
<IconFiles512 Include="$(WWWRoot)**\*icon*512*.*;"> | ||
<Size>512x512</Size> | ||
</IconFiles512> | ||
</ItemGroup> | ||
|
||
<!-- Use defualt icons if none were provided as they are required for PWA --> | ||
<Copy Condition="'@(IconFiles192)' == ''" | ||
SourceFiles="$(ManifestDefaultIcon192)" | ||
DestinationFolder="$(WWWRoot)"/> | ||
<Copy Condition="'@(IconFiles512)' == ''" | ||
SourceFiles="$(ManifestDefaultIcon512)" | ||
DestinationFolder="$(WWWRoot)"/> | ||
|
||
<!-- Now we should definitely have the icons we need --> | ||
<ItemGroup> | ||
<IconFiles Include="$(WWWRoot)**\*icon*192*.*;"> | ||
<Size>192x192</Size> | ||
</IconFiles> | ||
<IconFiles Include="$(WWWRoot)**\*icon*512*.*;"> | ||
<Size>512x512</Size> | ||
</IconFiles> | ||
<ManifestText Include="{ | ||
"short_name": "$(ManifestShortName)", | ||
"name": "$(ManifestLongName)", | ||
"start_url": "$(ManifestBaseUrl)", | ||
"display": "$(ManifestDisplay)", | ||
"/> | ||
<ManifestText Include="%20%20"icons": ["/> | ||
<ManifestText Include="@(IconFiles-> ' { | ||
"src":"$(ManifestBaseUrl)%(RecursiveDir)%(Filename)%(Extension)", | ||
"type":"image/%(Extension)", | ||
"sizes":"%(Size)" | ||
}'->Replace('/.','/')->Replace('\','/'),',%0D%0A');%20%20];}"/> | ||
</ItemGroup> | ||
|
||
<!-- Write the manifest --> | ||
<WriteLinesToFile File="$(WWWRoot)$(ManifestFileName)" Overwrite="true" Lines="@(ManifestText);" /> | ||
|
||
<!-- Add manifest to index.html --> | ||
<PropertyGroup> | ||
<IndexFile>$(WWWRoot)$(ServiceWorkerIndexUrl)</IndexFile> | ||
<IndexLines>$([System.IO.File]::ReadAllText($(IndexFile)))</IndexLines> | ||
</PropertyGroup> | ||
|
||
<Message Importance="high" Text="Adding manifest to $(IndexFile)" | ||
Condition="'$(IndexLines.Contains(rel="manifest"))'=='false'"/> | ||
|
||
<WriteLinesToFile | ||
File="$(IndexFile)" | ||
Overwrite="true" | ||
Lines="$(IndexLines.Replace('</head>',' <link href="/$(ManifestFileName)" rel="manifest"/>%0D%0A</head>'))" | ||
Condition="'$(IndexLines.Contains(rel="manifest"))'=='false'"/> | ||
</Target> | ||
</Project> |
Oops, something went wrong.