polymer-platinum-rails 1.0.0.pre.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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>
|