polymer-paper-rails 0.1.0

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.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +69 -0
  3. data/Rakefile +1 -0
  4. data/app/assets/components/core/animation/web-animations.html.erb +1 -0
  5. data/app/assets/components/core/animation/web-animations.js +5666 -0
  6. data/app/assets/components/core/icon/core-icon.css +25 -0
  7. data/app/assets/components/core/icon/core-icon.html.erb +126 -0
  8. data/app/assets/components/core/iconset/core-iconset.html.erb +236 -0
  9. data/app/assets/components/core/input/core-input.css +35 -0
  10. data/app/assets/components/core/input/core-input.html.erb +385 -0
  11. data/app/assets/components/core/list/core-list.css +20 -0
  12. data/app/assets/components/core/list/core-list.html.erb +403 -0
  13. data/app/assets/components/core/media-query/core-media-query.html +86 -0
  14. data/app/assets/components/core/menu/core-menu.css +18 -0
  15. data/app/assets/components/core/menu/core-menu.html.erb +62 -0
  16. data/app/assets/components/core/menu/core-submenu.css +29 -0
  17. data/app/assets/components/core/menu/core-submenu.html.erb +106 -0
  18. data/app/assets/components/core/meta/core-meta.html +143 -0
  19. data/app/assets/components/core/overlay/core-key-helper.html +17 -0
  20. data/app/assets/components/core/overlay/core-overlay-layer.html +112 -0
  21. data/app/assets/components/core/overlay/core-overlay.html.erb +661 -0
  22. data/app/assets/components/core/range/core-range.html +106 -0
  23. data/app/assets/components/core/selection/core-selection.html +148 -0
  24. data/app/assets/components/core/selector/core-selector.html.erb +423 -0
  25. data/app/assets/components/core/style/core-style.html +386 -0
  26. data/app/assets/components/core/transition/core-transition-css.html.erb +76 -0
  27. data/app/assets/components/core/transition/core-transition-overlay.css +46 -0
  28. data/app/assets/components/core/transition/core-transition.html.erb +44 -0
  29. data/app/assets/components/paper-button/paper-button.css +115 -0
  30. data/app/assets/components/paper-button/paper-button.html.erb +210 -0
  31. data/app/assets/components/paper-checkbox/paper-checkbox.css +262 -0
  32. data/app/assets/components/paper-checkbox/paper-checkbox.html.erb +104 -0
  33. data/app/assets/components/paper-dialog/paper-dialog-transition.css +59 -0
  34. data/app/assets/components/paper-dialog/paper-dialog-transition.html.erb +27 -0
  35. data/app/assets/components/paper-dialog/paper-dialog.css +0 -0
  36. data/app/assets/components/paper-dialog/paper-dialog.html.erb +176 -0
  37. data/app/assets/components/paper-fab/paper-fab.css +27 -0
  38. data/app/assets/components/paper-fab/paper-fab.html.erb +55 -0
  39. data/app/assets/components/paper-focusable/paper-focusable.html +144 -0
  40. data/app/assets/components/paper-icon-button/paper-icon-button.css +17 -0
  41. data/app/assets/components/paper-icon-button/paper-icon-button.html.erb +87 -0
  42. data/app/assets/components/paper-input/error-100.png +0 -0
  43. data/app/assets/components/paper-input/error-200.png +0 -0
  44. data/app/assets/components/paper-input/paper-input.html.erb +398 -0
  45. data/app/assets/components/paper-input/paper-input.scss +203 -0
  46. data/app/assets/components/paper-item/paper-item.css +30 -0
  47. data/app/assets/components/paper-item/paper-item.html.erb +103 -0
  48. data/app/assets/components/paper-menu-button/paper-menu-button-overlay.html.erb +86 -0
  49. data/app/assets/components/paper-menu-button/paper-menu-button-transition.css +19 -0
  50. data/app/assets/components/paper-menu-button/paper-menu-button-transition.html.erb +118 -0
  51. data/app/assets/components/paper-menu-button/paper-menu-button.css +86 -0
  52. data/app/assets/components/paper-menu-button/paper-menu-button.html.erb +128 -0
  53. data/app/assets/components/paper-progress/paper-progress.css +35 -0
  54. data/app/assets/components/paper-progress/paper-progress.html.erb +98 -0
  55. data/app/assets/components/paper-radio-button/paper-radio-button.css +98 -0
  56. data/app/assets/components/paper-radio-button/paper-radio-button.html.erb +148 -0
  57. data/app/assets/components/paper-radio-group/paper-radio-group.html.erb +68 -0
  58. data/app/assets/components/paper-ripple/paper-ripple.html +426 -0
  59. data/app/assets/components/paper-shadow/paper-shadow.css +81 -0
  60. data/app/assets/components/paper-shadow/paper-shadow.html.erb +212 -0
  61. data/app/assets/components/paper-slider/paper-slider.css +193 -0
  62. data/app/assets/components/paper-slider/paper-slider.html.erb +310 -0
  63. data/app/assets/components/paper-tabs/paper-tab.css +49 -0
  64. data/app/assets/components/paper-tabs/paper-tab.html.erb +66 -0
  65. data/app/assets/components/paper-tabs/paper-tabs.css +57 -0
  66. data/app/assets/components/paper-tabs/paper-tabs.html.erb +127 -0
  67. data/app/assets/components/paper-toast/paper-toast.css +0 -0
  68. data/app/assets/components/paper-toast/paper-toast.html.erb +258 -0
  69. data/app/assets/components/paper-toggle-button/paper-toggle-button.css +61 -0
  70. data/app/assets/components/paper-toggle-button/paper-toggle-button.html.erb +125 -0
  71. data/lib/polymer-paper-rails/engine.rb +4 -0
  72. data/lib/polymer-paper-rails/version.rb +3 -0
  73. data/lib/polymer-paper-rails.rb +2 -0
  74. metadata +158 -0
@@ -0,0 +1,661 @@
1
+ <!--
2
+ Copyright (c) 2014 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
+ <%= html_import_tag "core/transition/core-transition" %>
10
+ <%= html_import_tag "core/overlay/core-key-helper" %>
11
+ <%= html_import_tag "core/overlay/core-overlay-layer" %>
12
+
13
+
14
+ <!--
15
+ The `core-overlay` element displays overlayed on top of other content. It starts
16
+ out hidden and is displayed by setting its `opened` property to true.
17
+ A `core-overlay's` opened state can be toggled by calling the `toggle`
18
+ method.
19
+
20
+ The `core-overlay` will, by default, show/hide itself when it's opened. The
21
+ `target` property may be set to another element to cause that element to
22
+ be shown when the overlay is opened.
23
+
24
+ It's common to want a `core-overlay` to animate to its opened
25
+ position. The `core-overlay` element uses a `core-transition` to handle
26
+ animation. The default transition is `core-transition-fade` which
27
+ causes the overlay to fade in when displayed. See
28
+ <a href="../core-transition/">`core-transition`</a> for more
29
+ information about customizing a `core-overlay's` opening animation. The
30
+ `backdrop` property can be set to true to show a backdrop behind the overlay
31
+ that will darken the rest of the window.
32
+
33
+ An element that should close the `core-overlay` will automatically
34
+ do so if it's given the `core-overlay-toggle` attribute. This attribute
35
+ can be customized with the `closeAttribute` property. You can also use
36
+ `closeSelector` if more general matching is needed.
37
+
38
+ By default `core-overlay` will close whenever the user taps outside it or
39
+ presses the escape key. This behavior can be turned off via the
40
+ `autoCloseDisabled` property.
41
+
42
+ <core-overlay>
43
+ <h2>Dialog</h2>
44
+ <input placeholder="say something..." autofocus>
45
+ <div>I agree with this wholeheartedly.</div>
46
+ <button core-overlay-toggle>OK</button>
47
+ </core-overlay>
48
+
49
+ `core-overlay` will automatically size and position itself according to the
50
+ following rules. If the target's style.top and style.left are unset, the
51
+ target will be centered. The size of the target is constrained to be no larger
52
+ than the window dimensions. The `margin` property specifies the extra amount
53
+ of space that should be reserved around the overlay. This can be used to ensure
54
+ that, for example, a drop shadow is always visible around the overlay.
55
+
56
+ @group Core Elements
57
+ @element core-overlay
58
+ @homepage github.io
59
+ -->
60
+ <!--
61
+ Fired when the `core-overlay`'s `opened` property changes.
62
+
63
+ @event core-overlay-open
64
+ @param {Object} detail
65
+ @param {Object} detail.opened the opened state
66
+ -->
67
+
68
+ <style>
69
+ .core-overlay-backdrop {
70
+ position: fixed;
71
+ top: 0;
72
+ left: 0;
73
+ width: 100vw;
74
+ height: 100vh;
75
+ background-color: black;
76
+ opacity: 0;
77
+ transition: opacity 0.2s;
78
+ }
79
+
80
+ .core-overlay-backdrop.core-opened {
81
+ opacity: 0.6;
82
+ }
83
+ </style>
84
+
85
+ <polymer-element name="core-overlay">
86
+ <script>
87
+ (function() {
88
+
89
+ Polymer('core-overlay', {
90
+
91
+ publish: {
92
+ /**
93
+ * The target element that will be shown when the overlay is
94
+ * opened. If unspecified, the core-overlay itself is the target.
95
+ *
96
+ * @attribute target
97
+ * @type Object
98
+ * @default the overlay element
99
+ */
100
+ target: null,
101
+
102
+
103
+ /**
104
+ * A `core-overlay`'s size is guaranteed to be
105
+ * constrained to the window size. To achieve this, the sizingElement
106
+ * is sized with a max-height/width. By default this element is the
107
+ * target element, but it can be specifically set to a specific element
108
+ * inside the target if that is more appropriate. This is useful, for
109
+ * example, when a region inside the overlay should scroll if needed.
110
+ *
111
+ * @attribute sizingTarget
112
+ * @type Object
113
+ * @default the target element
114
+ */
115
+ sizingTarget: null,
116
+
117
+ /**
118
+ * Set opened to true to show an overlay and to false to hide it.
119
+ * A `core-overlay` may be made initially opened by setting its
120
+ * `opened` attribute.
121
+ * @attribute opened
122
+ * @type boolean
123
+ * @default false
124
+ */
125
+ opened: false,
126
+
127
+ /**
128
+ * If true, the overlay has a backdrop darkening the rest of the screen.
129
+ * The backdrop element is attached to the document body and may be styled
130
+ * with the class `core-overlay-backdrop`. When opened the `core-opened`
131
+ * class is applied.
132
+ *
133
+ * @attribute backdrop
134
+ * @type boolean
135
+ * @default false
136
+ */
137
+ backdrop: false,
138
+
139
+ /**
140
+ * If true, the overlay is guaranteed to display above page content.
141
+ *
142
+ * @attribute layered
143
+ * @type boolean
144
+ * @default false
145
+ */
146
+ layered: false,
147
+
148
+ /**
149
+ * By default an overlay will close automatically if the user
150
+ * taps outside it or presses the escape key. Disable this
151
+ * behavior by setting the `autoCloseDisabled` property to true.
152
+ * @attribute autoCloseDisabled
153
+ * @type boolean
154
+ * @default false
155
+ */
156
+ autoCloseDisabled: false,
157
+
158
+ /**
159
+ * This property specifies an attribute on elements that should
160
+ * close the overlay on tap. Should not set `closeSelector` if this
161
+ * is set.
162
+ *
163
+ * @attribute closeAttribute
164
+ * @type string
165
+ * @default "core-overlay-toggle"
166
+ */
167
+ closeAttribute: 'core-overlay-toggle',
168
+
169
+ /**
170
+ * This property specifies a selector matching elements that should
171
+ * close the overlay on tap. Should not set `closeAttribute` if this
172
+ * is set.
173
+ *
174
+ * @attribute closeSelector
175
+ * @type string
176
+ * @default ""
177
+ */
178
+ closeSelector: '',
179
+
180
+ /**
181
+ * A `core-overlay` target's size is constrained to the window size.
182
+ * The `margin` property specifies a pixel amount around the overlay
183
+ * that will be reserved. It's useful for ensuring that, for example,
184
+ * a shadow displayed outside the target will always be visible.
185
+ *
186
+ * @attribute margin
187
+ * @type number
188
+ * @default 0
189
+ */
190
+ margin: 0,
191
+
192
+ /**
193
+ * The transition property specifies a string which identifies a
194
+ * <a href="../core-transition/">`core-transition`</a> element that
195
+ * will be used to help the overlay open and close. The default
196
+ * `core-transition-fade` will cause the overlay to fade in and out.
197
+ *
198
+ * @attribute transition
199
+ * @type string
200
+ * @default 'core-transition-fade'
201
+ */
202
+ transition: 'core-transition-fade'
203
+
204
+ },
205
+
206
+ captureEventName: 'tap',
207
+ targetListeners: {
208
+ 'tap': 'tapHandler',
209
+ 'keydown': 'keydownHandler',
210
+ 'core-transitionend': 'transitionend'
211
+ },
212
+
213
+ registerCallback: function(element) {
214
+ this.layer = document.createElement('core-overlay-layer');
215
+ this.keyHelper = document.createElement('core-key-helper');
216
+ this.meta = document.createElement('core-transition');
217
+ this.scrim = document.createElement('div');
218
+ this.scrim.className = 'core-overlay-backdrop';
219
+ },
220
+
221
+ ready: function() {
222
+ this.target = this.target || this;
223
+ // flush to ensure styles are installed before paint
224
+ Platform.flush();
225
+ },
226
+
227
+ /**
228
+ * Toggle the opened state of the overlay.
229
+ * @method toggle
230
+ */
231
+ toggle: function() {
232
+ this.opened = !this.opened;
233
+ },
234
+
235
+ /**
236
+ * Open the overlay. This is equivalent to setting the `opened`
237
+ * property to true.
238
+ * @method open
239
+ */
240
+ open: function() {
241
+ this.opened = true;
242
+ },
243
+
244
+ /**
245
+ * Close the overlay. This is equivalent to setting the `opened`
246
+ * property to false.
247
+ * @method close
248
+ */
249
+ close: function() {
250
+ this.opened = false;
251
+ },
252
+
253
+ domReady: function() {
254
+ this.ensureTargetSetup();
255
+ },
256
+
257
+ targetChanged: function(old) {
258
+ if (this.target) {
259
+ // really make sure tabIndex is set
260
+ if (this.target.tabIndex < 0) {
261
+ this.target.tabIndex = -1;
262
+ }
263
+ this.addElementListenerList(this.target, this.targetListeners);
264
+ this.target.style.display = 'none';
265
+ }
266
+ if (old) {
267
+ this.removeElementListenerList(old, this.targetListeners);
268
+ var transition = this.getTransition();
269
+ if (transition) {
270
+ transition.teardown(old);
271
+ } else {
272
+ old.style.position = null;
273
+ old.style.outline = null;
274
+ }
275
+ old.style.display = null;
276
+ }
277
+ },
278
+
279
+ // NOTE: wait to call this until we're as sure as possible that target
280
+ // is styled.
281
+ ensureTargetSetup: function() {
282
+ if (!this.target || this.target.__overlaySetup) {
283
+ return;
284
+ }
285
+ this.target.__overlaySetup = true;
286
+ this.target.style.display = null;
287
+ var transition = this.getTransition();
288
+ if (transition) {
289
+ transition.setup(this.target);
290
+ }
291
+ var computed = getComputedStyle(this.target);
292
+ this.targetStyle = {
293
+ position: computed.position === 'static' ? 'fixed' :
294
+ computed.position
295
+ }
296
+ if (!transition) {
297
+ this.target.style.position = this.targetStyle.position;
298
+ this.target.style.outline = 'none';
299
+ }
300
+ this.target.style.display = 'none';
301
+ },
302
+
303
+ openedChanged: function() {
304
+ this.ensureTargetSetup();
305
+ this.prepareRenderOpened();
306
+ // continue styling after delay so display state can change
307
+ // without aborting transitions
308
+ // note: we wait a full frame so that transition changes executed
309
+ // during measuring do not cause transition
310
+ this.async(function() {
311
+ this.target.style.display = null;
312
+ this.async('renderOpened');
313
+ });
314
+ this.fire('core-overlay-open', this.opened);
315
+ },
316
+
317
+ // tasks which must occur before opening; e.g. making the element visible
318
+ prepareRenderOpened: function() {
319
+ if (this.opened) {
320
+ addOverlay(this);
321
+ }
322
+ this.prepareBackdrop();
323
+ // async so we don't auto-close immediately via a click.
324
+ this.async(function() {
325
+ if (!this.autoCloseDisabled) {
326
+ this.enableElementListener(this.opened, document,
327
+ this.captureEventName, 'captureHandler', true);
328
+ }
329
+ });
330
+ this.enableElementListener(this.opened, window, 'resize',
331
+ 'resizeHandler');
332
+
333
+ if (this.opened) {
334
+ // TODO(sorvell): force SD Polyfill to render
335
+ forcePolyfillRender(this.target);
336
+ if (!this._shouldPosition) {
337
+ this.target.style.position = 'absolute';
338
+ var computed = getComputedStyle(this.target);
339
+ var t = (computed.top === 'auto' && computed.bottom === 'auto');
340
+ var l = (computed.left === 'auto' && computed.right === 'auto');
341
+ this.target.style.position = this.targetStyle.position;
342
+ this._shouldPosition = {top: t, left: l};
343
+ }
344
+ // if we are showing, then take care when measuring
345
+ this.prepareMeasure(this.target);
346
+ this.updateTargetDimensions();
347
+ this.finishMeasure(this.target);
348
+ if (this.layered) {
349
+ this.layer.addElement(this.target);
350
+ this.layer.opened = this.opened;
351
+ }
352
+ }
353
+ },
354
+
355
+ // tasks which cause the overlay to actually open; typically play an
356
+ // animation
357
+ renderOpened: function() {
358
+ var transition = this.getTransition();
359
+ if (transition) {
360
+ transition.go(this.target, {opened: this.opened});
361
+ } else {
362
+ this.transitionend();
363
+ }
364
+ this.renderBackdropOpened();
365
+ },
366
+
367
+ // finishing tasks; typically called via a transition
368
+ transitionend: function(e) {
369
+ // make sure this is our transition event.
370
+ if (e && e.target !== this.target) {
371
+ return;
372
+ }
373
+ if (!this.opened) {
374
+ this.resetTargetDimensions();
375
+ this.target.style.display = 'none';
376
+ this.completeBackdrop();
377
+ removeOverlay(this);
378
+ if (this.layered) {
379
+ if (!currentOverlay()) {
380
+ this.layer.opened = this.opened;
381
+ }
382
+ this.layer.removeElement(this.target);
383
+ }
384
+ }
385
+ this.applyFocus();
386
+ },
387
+
388
+ prepareBackdrop: function() {
389
+ if (this.backdrop && this.opened) {
390
+ if (!this.scrim.parentNode) {
391
+ document.body.appendChild(this.scrim);
392
+ this.scrim.style.zIndex = currentOverlayZ() - 1;
393
+ }
394
+ trackBackdrop(this);
395
+ }
396
+ },
397
+
398
+ renderBackdropOpened: function() {
399
+ if (this.backdrop && getBackdrops().length < 2) {
400
+ this.scrim.classList.toggle('core-opened', this.opened);
401
+ }
402
+ },
403
+
404
+ completeBackdrop: function() {
405
+ if (this.backdrop) {
406
+ trackBackdrop(this);
407
+ if (getBackdrops().length === 0) {
408
+ this.scrim.parentNode.removeChild(this.scrim);
409
+ }
410
+ }
411
+ },
412
+
413
+ prepareMeasure: function(target) {
414
+ target.style.transition = target.style.webkitTransition = 'none';
415
+ target.style.transform = target.style.webkitTransform = 'none';
416
+ target.style.display = null;
417
+ },
418
+
419
+ finishMeasure: function(target) {
420
+ target.style.display = 'none';
421
+ target.style.transform = target.style.webkitTransform = null;
422
+ target.style.transition = target.style.webkitTransition = null;
423
+ },
424
+
425
+ getTransition: function() {
426
+ return this.meta.byId(this.transition);
427
+ },
428
+
429
+ getFocusNode: function() {
430
+ return this.target.querySelector('[autofocus]') || this.target;
431
+ },
432
+
433
+ applyFocus: function() {
434
+ var focusNode = this.getFocusNode();
435
+ if (this.opened) {
436
+ focusNode.focus();
437
+ } else {
438
+ focusNode.blur();
439
+ focusOverlay();
440
+ }
441
+ },
442
+
443
+ updateTargetDimensions: function() {
444
+ this.positionTarget();
445
+ this.sizeTarget();
446
+ //
447
+ if (this.layered) {
448
+ var rect = this.target.getBoundingClientRect();
449
+ this.target.style.top = rect.top + 'px';
450
+ this.target.style.left = rect.left + 'px';
451
+ this.target.style.right = this.target.style.bottom = 'auto';
452
+ }
453
+ },
454
+
455
+ sizeTarget: function() {
456
+ var sizer = this.sizingTarget || this.target;
457
+ var rect = sizer.getBoundingClientRect();
458
+ var mt = rect.top === this.margin ? this.margin : this.margin * 2;
459
+ var ml = rect.left === this.margin ? this.margin : this.margin * 2;
460
+ var h = window.innerHeight - rect.top - mt;
461
+ var w = window.innerWidth - rect.left - ml;
462
+ sizer.style.maxHeight = h + 'px';
463
+ sizer.style.maxWidth = w + 'px';
464
+ sizer.style.boxSizing = 'border-box';
465
+ },
466
+
467
+ positionTarget: function() {
468
+ // vertically and horizontally center if not positioned
469
+ if (this._shouldPosition.top) {
470
+ var t = Math.max((window.innerHeight -
471
+ this.target.offsetHeight - this.margin*2) / 2, this.margin);
472
+ this.target.style.top = t + 'px';
473
+ }
474
+ if (this._shouldPosition.left) {
475
+ var l = Math.max((window.innerWidth -
476
+ this.target.offsetWidth - this.margin*2) / 2, this.margin);
477
+ this.target.style.left = l + 'px';
478
+ }
479
+ },
480
+
481
+ resetTargetDimensions: function() {
482
+ this.target.style.top = this.target.style.left = null;
483
+ this.target.style.right = this.target.style.bottom = null;
484
+ this.target.style.width = this.target.style.height = null;
485
+ this._shouldPosition = null;
486
+ },
487
+
488
+ tapHandler: function(e) {
489
+ // closeSelector takes precedence since closeAttribute has a default non-null value.
490
+ if (e.target &&
491
+ (this.closeSelector && e.target.matches(this.closeSelector)) ||
492
+ (this.closeAttribute && e.target.hasAttribute(this.closeAttribute))) {
493
+ this.toggle();
494
+ } else {
495
+ if (this.autoCloseJob) {
496
+ this.autoCloseJob.stop();
497
+ this.autoCloseJob = null;
498
+ }
499
+ }
500
+ },
501
+
502
+ // We use the traditional approach of capturing events on document
503
+ // to to determine if the overlay needs to close. However, due to
504
+ // ShadowDOM event retargeting, the event target is not useful. Instead
505
+ // of using it, we attempt to close asynchronously and prevent the close
506
+ // if a tap event is immediately heard on the target.
507
+ // TODO(sorvell): This approach will not work with modal. For
508
+ // this we need a scrim.
509
+ captureHandler: function(e) {
510
+ if (!this.autoCloseDisabled && (currentOverlay() == this)) {
511
+ this.autoCloseJob = this.job(this.autoCloseJob, function() {
512
+ this.close();
513
+ });
514
+ }
515
+ },
516
+
517
+ keydownHandler: function(e) {
518
+ if (!this.autoCloseDisabled && (e.keyCode == this.keyHelper.ESCAPE_KEY)) {
519
+ this.close();
520
+ e.stopPropagation();
521
+ }
522
+ },
523
+
524
+ /**
525
+ * Extensions of core-overlay should implement the `resizeHandler`
526
+ * method to adjust the size and position of the overlay when the
527
+ * browser window resizes.
528
+ * @method resizeHandler
529
+ */
530
+ resizeHandler: function() {
531
+ this.updateTargetDimensions();
532
+ },
533
+
534
+ // TODO(sorvell): these utility methods should not be here.
535
+ addElementListenerList: function(node, events) {
536
+ for (var i in events) {
537
+ this.addElementListener(node, i, events[i]);
538
+ }
539
+ },
540
+
541
+ removeElementListenerList: function(node, events) {
542
+ for (var i in events) {
543
+ this.removeElementListener(node, i, events[i]);
544
+ }
545
+ },
546
+
547
+ enableElementListener: function(enable, node, event, methodName, capture) {
548
+ if (enable) {
549
+ this.addElementListener(node, event, methodName, capture);
550
+ } else {
551
+ this.removeElementListener(node, event, methodName, capture);
552
+ }
553
+ },
554
+
555
+ addElementListener: function(node, event, methodName, capture) {
556
+ var fn = this._makeBoundListener(methodName);
557
+ if (node && fn) {
558
+ node.addEventListener(event, fn, capture);
559
+ }
560
+ },
561
+
562
+ removeElementListener: function(node, event, methodName, capture) {
563
+ var fn = this._makeBoundListener(methodName);
564
+ if (node && fn) {
565
+ node.removeEventListener(event, fn, capture);
566
+ }
567
+ },
568
+
569
+ _makeBoundListener: function(methodName) {
570
+ var self = this, method = this[methodName];
571
+ if (!method) {
572
+ return;
573
+ }
574
+ var bound = '_bound' + methodName;
575
+ if (!this[bound]) {
576
+ this[bound] = function(e) {
577
+ method.call(self, e);
578
+ }
579
+ }
580
+ return this[bound];
581
+ },
582
+ });
583
+
584
+ function forcePolyfillRender(target) {
585
+ if (window.ShadowDOMPolyfill) {
586
+ target.offsetHeight;
587
+ }
588
+ }
589
+
590
+ // TODO(sorvell): This should be an element with private state so it can
591
+ // be independent of overlay.
592
+ // track overlays for z-index and focus managemant
593
+ var overlays = [];
594
+ function addOverlay(overlay) {
595
+ var z0 = currentOverlayZ();
596
+ overlays.push(overlay);
597
+ var z1 = currentOverlayZ();
598
+ if (z1 <= z0) {
599
+ applyOverlayZ(overlay, z0);
600
+ }
601
+ }
602
+
603
+ function removeOverlay(overlay) {
604
+ var i = overlays.indexOf(overlay);
605
+ if (i >= 0) {
606
+ overlays.splice(i, 1);
607
+ setZ(overlay, null);
608
+ }
609
+ }
610
+
611
+ function applyOverlayZ(overlay, aboveZ) {
612
+ setZ(overlay.target, aboveZ + 2);
613
+ }
614
+
615
+ function setZ(element, z) {
616
+ element.style.zIndex = z;
617
+ }
618
+
619
+ function currentOverlay() {
620
+ return overlays[overlays.length-1];
621
+ }
622
+
623
+ var DEFAULT_Z = 10;
624
+
625
+ function currentOverlayZ() {
626
+ var z;
627
+ var current = currentOverlay();
628
+ if (current) {
629
+ var z1 = window.getComputedStyle(current.target).zIndex;
630
+ if (!isNaN(z1)) {
631
+ z = Number(z1);
632
+ }
633
+ }
634
+ return z || DEFAULT_Z;
635
+ }
636
+
637
+ function focusOverlay() {
638
+ var current = currentOverlay();
639
+ if (current) {
640
+ current.applyFocus();
641
+ }
642
+ }
643
+
644
+ var backdrops = [];
645
+ function trackBackdrop(element) {
646
+ if (element.opened) {
647
+ backdrops.push(element);
648
+ } else {
649
+ var i = backdrops.indexOf(element);
650
+ if (i >= 0) {
651
+ backdrops.splice(i, 1);
652
+ }
653
+ }
654
+ }
655
+
656
+ function getBackdrops() {
657
+ return backdrops;
658
+ }
659
+ })();
660
+ </script>
661
+ </polymer-element>