| 
1 | 1 | 'use strict';  | 
 | 2 | +const MANIFEST = 'flutter-app-manifest';  | 
 | 3 | +const TEMP = 'flutter-temp-cache';  | 
2 | 4 | const CACHE_NAME = 'flutter-app-cache';  | 
3 | 5 | const RESOURCES = {  | 
4 |  | -  "/index.html": "586ceada6c8fe349bd345099af0715d8",  | 
5 |  | -"/main.dart.js": "6f845bf9ea3aed21bbf8ada9fa3f2a3f",  | 
6 |  | -"/assets/LICENSE": "f735d46327889dff9a8f2afc0912e923",  | 
7 |  | -"/assets/AssetManifest.json": "2efbb41d7877d10aac9d091f58ccd7b9",  | 
8 |  | -"/assets/FontManifest.json": "01700ba55b08a6141f33e168c4a6c22f",  | 
9 |  | -"/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "115e937bb829a890521f72d2e664b632",  | 
10 |  | -"/assets/fonts/MaterialIcons-Regular.ttf": "56d3ffdef7a25659eab6a68a3fbfaf16"  | 
 | 6 | +  "version.json": "3cd6f815d9c5d07f0f911f700a1b794f",  | 
 | 7 | +"index.html": "586ceada6c8fe349bd345099af0715d8",  | 
 | 8 | +"/": "586ceada6c8fe349bd345099af0715d8",  | 
 | 9 | +"main.dart.js": "accbe5718f9ba09566d794f2e928dccb",  | 
 | 10 | +"assets/AssetManifest.json": "2efbb41d7877d10aac9d091f58ccd7b9",  | 
 | 11 | +"assets/NOTICES": "6c189b91b43a3a483186be04162c19cf",  | 
 | 12 | +"assets/FontManifest.json": "dc3d03800ccca4601324923c0b1d6d57",  | 
 | 13 | +"assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "b14fcf3ee94e3ace300b192e9e7c8c5d",  | 
 | 14 | +"assets/fonts/MaterialIcons-Regular.otf": "1288c9e28052e028aba623321f7826ac"  | 
11 | 15 | };  | 
12 | 16 | 
 
  | 
13 |  | -self.addEventListener('activate', function (event) {  | 
14 |  | -  event.waitUntil(  | 
15 |  | -    caches.keys().then(function (cacheName) {  | 
16 |  | -      return caches.delete(cacheName);  | 
17 |  | -    }).then(function (_) {  | 
18 |  | -      return caches.open(CACHE_NAME);  | 
19 |  | -    }).then(function (cache) {  | 
20 |  | -      return cache.addAll(Object.keys(RESOURCES));  | 
 | 17 | +// The application shell files that are downloaded before a service worker can  | 
 | 18 | +// start.  | 
 | 19 | +const CORE = [  | 
 | 20 | +  "/",  | 
 | 21 | +"main.dart.js",  | 
 | 22 | +"index.html",  | 
 | 23 | +"assets/NOTICES",  | 
 | 24 | +"assets/AssetManifest.json",  | 
 | 25 | +"assets/FontManifest.json"];  | 
 | 26 | +// During install, the TEMP cache is populated with the application shell files.  | 
 | 27 | +self.addEventListener("install", (event) => {  | 
 | 28 | +  self.skipWaiting();  | 
 | 29 | +  return event.waitUntil(  | 
 | 30 | +    caches.open(TEMP).then((cache) => {  | 
 | 31 | +      return cache.addAll(  | 
 | 32 | +        CORE.map((value) => new Request(value + '?revision=' + RESOURCES[value], {'cache': 'reload'})));  | 
21 | 33 |     })  | 
22 | 34 |   );  | 
23 | 35 | });  | 
24 | 36 | 
 
  | 
25 |  | -self.addEventListener('fetch', function (event) {  | 
26 |  | -  event.respondWith(  | 
27 |  | -    caches.match(event.request)  | 
28 |  | -      .then(function (response) {  | 
29 |  | -        if (response) {  | 
30 |  | -          return response;  | 
 | 37 | +// During activate, the cache is populated with the temp files downloaded in  | 
 | 38 | +// install. If this service worker is upgrading from one with a saved  | 
 | 39 | +// MANIFEST, then use this to retain unchanged resource files.  | 
 | 40 | +self.addEventListener("activate", function(event) {  | 
 | 41 | +  return event.waitUntil(async function() {  | 
 | 42 | +    try {  | 
 | 43 | +      var contentCache = await caches.open(CACHE_NAME);  | 
 | 44 | +      var tempCache = await caches.open(TEMP);  | 
 | 45 | +      var manifestCache = await caches.open(MANIFEST);  | 
 | 46 | +      var manifest = await manifestCache.match('manifest');  | 
 | 47 | +      // When there is no prior manifest, clear the entire cache.  | 
 | 48 | +      if (!manifest) {  | 
 | 49 | +        await caches.delete(CACHE_NAME);  | 
 | 50 | +        contentCache = await caches.open(CACHE_NAME);  | 
 | 51 | +        for (var request of await tempCache.keys()) {  | 
 | 52 | +          var response = await tempCache.match(request);  | 
 | 53 | +          await contentCache.put(request, response);  | 
 | 54 | +        }  | 
 | 55 | +        await caches.delete(TEMP);  | 
 | 56 | +        // Save the manifest to make future upgrades efficient.  | 
 | 57 | +        await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES)));  | 
 | 58 | +        return;  | 
 | 59 | +      }  | 
 | 60 | +      var oldManifest = await manifest.json();  | 
 | 61 | +      var origin = self.location.origin;  | 
 | 62 | +      for (var request of await contentCache.keys()) {  | 
 | 63 | +        var key = request.url.substring(origin.length + 1);  | 
 | 64 | +        if (key == "") {  | 
 | 65 | +          key = "/";  | 
31 | 66 |         }  | 
32 |  | -        return fetch(event.request);  | 
 | 67 | +        // If a resource from the old manifest is not in the new cache, or if  | 
 | 68 | +        // the MD5 sum has changed, delete it. Otherwise the resource is left  | 
 | 69 | +        // in the cache and can be reused by the new service worker.  | 
 | 70 | +        if (!RESOURCES[key] || RESOURCES[key] != oldManifest[key]) {  | 
 | 71 | +          await contentCache.delete(request);  | 
 | 72 | +        }  | 
 | 73 | +      }  | 
 | 74 | +      // Populate the cache with the app shell TEMP files, potentially overwriting  | 
 | 75 | +      // cache files preserved above.  | 
 | 76 | +      for (var request of await tempCache.keys()) {  | 
 | 77 | +        var response = await tempCache.match(request);  | 
 | 78 | +        await contentCache.put(request, response);  | 
 | 79 | +      }  | 
 | 80 | +      await caches.delete(TEMP);  | 
 | 81 | +      // Save the manifest to make future upgrades efficient.  | 
 | 82 | +      await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES)));  | 
 | 83 | +      return;  | 
 | 84 | +    } catch (err) {  | 
 | 85 | +      // On an unhandled exception the state of the cache cannot be guaranteed.  | 
 | 86 | +      console.error('Failed to upgrade service worker: ' + err);  | 
 | 87 | +      await caches.delete(CACHE_NAME);  | 
 | 88 | +      await caches.delete(TEMP);  | 
 | 89 | +      await caches.delete(MANIFEST);  | 
 | 90 | +    }  | 
 | 91 | +  }());  | 
 | 92 | +});  | 
 | 93 | + | 
 | 94 | +// The fetch handler redirects requests for RESOURCE files to the service  | 
 | 95 | +// worker cache.  | 
 | 96 | +self.addEventListener("fetch", (event) => {  | 
 | 97 | +  if (event.request.method !== 'GET') {  | 
 | 98 | +    return;  | 
 | 99 | +  }  | 
 | 100 | +  var origin = self.location.origin;  | 
 | 101 | +  var key = event.request.url.substring(origin.length + 1);  | 
 | 102 | +  // Redirect URLs to the index.html  | 
 | 103 | +  if (key.indexOf('?v=') != -1) {  | 
 | 104 | +    key = key.split('?v=')[0];  | 
 | 105 | +  }  | 
 | 106 | +  if (event.request.url == origin || event.request.url.startsWith(origin + '/#') || key == '') {  | 
 | 107 | +    key = '/';  | 
 | 108 | +  }  | 
 | 109 | +  // If the URL is not the RESOURCE list then return to signal that the  | 
 | 110 | +  // browser should take over.  | 
 | 111 | +  if (!RESOURCES[key]) {  | 
 | 112 | +    return;  | 
 | 113 | +  }  | 
 | 114 | +  // If the URL is the index.html, perform an online-first request.  | 
 | 115 | +  if (key == '/') {  | 
 | 116 | +    return onlineFirst(event);  | 
 | 117 | +  }  | 
 | 118 | +  event.respondWith(caches.open(CACHE_NAME)  | 
 | 119 | +    .then((cache) =>  {  | 
 | 120 | +      return cache.match(event.request).then((response) => {  | 
 | 121 | +        // Either respond with the cached resource, or perform a fetch and  | 
 | 122 | +        // lazily populate the cache.  | 
 | 123 | +        return response || fetch(event.request).then((response) => {  | 
 | 124 | +          cache.put(event.request, response.clone());  | 
 | 125 | +          return response;  | 
 | 126 | +        });  | 
33 | 127 |       })  | 
 | 128 | +    })  | 
34 | 129 |   );  | 
35 | 130 | });  | 
 | 131 | + | 
 | 132 | +self.addEventListener('message', (event) => {  | 
 | 133 | +  // SkipWaiting can be used to immediately activate a waiting service worker.  | 
 | 134 | +  // This will also require a page refresh triggered by the main worker.  | 
 | 135 | +  if (event.data === 'skipWaiting') {  | 
 | 136 | +    self.skipWaiting();  | 
 | 137 | +    return;  | 
 | 138 | +  }  | 
 | 139 | +  if (event.data === 'downloadOffline') {  | 
 | 140 | +    downloadOffline();  | 
 | 141 | +    return;  | 
 | 142 | +  }  | 
 | 143 | +});  | 
 | 144 | + | 
 | 145 | +// Download offline will check the RESOURCES for all files not in the cache  | 
 | 146 | +// and populate them.  | 
 | 147 | +async function downloadOffline() {  | 
 | 148 | +  var resources = [];  | 
 | 149 | +  var contentCache = await caches.open(CACHE_NAME);  | 
 | 150 | +  var currentContent = {};  | 
 | 151 | +  for (var request of await contentCache.keys()) {  | 
 | 152 | +    var key = request.url.substring(origin.length + 1);  | 
 | 153 | +    if (key == "") {  | 
 | 154 | +      key = "/";  | 
 | 155 | +    }  | 
 | 156 | +    currentContent[key] = true;  | 
 | 157 | +  }  | 
 | 158 | +  for (var resourceKey in Object.keys(RESOURCES)) {  | 
 | 159 | +    if (!currentContent[resourceKey]) {  | 
 | 160 | +      resources.push(resourceKey);  | 
 | 161 | +    }  | 
 | 162 | +  }  | 
 | 163 | +  return contentCache.addAll(resources);  | 
 | 164 | +}  | 
 | 165 | + | 
 | 166 | +// Attempt to download the resource online before falling back to  | 
 | 167 | +// the offline cache.  | 
 | 168 | +function onlineFirst(event) {  | 
 | 169 | +  return event.respondWith(  | 
 | 170 | +    fetch(event.request).then((response) => {  | 
 | 171 | +      return caches.open(CACHE_NAME).then((cache) => {  | 
 | 172 | +        cache.put(event.request, response.clone());  | 
 | 173 | +        return response;  | 
 | 174 | +      });  | 
 | 175 | +    }).catch((error) => {  | 
 | 176 | +      return caches.open(CACHE_NAME).then((cache) => {  | 
 | 177 | +        return cache.match(event.request).then((response) => {  | 
 | 178 | +          if (response != null) {  | 
 | 179 | +            return response;  | 
 | 180 | +          }  | 
 | 181 | +          throw error;  | 
 | 182 | +        });  | 
 | 183 | +      });  | 
 | 184 | +    })  | 
 | 185 | +  );  | 
 | 186 | +}  | 
0 commit comments