~didrocks/+junk/face-detection-15.04

« back to all changes in this revision

Viewing changes to facedetection/www/bower_components/platinum-sw/platinum-sw-register.html

  • Committer: Didier Roche
  • Date: 2016-05-10 23:09:11 UTC
  • Revision ID: didier.roche@canonical.com-20160510230911-c7xr490zrj3yrzxd
New version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!--
 
2
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
 
3
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 
4
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 
5
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 
6
Code distributed by Google as part of the polymer project is also
 
7
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 
8
-->
 
9
<link rel="import" href="../polymer/polymer.html">
 
10
 
 
11
<script>
 
12
  /**
 
13
   * The `<platinum-sw-register>` element handles
 
14
   * [service worker](http://www.html5rocks.com/en/tutorials/service-worker/introduction/)
 
15
   * registration, reflects the overall service worker state, and coordinates the configuration
 
16
   * provided by other Service Worker Elements.
 
17
   * `<platinum-sw-register>` is used as a parent element for child elements in the
 
18
   * `<platinum-sw-*>` group.
 
19
   *
 
20
   *     <platinum-sw-register skip-waiting
 
21
   *                           clients-claim
 
22
   *                           auto-register
 
23
   *                           state="{{state}}"
 
24
   *                           on-service-worker-error="handleSWError"
 
25
   *                           on-service-worker-updated="handleSWUpdated"
 
26
   *                           on-service-worker-installed="handleSWInstalled">
 
27
   *       ...one or more <platinum-sw-*> children which share the service worker registration...
 
28
   *     </platinum-sw-register>
 
29
   *
 
30
   * Please see https://github.com/PolymerElements/platinum-sw#top-level-sw-importjs for a
 
31
   * *crucial* prerequisite file you must create before `<platinum-sw-register>` can be used!
 
32
   *
 
33
   * @demo demo/index.html An offline-capable eReader demo.
 
34
   */
 
35
  Polymer({
 
36
    is: 'platinum-sw-register',
 
37
 
 
38
    // Used as an "emergency" switch if we make breaking changes in the way <platinum-sw-register>
 
39
    // talks to service-worker.js. Otherwise, it shouldn't need to change, and isn't meant to be
 
40
    // kept in sync with the element's release number.
 
41
    _version: '1.0',
 
42
 
 
43
    /**
 
44
     * Fired when the initial service worker installation completes successfully.
 
45
     * The service worker will normally only be installed once, the first time a page with a
 
46
     * `<platinum-sw-register>` element is visited in a given browser. If the same page is visited
 
47
     * again, the existing service worker will be reused, and there won't be another
 
48
     * `service-worker-installed` fired.
 
49
     *
 
50
     * @event service-worker-installed
 
51
     * @param {String} A message indicating that the installation succeeded.
 
52
     */
 
53
 
 
54
    /**
 
55
     * Fired when the service worker update flow completes successfully.
 
56
     * If you make changes to your `<platinum-sw-register>` configuration (i.e. by adding in new
 
57
     * `<platinum-sw-*>` child elements, or changing their attributes), users who had the old
 
58
     * service worker installed will get the update installed when they see the modified elements.
 
59
     *
 
60
     * @event service-worker-updated
 
61
     * @param {String} A message indicating that the update succeeded.
 
62
     */
 
63
 
 
64
    /**
 
65
     * Fired when an error prevents the service worker installation from completing.
 
66
     *
 
67
     * @event service-worker-error
 
68
     * @param {String} A message indicating what went wrong.
 
69
     */
 
70
 
 
71
    properties: {
 
72
      /**
 
73
       * Whether this element should automatically register the corresponding service worker as
 
74
       * soon as its added to a page.
 
75
       *
 
76
       * If set to `false`, then the service worker won't be automatically registered, and you
 
77
       * must call this element's `register()` method if you want service worker functionality.
 
78
       * This is useful if, for example, the service worker needs to be configured using
 
79
       * information that isn't immediately available at the time the page loads.
 
80
       *
 
81
       * If set to `true`, the service worker will be automatically registered without having to
 
82
       * call any methods.
 
83
       */
 
84
      autoRegister: {
 
85
        type: Boolean,
 
86
        value: false
 
87
      },
 
88
 
 
89
      /**
 
90
       * The URI used as a base when constructing relative paths to service worker helper libraries
 
91
       * that need to be loaded.
 
92
       *
 
93
       * This can normally be kept set to the default, which will use the directory containing this
 
94
       * element as the base. However, if you [Vulcanize](https://github.com/polymer/vulcanize) your
 
95
       * elements, then the default base might not be appropriate anymore. This will allow you to
 
96
       * override it.
 
97
       *
 
98
       * See https://github.com/PolymerElements/platinum-sw#relative-paths--vulcanization for more
 
99
       * information.
 
100
       */
 
101
      baseUri: {
 
102
        type: String,
 
103
        // Grab the URI of this file to use as a base when resolving relative paths.
 
104
        // See https://github.com/webcomponents/webcomponentsjs/blob/88240ba9ef4cebb1579e07f7888c7b58ec017a39/src/HTMLImports/base.js#L31
 
105
        // for background on document._currentScript. We want to support document.currentScript
 
106
        // as well, on the off chance that the polyfills aren't loaded.
 
107
        // Fallback to './' as a default, though current browsers that don't support
 
108
        // document.currentScript also don't support service workers.
 
109
        value: document._currentScript ? document._currentScript.baseURI :
 
110
          (document.currentScript ? document.currentScript.baseURI : './')
 
111
      },
 
112
 
 
113
      /**
 
114
       * Whether the activated service worker should [take immediate control](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#clients-claim-method)
 
115
       * of any pages under its scope.
 
116
       *
 
117
       * If this is `false`, the service worker won't have any effect until the next time the page
 
118
       * is visited/reloaded.
 
119
       * If this is `true`, it will take control and start handling events for the current page
 
120
       * (and any pages under the same scope open in other tabs/windows) as soon it's active.
 
121
       * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#clients-claim-method}
 
122
       */
 
123
      clientsClaim: {
 
124
        type: Boolean,
 
125
        value: false
 
126
      },
 
127
 
 
128
      /**
 
129
       * The service worker script that is [registered](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register).
 
130
       * The script *should* be located at the top level of your site, to ensure that it is able
 
131
       * to control all the pages on your site.
 
132
       *
 
133
       * It's *strongly* recommended that you create a top-level file named `sw-import.js`
 
134
       * containing only:
 
135
       *
 
136
       * `importScripts('bower_components/platinum-sw/service-worker.js');`
 
137
       *
 
138
       * (adjust to match the path where your `platinum-sw` element directory can be found).
 
139
       *
 
140
       * This will ensure that your service worker script contains everything needed to play
 
141
       * nicely with the Service Worker Elements group.
 
142
       *
 
143
       * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register}
 
144
       */
 
145
      href: {
 
146
        type: String,
 
147
        value: 'sw-import.js'
 
148
      },
 
149
 
 
150
      /**
 
151
       * Whether the page should be automatically reloaded (via `window.location.reload()`) when
 
152
       * the service worker is successfully installed.
 
153
       *
 
154
       * While it's perfectly valid to continue using a page with a freshly installed service
 
155
       * worker, it's a common pattern to want to reload it immediately following the install.
 
156
       * This ensures that, for example, if you're using a `<platinum-sw-cache>` with an on the
 
157
       * fly caching strategy, it will get a chance to intercept all the requests needed to render
 
158
       * your page and store them in the cache.
 
159
       *
 
160
       * If you don't immediately reload your page, then any resources that were loaded before the
 
161
       * service worker was installed (e.g. this `platinum-sw-register.html` file) won't be present
 
162
       * in the cache until the next time the page is loaded.
 
163
       *
 
164
       * Note that this reload will only happen when a service worker is installed for the first
 
165
       * time. If the service worker is subsequently updated, it won't trigger another reload.
 
166
       */
 
167
      reloadOnInstall: {
 
168
        type: Boolean,
 
169
        value: false
 
170
      },
 
171
 
 
172
      /**
 
173
       * By default, the service worker will use a scope that applies to all pages at the same
 
174
       * directory level or lower. This is almost certainly what you want, as illustrated by the
 
175
       * following hypothetical serving setup:
 
176
       *
 
177
       * ```
 
178
       * /root/
 
179
       *   service-worker.js
 
180
       *   index.html
 
181
       *   subdir1/
 
182
       *     index.html
 
183
       *   subdir2/
 
184
       *     index.html
 
185
       * ```
 
186
       *
 
187
       * So by default, registering `/root/service-worker.js` will cause the service worker's scope
 
188
       * to cover `/root/index.html`, `/root/subdir1/index.html`, and /root/subdir2/index.html`.
 
189
       *
 
190
       * If, for some reason, you need to register `/root/service-worker.js` from within
 
191
       * `/root/subdir1/index.html`, *and* you want that registration to only cover
 
192
       * `/root/subdir1/**`, you can override this `scope` property and set it to `'./'`.
 
193
       *
 
194
       * There is more context about default scopes and how scope overrides work in
 
195
       * [this Stack Overflow](http://stackoverflow.com/a/33881341/385997) response.
 
196
       *
 
197
       * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register}
 
198
       */
 
199
      scope: {
 
200
        type: String,
 
201
        value: null
 
202
      },
 
203
 
 
204
      /**
 
205
       * Whether an updated service worker should [bypass the `waiting` state](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-global-scope-skipwaiting)
 
206
       * and immediately become `active`.
 
207
       *
 
208
       * Normally, during an update, the new service worker stays in the
 
209
       * `waiting` state until the current page and any other tabs/windows that are using the old
 
210
       * service worker are unloaded.
 
211
       *
 
212
       * If this is `false`, an updated service worker won't be activated until all instances of
 
213
       * the old server worker have been unloaded.
 
214
       *
 
215
       * If this is `true`, an updated service worker will become `active` immediately.
 
216
       * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-global-scope-skipwaiting}
 
217
       */
 
218
      skipWaiting: {
 
219
        type: Boolean,
 
220
        value: false
 
221
      },
 
222
 
 
223
      /**
 
224
       * The current state of the service worker registered by this element.
 
225
       *
 
226
       * One of:
 
227
       * - 'installed'
 
228
       * - 'updated'
 
229
       * - 'error'
 
230
       * - 'unsupported'
 
231
       */
 
232
      state: {
 
233
        notify: true,
 
234
        readOnly: true,
 
235
        type: String
 
236
      }
 
237
    },
 
238
 
 
239
    /**
 
240
     * Registers the service worker based on the configuration options in this element and any
 
241
     * child elements.
 
242
     *
 
243
     * If you set the `autoRegister` property to `true`, then this method is called automatically
 
244
     * at page load.
 
245
     * It can be useful to set `autoRegister` to `false` and then explicitly call this method if
 
246
     * there are options that are only configured after the page is loaded.
 
247
     */
 
248
    register: function() {
 
249
      if ('serviceWorker' in navigator) {
 
250
        this._constructServiceWorkerUrl().then(function(serviceWorkerUrl) {
 
251
          this._registerServiceWorker(serviceWorkerUrl);
 
252
        }.bind(this));
 
253
      } else {
 
254
        this._setState('unsupported');
 
255
        this.fire('service-worker-error', 'Service workers are not available in the current browser.');
 
256
      }
 
257
    },
 
258
 
 
259
    _constructServiceWorkerUrl: function() {
 
260
      var paramsPromises = [];
 
261
      var children = Polymer.dom(this).children;
 
262
      var baseUri = new URL(this.baseUri, window.location.href);
 
263
 
 
264
      for (var i = 0; i < children.length; i++) {
 
265
        if (typeof children[i]._getParameters === 'function') {
 
266
          paramsPromises.push(children[i]._getParameters(baseUri));
 
267
        }
 
268
      }
 
269
 
 
270
      return Promise.all(paramsPromises).then(function(paramsResolutions) {
 
271
        var params = {
 
272
          baseURI: baseUri,
 
273
          version: this._version
 
274
        };
 
275
 
 
276
        paramsResolutions.forEach(function(childParams) {
 
277
          Object.keys(childParams).forEach(function(key) {
 
278
            if (Array.isArray(params[key])) {
 
279
              params[key] = params[key].concat(childParams[key]);
 
280
            } else {
 
281
              params[key] = [].concat(childParams[key]);
 
282
            }
 
283
          });
 
284
        });
 
285
 
 
286
        return params;
 
287
      }.bind(this)).then(function(params) {
 
288
        if (params.importscriptLate) {
 
289
          if (params.importscript) {
 
290
            params.importscript = params.importscript.concat(params.importscriptLate);
 
291
          } else {
 
292
            params.importscript = params.importscriptLate;
 
293
          }
 
294
        }
 
295
 
 
296
        if (params.importscript) {
 
297
          params.importscript = this._unique(params.importscript);
 
298
        }
 
299
 
 
300
        // We've already concatenated importscriptLate, so don't include it in the serialized URL.
 
301
        delete params.importscriptLate;
 
302
 
 
303
        params.clientsClaim = this.clientsClaim;
 
304
        params.skipWaiting = this.skipWaiting;
 
305
 
 
306
        var serviceWorkerUrl = new URL(this.href, window.location);
 
307
        // It's very important to ensure that the serialization is stable.
 
308
        // Serializing the same settings should always produce the same URL.
 
309
        // Serializing different settings should always produce a different URL.
 
310
        // This ensures that the service worker upgrade flow is triggered when settings change.
 
311
        serviceWorkerUrl.search = this._serializeUrlParams(params);
 
312
 
 
313
        return serviceWorkerUrl;
 
314
      }.bind(this));
 
315
    },
 
316
 
 
317
    _unique: function(arr) {
 
318
      return arr.filter(function(item, index) {
 
319
        return arr.indexOf(item) === index;
 
320
      });
 
321
    },
 
322
 
 
323
    _serializeUrlParams: function(params) {
 
324
      return Object.keys(params).sort().map(function(key) {
 
325
        // encodeURIComponent(['a', 'b']) => 'a%2Cb',
 
326
        // so this will still work when the values are Arrays.
 
327
        // TODO: It won't work if the values in the Arrays have ',' characters in them.
 
328
        return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
 
329
      }).join('&');
 
330
    },
 
331
 
 
332
    _registerServiceWorker: function(serviceWorkerUrl) {
 
333
      var options = this.scope ? {scope: this.scope} : null;
 
334
      navigator.serviceWorker.register(serviceWorkerUrl, options).then(function(registration) {
 
335
        if (registration.active) {
 
336
          this._setState('installed');
 
337
        }
 
338
 
 
339
        registration.onupdatefound = function() {
 
340
          var installingWorker = registration.installing;
 
341
          installingWorker.onstatechange = function() {
 
342
            switch (installingWorker.state) {
 
343
              case 'installed':
 
344
                if (navigator.serviceWorker.controller) {
 
345
                  this._setState('updated');
 
346
                  this.fire('service-worker-updated',
 
347
                    'A new service worker was installed, replacing the old service worker.');
 
348
                } else {
 
349
                  if (this.reloadOnInstall) {
 
350
                    window.location.reload();
 
351
                  } else {
 
352
                    this._setState('installed');
 
353
                    this.fire('service-worker-installed', 'A new service worker was installed.');
 
354
                  }
 
355
                }
 
356
              break;
 
357
 
 
358
              case 'redundant':
 
359
                this._setState('error');
 
360
                this.fire('service-worker-error', 'The installing service worker became redundant.');
 
361
              break;
 
362
            }
 
363
          }.bind(this);
 
364
        }.bind(this);
 
365
      }.bind(this)).catch(function(error) {
 
366
        this._setState('error');
 
367
        this.fire('service-worker-error', error.toString());
 
368
        if (error.name === 'NetworkError') {
 
369
          var location = serviceWorkerUrl.origin + serviceWorkerUrl.pathname;
 
370
          console.error('A valid service worker script was not found at ' + location + '\n' +
 
371
            'To learn how to fix this, please see\n' +
 
372
            'https://github.com/PolymerElements/platinum-sw#top-level-sw-importjs');
 
373
        }
 
374
      }.bind(this));
 
375
    },
 
376
 
 
377
    attached: function() {
 
378
      if (this.autoRegister) {
 
379
        this.async(this.register);
 
380
      }
 
381
    }
 
382
  });
 
383
</script>