npm-polymer-elements
Version:
Polymer Elements package for npm
189 lines (180 loc) • 9.08 kB
HTML
<!--
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>