diff --git a/service-worker/README.md b/service-worker/README.md index 9b14ca73b4..865f0eb438 100644 --- a/service-worker/README.md +++ b/service-worker/README.md @@ -1,6 +1,11 @@ # Service Worker Recipes -- [Basic registration](https://googlechrome.github.io/samples/service-worker/registration/index.html) - +- [Basic Demo](https://googlechrome.github.io/samples/service-worker/basic/index.html) - +a sample covering a basic, common use case. It precaches a set of local resources in a +versioned cache, and maintains another cache that's populated at runtime as additional +resources are requested. + +- [Simple registration](https://googlechrome.github.io/samples/service-worker/registration/index.html) - a bare-bones sample that simply performs service worker registration, with placeholders for various event handlers. - [Detailed registration](https://googlechrome.github.io/samples/service-worker/registration-events/index.html) - diff --git a/service-worker/basic/README.md b/service-worker/basic/README.md new file mode 100644 index 0000000000..597420d089 --- /dev/null +++ b/service-worker/basic/README.md @@ -0,0 +1,5 @@ +Basic Service Worker Sample +=========================== +See https://googlechrome.github.io/samples/service-worker/basic/index.html for a live demo. + +Learn more at https://www.chromestatus.com/feature/6561526227927040 diff --git a/service-worker/basic/demo.js b/service-worker/basic/demo.js new file mode 100644 index 0000000000..813f453e63 --- /dev/null +++ b/service-worker/basic/demo.js @@ -0,0 +1,11 @@ + +if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('service-worker.js'); +} + +document.querySelector('#show').addEventListener('click', () => { + const iconUrl = document.querySelector('select').selectedOptions[0].value; + let imgElement = document.createElement('img'); + imgElement.src = iconUrl; + document.querySelector('#container').appendChild(imgElement); +}); diff --git a/service-worker/basic/icons/ic_create_new_folder_black_48dp.png b/service-worker/basic/icons/ic_create_new_folder_black_48dp.png new file mode 100755 index 0000000000..6cbb30e536 Binary files /dev/null and b/service-worker/basic/icons/ic_create_new_folder_black_48dp.png differ diff --git a/service-worker/basic/icons/ic_file_upload_black_48dp.png b/service-worker/basic/icons/ic_file_upload_black_48dp.png new file mode 100755 index 0000000000..275bebaadc Binary files /dev/null and b/service-worker/basic/icons/ic_file_upload_black_48dp.png differ diff --git a/service-worker/basic/icons/ic_folder_black_48dp.png b/service-worker/basic/icons/ic_folder_black_48dp.png new file mode 100755 index 0000000000..27e524f611 Binary files /dev/null and b/service-worker/basic/icons/ic_folder_black_48dp.png differ diff --git a/service-worker/basic/icons/ic_folder_open_black_48dp.png b/service-worker/basic/icons/ic_folder_open_black_48dp.png new file mode 100755 index 0000000000..a8435be078 Binary files /dev/null and b/service-worker/basic/icons/ic_folder_open_black_48dp.png differ diff --git a/service-worker/basic/icons/ic_folder_shared_black_48dp.png b/service-worker/basic/icons/ic_folder_shared_black_48dp.png new file mode 100755 index 0000000000..f7e17fc0d7 Binary files /dev/null and b/service-worker/basic/icons/ic_folder_shared_black_48dp.png differ diff --git a/service-worker/basic/index.html b/service-worker/basic/index.html index bd987af283..013a7435a4 100644 --- a/service-worker/basic/index.html +++ b/service-worker/basic/index.html @@ -1,49 +1,100 @@ - - - - - - -
Some nice places to visit: +
+ You can confirm the service worker's behavior using the + Application panel + of Chrome's DevTools. +
+CACHES.PRECACHE
name to pick up
+ new versions after updating anything!
+
+ cache.addAll()
call may be fulfilled with responses from
+ the HTTP cache, depending on the HTTP caching headers you use. If you
+ are using
+ HTTP caching
+ and unversioned resources, it can be safer to
+ cache-bust
+ your precaching requests.
+
+ sw-toolbox
+ which provides
+ cache-expiration
+ is recommended.
+
+ + The following demo illustrates the service worker's runtime caching by loading + images in response to clicking the button below. +
++ The first time a given image is requested, the service worker will be load it + from the network, but each subsequent time, it will be retrieved from the cache. +
+ + + + + +{% include js_snippet.html filename='demo.js' %} +{% include js_snippet.html filename='service-worker.js' displayonly=true title="Service Worker's JavaScript" %} diff --git a/service-worker/basic/readme.md b/service-worker/basic/readme.md deleted file mode 100644 index 178660a0a2..0000000000 --- a/service-worker/basic/readme.md +++ /dev/null @@ -1,14 +0,0 @@ -Service Worker Sample -=== - -See https://googlechrome.github.io/samples/service-worker/basic/index.html for a live demo. - - -#### Directions: - -* Install Chrome, or another browser that supports Service Workers. -* Open the demo at https://googlechrome.github.io/samples/service-worker/basic/index.html [(source)](https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/index.html) -* Open the Developer Tools. Things are logged there later on. -* Try visiting Cleveland and get a 404. Go back. -* Click the 'Register' button, watch the Inspector console, then try visiting Cleveland again... oooh. -* Go to `chrome://inspect#service-workers` and click on `Inspect` to open the Inspector and debug your Service Worker [(source)](https://github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js) diff --git a/service-worker/basic/service-worker.js b/service-worker/basic/service-worker.js index 85b4b1850b..9cc7410d04 100644 --- a/service-worker/basic/service-worker.js +++ b/service-worker/basic/service-worker.js @@ -1,12 +1,76 @@ -self.addEventListener('fetch', function(event) { - console.log('got a request'); +/* + Copyright 2016 Google Inc. All Rights Reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ - var salutation = 'Hello, '; - var whom = decodeURIComponent(event.request.url.match(/\/([^/]*)$/)[1]); - var energyLevel = (whom === 'Cleveland') ? '!!!' : '!'; - var version = '\n\n(Version 1)'; +// Names of the two caches used in this version of the service worker. +// Change to v2, etc. when you update any of the local resources, which will +// in turn trigger the install event again. +const PRECACHE = 'precache-v1'; +const RUNTIME = 'runtime'; - var body = new Blob([salutation, whom, energyLevel, version]); +// A list of local resources we always want to be cached. +const PRECACHE_URLS = [ + 'index.html', + './', // Alias for index.html + 'styles.css', + '../../styles/main.css', + 'demo.js' +]; - event.respondWith(new Response(body)); +// The install handler takes care of precaching the resources we always need. +self.addEventListener('install', event => { + event.waitUntil( + caches.open(PRECACHE) + .then(cache => cache.addAll(PRECACHE_URLS)) + .then(self.skipWaiting()) + ); }); + +// The activate handler takes care of cleaning up old caches. +self.addEventListener('activate', event => { + const currentCaches = [PRECACHE, RUNTIME]; + event.waitUntil( + caches.keys().then(cacheNames => { + return cacheNames.filter(cacheName => !currentCaches.includes(cacheName)); + }).then(cachesToDelete => { + return Promise.all(cachesToDelete.map(cacheToDelete => { + return caches.delete(cacheToDelete); + })); + }).then(() => self.clients.claim()) + ); +}); + +// The fetch handler serves responses for same-origin resources from a cache. +// If no response is found, it populates the runtime cache with the response +// from the network before returning it to the page. +self.addEventListener('fetch', event => { + // Skip cross-origin requests, like those for Google Analytics. + if (event.request.url.startsWith(self.location.origin)) { + event.respondWith( + caches.match(event.request).then(cachedResponse => { + if (cachedResponse) { + return cachedResponse; + } + + return caches.open(RUNTIME).then(cache => { + return fetch(event.request).then(response => { + // Put a copy of the response in the runtime cache. + return cache.put(event.request, response.clone()).then(() => { + return response; + }); + }); + }); + }) + ); + } +}); + diff --git a/service-worker/basic/styles.css b/service-worker/basic/styles.css new file mode 100644 index 0000000000..73a9e2b62a --- /dev/null +++ b/service-worker/basic/styles.css @@ -0,0 +1,10 @@ +#container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-around; +} + +li { + margin-bottom: 1em; +}