1/*global self, caches */ 2 3// This is the service worker code that lives at the root (sw.js) 4'use strict'; 5 6// You have to supply a name for your cache, this will 7// allow us to remove an old one to avoid hitting disk 8// space limits and displaying old resources 9var cacheName = 'v1'; 10 11// Change for your sitemap's path if that's what 12// you'll use to get your blog's pages 13var sitemapUrl = ''; 14 15// Assets to cache 16// The items to cache at this point should be something you don't forsee 17// changing often, such as base styles, scripts, fonts, logos, etc. 18var assetsToCache = [ 19 '/assets/styles/css/style.css', 20 '/assets/scripts/min/fatkit.min.js' 21 // Add any image files you might need here too 22]; 23 24self.addEventListener('install', function(event) 25{ 26 27 // waitUntil() ensures that the Service Worker will not 28 // install until the code inside has successfully occurred 29 event.waitUntil( 30 // Create cache with the name supplied above and 31 // return a promise for it 32 caches.open(cacheName).then(function(cache) 33 { 34 35 if(sitemapUrl !== '') 36 { 37 38 // Add all assets to cache 39 cache.addAll(assetsToCache); 40 41 // Get your blog's pages and add them to cache 42 cachePages(cache); 43 44 } else { 45 46 // Important to `return` the promise here to have `skipWaiting()` 47 // fire after the cache has been updated. 48 return cache.addAll(assetsToCache); 49 50 } 51 52 }) 53 .then(function () 54 { 55 56 // `skipWaiting()` forces the waiting ServiceWorker to become the 57 // active ServiceWorker, triggering the `onactivate` event. 58 // Together with `Clients.claim()` this allows a worker to take effect 59 // immediately in the client(s). 60 return self.skipWaiting(); 61 62 }) 63 .catch(function(e) 64 { 65 66 console.error('[FatKit] Service worker error occured when trying to add files to cache. Do the files specified in the assetsToCache array (in sw.js) exist? Error:', e); 67 68 }) 69 ); 70 71}); 72 73// Activate event 74// Be sure to call self.clients.claim() 75self.addEventListener('activate', function(event) 76{ 77 78 // `claim()` sets this worker as the active worker for all clients that 79 // match the workers scope and triggers an `oncontrollerchange` event for 80 // the clients. 81 return self.clients.claim(); 82 83}); 84 85function cachePages(cache) 86{ 87 88 // Get sitemap and return the text response 89 fetch(sitemapUrl).then(function(response) 90 { 91 92 return response.text(); 93 94 }).then(function(text) 95 { 96 97 // Regex to match xml locations (URLs) 98 var pattern = /<loc>(.+?)</g; 99 // Get all matches within the text 100 var urls = getMatches(text, pattern); 101 // Add them to the previously opened cache 102 cache.addAll(urls); 103 104 }); 105 106} 107 108// Simple function to get multiple matched groups 109function getMatches(string, regex) 110{ 111 112 var matches = []; 113 var match; 114 while(match = regex.exec(string)) 115 { 116 117 matches.push(match[1]); 118 119 } 120 return matches; 121 122} 123 124self.addEventListener('fetch', function(event) 125{ 126 127 // Get current path 128 var requestUrl = new URL(event.request.url); 129 130 // Ignore non-get request like when accessing the admin panel 131 if(event.request.method !== 'GET') 132 { 133 return; 134 } 135 136 // Don't try to handle non-secure assets because fetch will fail 137 if(/http:/.test(event.request.url)) 138 { 139 return; 140 } 141 142 // Don't try and cache the umbraco back end 143 if(/umbraco/.test(event.request.url)) 144 { 145 return 146 } 147 148 // Ignore certain file types 149 // Necessary for PDFs (and maybe others), as service workers won't fetch files in an <embed> or <object> tag, 150 // but browsers may use these tags with their native file viewers (eg, Chrome's PDF viewer uses embed) 151 // Reference: https://www.chromestatus.com/feature/6313531834105856 152 var ignoreFileExtensions = [ 'pdf' ]; 153 154 var fileExtRegex = /\.([A-z]*)$/gm; 155 var fileExtMatch = fileExtRegex.exec(requestUrl.pathname); 156 157 if (fileExtMatch && ignoreFileExtensions.includes(fileExtMatch[1])) 158 { 159 console.log(`[FatKit] Service worker ignored this ${fileExtMatch[1].toUpperCase()} file: `, requestUrl.href); 160 return; 161 } 162 163 // Save all resources on origin path only, or img.fat.dev images 164 if(requestUrl.origin === location.origin || requestUrl.origin === "https://img.fat.dev") 165 { 166 167 // To cache specific page check it here 168 // if(requestUrl.pathname === '/') 169 // { 170 171 // Here's where we cache all the things! 172 event.respondWith( 173 // Open the cache created when install 174 caches.open(cacheName).then(function(cache) 175 { 176 177 // Go to the network to ask for that resource
178 return fetch(event.request).then(function(networkResponse) 179 { 180 181 // .NET returns a vary header of '*' under certain 182 // scenarios, which is invalid for putting in the cache 183 var varyHeader = networkResponse.headers.get('vary'); 184 if (varyHeader === '*') { 185 return networkResponse; 186 } 187 188 // Add a copy of the response to the cache (updating the old version) 189 cache.put(event.request, networkResponse.clone()); 190 191 // Respond with it 192 return networkResponse; 193 194 }).catch(function() 195 { 196 197 // If there is no internet connection, try to match the request 198 // to some of our cached resources 199 return cache.match(event.request); 200 201 }); 202 203 }) 204 ); 205 206 // } 207 208 } 209 210});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.