Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: polymer_1.0.4/bower_components/platinum-push-messaging/platinum-push-messaging.html

Issue 1205703007: Add polymer 1.0 to npm_modules (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Renamed folder to 1.0.4 Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!--
2 @license
3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
4 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt
5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt
7 Code distributed by Google as part of the polymer project is also
8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
9 -->
10 <link rel="import" href="../polymer/polymer.html">
11
12 <script>
13 (function() {
14 'use strict';
15 // TODO: Doesn't work for IE or Safari, and the usual
16 // document.getElementsByTagName('script') workaround seems to be broken by
17 // HTML imports. Not important for now as neither of those browsers support
18 // service worker yet.
19 var currentScript = document.currentScript.baseURI;
20
21 var SCOPE = new URL('./$$platinum-push-messaging$$/', currentScript).href;
22 var WORKER_URL = new URL('./service-worker.js', currentScript).href;
23
24 var BASE_URL = new URL('./', document.location.href).href;
25
26 var SUPPORTED = 'serviceWorker' in navigator &&
27 'PushManager' in window &&
28 'Notification' in window;
29
30 /**
31 * @const {Number} The desired version of the service worker to use. This is
32 * not strictly tied to anything except that it should be changed whenever
33 * a breaking change is made to the service worker code.
34 */
35 var VERSION = 1;
36
37 // This allows us to use the PushSubscription attribute type in browsers
38 // where it is not defined.
39 if (!('PushSubscription' in window)) {
40 window.PushSubscription = {};
41 }
42
43 /**
44 * `<platinum-push-messaging>` sets up a [push messaging][1] subscription
45 * and allows you to define what happens when a push message is received.
46 *
47 * The element can be placed anywhere, but should only be used once in a
48 * page. If there are multiple occurrences, only one will be active.
49 *
50 * # Requirements
51 * Push messaging is currently only available in Google Chrome, which
52 * requires you to configure Google Cloud Messaging. Chrome will check that
53 * your page links to a manifest file that contains a `gcm_sender_id` field.
54 * You can find full details of how to set all of this up in the [HTML5
55 * Rocks guide to push notifications][1].
56 *
57 * # Notifcation details
58 * The data for how a notification should be displayed can come from one of
59 * three places.
60 *
61 * Firstly, you can specify a URL from which to fetch the message data.
62 * ```
63 * <platinum-push-messaging
64 * message-url="notification-data.json">
65 * </platinum-push-messaging>
66 * ```
67 *
68 * The second way is to send the message data in the body of
69 * the push message from your server. In this case you do not need to
70 * configure anything in your page:
71 * ```
72 * <platinum-push-messaging></platinum-push-messaging>
73 * ```
74 * **Note that this method is not currently supported by any browser**. It
75 * is, however, defined in the
76 * [draft W3C specification](http://w3c.github.io/push-api/#the-push-event)
77 * and this element should use that data when it is implemented in the
78 * future.
79 *
80 * If a message-url is provided then the message body will be ignored in
81 * favor of the first method.
82 *
83 * Thirdly, you can manually define the attributes on the element:
84 * ```
85 * <platinum-push-messaging
86 * title="Application updated"
87 * message="The application was updated in the background"
88 * icon-url="icon.png"
89 * click-url="notification.html">
90 * </platinum-push-messaging>
91 * ```
92 * These values will also be used as defaults if one of the other methods
93 * does not provide a value for that property.
94 *
95 * # Testing
96 * If you have set up Google Cloud Messaging then you can send push messages
97 * to your browser by following the guide in the [GCM documentation][2].
98 *
99 * However, for quick client testing there are two options. You can use the
100 * `testPush` method, which allows you to simulate a push message that
101 * includes a payload.
102 *
103 * Or, at a lower level, you can open up chrome://serviceworker-internals in
104 * Chrome and use the 'Push' button for the service worker corresponding to
105 * your app.
106 *
107 * [1]: http://updates.html5rocks.com/2015/03/push-notificatons-on-the-open- web
108 * [2]: https://developer.android.com/google/gcm/http.html
109 *
110 * @demo demo/
111 */
112 Polymer({
113 is: 'platinum-push-messaging',
114
115 properties: {
116
117 /**
118 * Indicates whether the Push and Notification APIs are supported by
119 * this browser.
120 */
121 supported: {
122 readOnly: true,
123 type: Boolean,
124 value: SUPPORTED
125 },
126
127 /**
128 * The details of the current push subscription, if any.
129 */
130 subscription: {
131 readOnly: true,
132 type: PushSubscription,
133 notify: true,
134 },
135
136 /**
137 * Indicates the status of the element. If true, push messages will be
138 * received.
139 */
140 enabled: {
141 readOnly: true,
142 type: Boolean,
143 notify: true,
144 value: false
145 },
146
147
148 /**
149 * A URL from which message information can be retrieved.
150 *
151 * When a push event happens that does not contain a message body this
152 * URL will be fetched. The URL is expected to be for a JSON document in
153 * the format:
154 * ```
155 * {
156 * "title": "The title for the notification",
157 * "body": "The message to display in the notification",
158 * "url": "The URL to display when the notification is clicked",
159 * "icon": "The URL of an icon to display with the notification",
160 * "tag": "An identifier that determines which notifications can be di splayed at the same time"
161 * }
162 * ```
163 */
164 messageUrl: String,
165
166 /**
167 * A default notification title.
168 */
169 title: String,
170
171 /**
172 * A default notification message.
173 */
174 message: String,
175
176 /**
177 * A default icon for notifications.
178 */
179 iconUrl: String,
180
181 /**
182 * A default URL to display when a notification is clicked.
183 */
184 clickUrl: {
185 type: String,
186 value: document.location.href
187 },
188
189 /**
190 * A default tag for the notifications that will be generated by
191 * this element. Notifications with the same tag will overwrite one
192 * another, so that only one will be shown at once.
193 */
194 tag: String
195 },
196
197 /**
198 * Fired when a notification is clicked that had the current page as the
199 * click URL.
200 *
201 * @event platinum-push-messaging-click
202 * @param {Object} The push message data used to create the notification
203 */
204
205 /**
206 * Fired when a push message is received but no notification is shown.
207 * This happens when the click URL is for this page and the page is
208 * visible to the user on the screen.
209 *
210 * @event platinum-push-messaging-push
211 * @param {Object} The push message data that was received
212 */
213
214 /**
215 * Fired when an error occurs while enabling or disabling notifications
216 *
217 * @event platinum-push-messaging-error
218 * @param {String} The error message
219 */
220
221 /**
222 * Returns a promise which will resolve to the registration object
223 * associated with our current service worker.
224 *
225 * @return {Promise<ServiceWorkerRegistration>}
226 */
227 _getRegistration: function() {
228 return navigator.serviceWorker.getRegistration(SCOPE);
229 },
230
231 /**
232 * Returns a promise that will resolve when the given registration becomes
233 * active.
234 *
235 * @param registration {ServiceWorkerRegistration}
236 * @return {Promise<undefined>}
237 */
238 _registrationReady: function(registration) {
239 if (registration.active) {
240 return Promise.resolve();
241 }
242
243 var serviceWorker = registration.installing || registration.waiting;
244
245 return new Promise(function(resolve, reject) {
246 // Because the Promise function is called on next tick there is a
247 // small chance that the worker became active already.
248 if (serviceWorker.state === 'activated') {
249 resolve();
250 }
251 var listener = function(event) {
252 if (serviceWorker.state === 'activated') {
253 resolve();
254 } else if (serviceWorker.state === 'redundant') {
255 reject(new Error('Worker became redundant'));
256 } else {
257 return;
258 }
259 serviceWorker.removeEventListener('statechange', listener);
260 };
261 serviceWorker.addEventListener('statechange', listener);
262 });
263 },
264
265 /**
266 * Event handler for the `message` event.
267 *
268 * @param event {MessageEvent}
269 */
270 _messageHandler: function(event) {
271 if (event.data && event.data.source === SCOPE) {
272 switch(event.data.type) {
273 case 'push':
274 this.fire('platinum-push-messaging-push', event.data);
275 break;
276 case 'click':
277 this.fire('platinum-push-messaging-click', event.data);
278 break;
279 }
280 }
281 },
282
283 /**
284 * Takes an options object and creates a stable JSON serialization of it.
285 * This naive algorithm will only work if the object contains only
286 * non-nested properties.
287 *
288 * @param options {Object.<String, ?(String|Number|Boolean)>}
289 * @return String
290 */
291 _serializeOptions: function(options) {
292 var props = Object.keys(options);
293 props.sort();
294 var parts = props.filter(function(propName) {
295 return !!options[propName];
296 }).map(function(propName) {
297 return JSON.stringify(propName) + ':' + JSON.stringify(options[propNam e]);
298 });
299 return '{' + parts.join(',') + '}';
300 },
301
302 /**
303 * Determine the URL of the worker based on the currently set parameters
304 *
305 * @return String the URL
306 */
307 _getWorkerURL: function() {
308 var options = this._serializeOptions({
309 tag: this.tag,
310 messageUrl: this.messageUrl,
311 title: this.title,
312 message: this.message,
313 iconUrl: this.iconUrl,
314 clickUrl: this.clickUrl,
315 version: VERSION,
316 baseUrl: BASE_URL
317 });
318
319 return WORKER_URL + '?' + options;
320 },
321
322 /**
323 * Update the subscription property, but only if the value has changed.
324 * This prevents triggering the subscription-changed event twice on page
325 * load.
326 */
327 _updateSubscription: function(subscription) {
328 if (JSON.stringify(subscription) !== JSON.stringify(this.subscription)) {
329 this._setSubscription(subscription);
330 }
331 },
332
333 /**
334 * Programmatically trigger a push message
335 *
336 * @param message {Object} the message payload
337 */
338 testPush: function(message) {
339 this._getRegistration().then(function(registration) {
340 registration.active.postMessage({
341 type: 'test-push',
342 message: message
343 });
344 });
345 },
346
347 /**
348 * Request push messaging to be enabled.
349 *
350 * @return {Promise<undefined>}
351 */
352 enable: function() {
353 if (!this.supported) {
354 this.fire('platinum-push-messaging-error', 'Your browser does not supp ort push notifications');
355 return Promise.resolve();
356 }
357
358 return navigator.serviceWorker.register(this._getWorkerURL(), {scope: SC OPE}).then(function(registration) {
359 return this._registrationReady(registration).then(function() {
360 return registration.pushManager.subscribe({userVisibleOnly: true});
361 });
362 }.bind(this)).then(function(subscription) {
363 this._updateSubscription(subscription);
364 this._setEnabled(true);
365 }.bind(this)).catch(function(error) {
366 this.fire('platinum-push-messaging-error', error.message || error);
367 }.bind(this));
368 },
369
370 /**
371 * Request push messaging to be disabled.
372 *
373 * @return {Promise<undefined>}
374 */
375 disable: function() {
376 if (!this.supported) {
377 return Promise.resolve();
378 }
379
380 return this._getRegistration().then(function(registration) {
381 if (!registration) {
382 return;
383 }
384 return registration.pushManager.getSubscription().then(function(subscr iption) {
385 if (subscription) {
386 return subscription.unsubscribe();
387 }
388 }).then(function() {
389 return registration.unregister();
390 }).then(function() {
391 this._updateSubscription();
392 this._setEnabled(false);
393 }.bind(this)).catch(function(error) {
394 this.fire('platinum-push-messaging-error', error.message || error);
395 }.bind(this));
396 }.bind(this));
397 },
398
399 ready: function() {
400 if (this.supported) {
401 var handler = this._messageHandler.bind(this);
402 // NOTE: We add the event listener twice because the specced and
403 // implemented behaviors do not match. In Chrome 42, messages are
404 // received on window. In the current spec they are supposed to be
405 // received on navigator.serviceWorker.
406 // TODO: Remove the non-spec code in the future.
407 window.addEventListener('message', handler);
408 navigator.serviceWorker.addEventListener('message', handler);
409
410 this._getRegistration().then(function(registration) {
411 if (!registration) {
412 return;
413 }
414 if (registration.active && registration.active.scriptURL !== this._g etWorkerURL()) {
415 // We have an existing worker in this scope, but it is out of date
416 return this.enable();
417 }
418 return registration.pushManager.getSubscription().then(function(subs cription) {
419 this._updateSubscription(subscription);
420 this._setEnabled(true);
421 }.bind(this));
422 }.bind(this));
423 }
424 }
425 });
426 })();
427 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698