UNPKG

npm-polymer-elements

Version:

Polymer Elements package for npm

189 lines (180 loc) 9.08 kB
<!-- Copyright (c) 2015 The Polymer Project Authors. All rights reserved. This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as part of the polymer project is also subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt --> <link rel="import" href="../polymer/polymer.html"> <script> /** * The `<platinum-sw-cache>` element makes it easy to precache specific resources, perform runtime * caching, and serve your cached resources when a network is unavailable. * Under the hood, the [sw-toolbox](https://github.com/googlechrome/sw-toolbox) library is used * for all the caching and request handling logic. * `<platinum-sw-cache>` needs to be a child element of `<platinum-sw-register>`. * A simple, yet useful configuration is * * <platinum-sw-register auto-register> * <platinum-sw-cache></platinum-sw-cache> * </platinum-sw-register> * * This is enough to have all of the resources your site uses cached at runtime, both local and * cross-origin. * (It uses the default `defaultCacheStrategy` of "networkFirst".) * When there's a network available, visits to your site will go against the network copy of the * resources, but if someone visits your site when they're offline, all the cached resources will * be used. * * @demo demo/index.html An offline-capable eReader demo. */ Polymer({ is: 'platinum-sw-cache', properties: { /** * Used to configure `<platinum-sw-precache>` behavior via a JSON file instead of via * attributes. This can come in handy when the configuration (e.g. which files to precache) * depends on the results of a build script. * * If configuration for the same properties are provided in both the JSON file and via the * element's attributes, then in general the JSON file's values take precedence. The one * exception is the `precache` property. Any values in the element's `precache` attribute will * be concatenated with the values in the JSON file's `precache` property and the set of files * that are precached will be the union of the two. * * There's one additional option, `precacheFingerprint`, that can be set in the JSON. If using * a build script that might output a large number of files to precache, its recommended * that your build script generate a unique "fingerprint" of the files. Any changes to the * `precacheFingerprint` value will result in the underlying service worker kicking off the * process of caching the files listed in `precache`. * While there are a few different strategies for generating an appropriate * `precacheFingerprint` value, a process that makes sense is to use a stable hash of the * serialized `precache` array. That way, any changes to the list of files in `precache` * will result in a new `precacheFingerprint` value. * If your build script is Node.js based, one way to generate this hash is: * * var md5 = require('crypto').createHash('md5'); * md5.update(JSON.stringify(precache)); * var precacheFingerprint = md5.digest('hex'); * * Alternatively, you could use something like the * [SHA-1 signature](http://stackoverflow.com/questions/1161869/how-to-get-sha-of-the-latest-commit-from-remote-git-repository) * of your latest `git` commit for the `precacheFingerprint` value. * * An example file may look like: * * { * "cacheId": "my-cache-id", * "defaultCacheStrategy": "fastest", * "disabled": false, * "precache": ["file1.html", "file2.css"], * "precacheFingerprint": "FINGERPRINT_OF_FILES_IN_PRECACHE" * } */ cacheConfigFile: String, /** * An id used to construct the name for the * [Cache](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache) * in which all the resources will be stored. * * If nothing is provided, the default value set in * [`toolbox.options.cacheName`](https://github.com/GoogleChrome/sw-toolbox/blob/8763dcc9fbc9352d58f184050e2131c42f7b6d68/lib/options.js#L28) * will be used. * * The `cacheId` is combined with the service worker's scope to construct the cache name, so * two `<platinum-sw-cache>` elements that are associated with different scopes will use * different caches. */ cacheId: String, /** * The caching strategy used for all requests, both for local and cross-origin resources. * * For a list of strategies, see the [`sw-toolbox` documentation](https://github.com/GoogleChrome/sw-toolbox#built-in-handlers). * Specify a strategy as a string, without the "toolbox" prefix. E.g., for * `toolbox.networkFirst`, set `defaultCacheStrategy` to "networkFirst". * * Note that the "cacheFirst" and "cacheOnly" strategies are not recommended, and may be * explicitly prevented in a future release. More information can be found at * https://github.com/PolymerElements/platinum-sw#cacheonly--cachefirst-defaultcachestrategy-considered-harmful * * @see {@link https://github.com/GoogleChrome/sw-toolbox#built-in-handlers} */ defaultCacheStrategy: { type: String, value: 'networkFirst' }, /** * If set to true, this element will not set up service worker caching. This is useful to * conditionally enable or disable caching depending on the build environment. */ disabled: { type: Boolean, value: false }, /** * Used to provide a list of URLs that are always precached as soon as the service worker is * installed. Corresponds to [`sw-toolbox`'s `precache()` method](https://github.com/GoogleChrome/sw-toolbox#toolboxprecachearrayofurls). * * This is useful for URLs that that wouldn't necessarily be picked up by runtime caching, * i.e. a list of resources that are needed by one of the subpages of your site, or a list of * resources that are only loaded via user interaction. * * `precache` can be used in conjunction with `cacheConfigFile`, and the two arrays will be * concatenated. * * @see {@link https://github.com/GoogleChrome/sw-toolbox#toolboxprecachearrayofurls} */ precache: { type: Array, value: function() { return []; } } }, _getParameters: function(baseURI) { return new Promise(function(resolve) { var params = { importscriptLate: new URL('bootstrap/sw-toolbox-setup.js', baseURI).href, defaultCacheStrategy: this.defaultCacheStrategy, precache: this.precache }; if (this.cacheConfigFile) { params.cacheConfigFile = this.cacheConfigFile; window.fetch(this.cacheConfigFile).then(function(response) { if (!response.ok) { throw Error('unable to load ' + this.cacheConfigFile); } return response.json(); }.bind(this)).then(function(config) { this.disabled = config.disabled; if (this.disabled) { // Use an empty set of parameters to effectively disable caching. params = {}; } else { // If there's a hash of the list of files to precache provided in the config file, // then copy that over to the params that will be used to construct the service worker // URL. This works around the issue where a potentially large number of precache // files could result in a longer URL than a browser will allow. // The actual list of files to precache (in config.precache) will be dealt by the // service worker during the install phase, so we can ignore it here. // See https://github.com/PolymerElements/platinum-sw/issues/53 if (config.precacheFingerprint) { params.precacheFingerprint = config.precacheFingerprint; } else { params.precache = params.precache.concat(config.precache); } params.cacheId = config.cacheId || params.cacheId; params.defaultCacheStrategy = config.defaultCacheStrategy || params.defaultCacheStrategy; } }.bind(this)).catch(function(error) { console.info('Skipping precaching: ' + error.message); }).then(function() { resolve(params); }); } else { resolve(params); } }.bind(this)); } }); </script>