polymer-platinum-rails 1.0.0.pre.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +39 -0
- data/Rakefile +1 -0
- data/app/assets/components/platinum-elements/LICENSE +202 -0
- data/app/assets/components/platinum-elements/README.md +2 -0
- data/app/assets/components/platinum-elements/bower.json +19 -0
- data/app/assets/components/platinum-push-messaging/README.md +4 -0
- data/app/assets/components/platinum-push-messaging/bower.json +37 -0
- data/app/assets/components/platinum-push-messaging/demo/index.html +130 -0
- data/app/assets/components/platinum-push-messaging/demo/manifest.json +4 -0
- data/app/assets/components/platinum-push-messaging/index.html +22 -0
- data/app/assets/components/platinum-push-messaging/platinum-push-messaging.html +427 -0
- data/app/assets/components/platinum-push-messaging/service-worker.js +151 -0
- data/app/assets/components/platinum-sw/README.md +43 -0
- data/app/assets/components/platinum-sw/bootstrap/sw-toolbox-setup.js +38 -0
- data/app/assets/components/platinum-sw/bower.json +37 -0
- data/app/assets/components/platinum-sw/demo/index.html +91 -0
- data/app/assets/components/platinum-sw/demo/sw-import.js +1 -0
- data/app/assets/components/platinum-sw/index.html +22 -0
- data/app/assets/components/platinum-sw/platinum-sw-cache.html +116 -0
- data/app/assets/components/platinum-sw/platinum-sw-elements.html +14 -0
- data/app/assets/components/platinum-sw/platinum-sw-fetch.html +130 -0
- data/app/assets/components/platinum-sw/platinum-sw-import-script.html +57 -0
- data/app/assets/components/platinum-sw/platinum-sw-register.html +342 -0
- data/app/assets/components/platinum-sw/service-worker.js +52 -0
- data/app/assets/components/polymer/LICENSE.txt +27 -0
- data/app/assets/components/polymer/bower.json +26 -0
- data/app/assets/components/polymer/build.log +27 -0
- data/app/assets/components/polymer/polymer-micro.html +523 -0
- data/app/assets/components/polymer/polymer-mini.html +1368 -0
- data/app/assets/components/polymer/polymer.html +3768 -0
- data/app/assets/components/sw-toolbox/CONTRIBUTING.md +30 -0
- data/app/assets/components/sw-toolbox/LICENSE +201 -0
- data/app/assets/components/sw-toolbox/README.md +156 -0
- data/app/assets/components/sw-toolbox/bower.json +14 -0
- data/app/assets/components/sw-toolbox/companion.js +23 -0
- data/app/assets/components/sw-toolbox/package.json +21 -0
- data/app/assets/components/sw-toolbox/sw-toolbox.js +148 -0
- data/app/assets/components/sw-toolbox/sw-toolbox.map.json +1 -0
- data/app/assets/components/webcomponentsjs/CustomElements.js +956 -0
- data/app/assets/components/webcomponentsjs/CustomElements.min.js +11 -0
- data/app/assets/components/webcomponentsjs/HTMLImports.js +1078 -0
- data/app/assets/components/webcomponentsjs/HTMLImports.min.js +11 -0
- data/app/assets/components/webcomponentsjs/MutationObserver.js +344 -0
- data/app/assets/components/webcomponentsjs/MutationObserver.min.js +11 -0
- data/app/assets/components/webcomponentsjs/README.md +125 -0
- data/app/assets/components/webcomponentsjs/ShadowDOM.js +4414 -0
- data/app/assets/components/webcomponentsjs/ShadowDOM.min.js +15 -0
- data/app/assets/components/webcomponentsjs/bower.json +14 -0
- data/app/assets/components/webcomponentsjs/build.log +33 -0
- data/app/assets/components/webcomponentsjs/package.json +31 -0
- data/app/assets/components/webcomponentsjs/webcomponents-lite.js +2300 -0
- data/app/assets/components/webcomponentsjs/webcomponents-lite.min.js +13 -0
- data/app/assets/components/webcomponentsjs/webcomponents.js +7112 -0
- data/app/assets/components/webcomponentsjs/webcomponents.min.js +15 -0
- data/lib/polymer-platinum-rails.rb +2 -0
- data/lib/polymer-platinum-rails/engine.rb +4 -0
- data/lib/polymer-platinum-rails/version.rb +3 -0
- metadata +149 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<!--
|
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.github.io/LICENSE
|
5
|
+
The complete set of authors may be found at http://polymer.github.io/AUTHORS
|
6
|
+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
|
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/PATENTS
|
9
|
+
-->
|
10
|
+
<html>
|
11
|
+
<head>
|
12
|
+
<meta charset="utf-8">
|
13
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
14
|
+
|
15
|
+
<script src="../webcomponentsjs/webcomponents-lite.js"></script>
|
16
|
+
<link rel="import" href="../iron-component-page/iron-component-page.html">
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<iron-component-page></iron-component-page>
|
21
|
+
</body>
|
22
|
+
</html>
|
@@ -0,0 +1,427 @@
|
|
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.github.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/CONTRIBUTORS.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/PATENTS.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 displayed 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[propName]);
|
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 support push notifications');
|
355
|
+
return Promise.resolve();
|
356
|
+
}
|
357
|
+
|
358
|
+
return navigator.serviceWorker.register(this._getWorkerURL(), {scope: SCOPE}).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(subscription) {
|
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._getWorkerURL()) {
|
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(subscription) {
|
419
|
+
this._updateSubscription(subscription);
|
420
|
+
this._setEnabled(true);
|
421
|
+
}.bind(this));
|
422
|
+
}.bind(this));
|
423
|
+
}
|
424
|
+
}
|
425
|
+
});
|
426
|
+
})();
|
427
|
+
</script>
|