OLD | NEW |
1 Polymer.IronOverlayManager = (function() { | 1 Polymer.IronOverlayManager = { |
2 | 2 |
3 var overlays = []; | 3 _overlays: [], |
4 var DEFAULT_Z = 10; | 4 |
5 var backdrops = []; | 5 // iframes have a default z-index of 100, so this default should be at least |
| 6 // that. |
| 7 _minimumZ: 101, |
| 8 |
| 9 _backdrops: [], |
| 10 |
| 11 _applyOverlayZ: function(overlay, aboveZ) { |
| 12 this._setZ(overlay, aboveZ + 2); |
| 13 }, |
| 14 |
| 15 _setZ: function(element, z) { |
| 16 element.style.zIndex = z; |
| 17 }, |
6 | 18 |
7 // track overlays for z-index and focus managemant | 19 // track overlays for z-index and focus managemant |
8 function addOverlay(overlay) { | 20 addOverlay: function(overlay) { |
9 var z0 = currentOverlayZ(); | 21 var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ); |
10 overlays.push(overlay); | 22 this._overlays.push(overlay); |
11 var z1 = currentOverlayZ(); | 23 var newZ = this.currentOverlayZ(); |
12 if (z1 <= z0) { | 24 if (newZ <= minimumZ) { |
13 applyOverlayZ(overlay, z0); | 25 this._applyOverlayZ(overlay, minimumZ); |
14 } | 26 } |
15 } | 27 }, |
16 | 28 |
17 function removeOverlay(overlay) { | 29 removeOverlay: function(overlay) { |
18 var i = overlays.indexOf(overlay); | 30 var i = this._overlays.indexOf(overlay); |
19 if (i >= 0) { | 31 if (i >= 0) { |
20 overlays.splice(i, 1); | 32 this._overlays.splice(i, 1); |
21 setZ(overlay, ''); | 33 this._setZ(overlay, ''); |
22 } | 34 } |
23 } | 35 }, |
24 | 36 |
25 function applyOverlayZ(overlay, aboveZ) { | 37 currentOverlay: function() { |
26 setZ(overlay, aboveZ + 2); | 38 var i = this._overlays.length - 1; |
27 } | 39 while (this._overlays[i] && !this._overlays[i].opened) { |
28 | |
29 function setZ(element, z) { | |
30 element.style.zIndex = z; | |
31 } | |
32 | |
33 function currentOverlay() { | |
34 var i = overlays.length - 1; | |
35 while (overlays[i] && !overlays[i].opened) { | |
36 --i; | 40 --i; |
37 } | 41 } |
38 return overlays[i]; | 42 return this._overlays[i]; |
39 } | 43 }, |
40 | 44 |
41 function currentOverlayZ() { | 45 currentOverlayZ: function() { |
42 var z; | 46 var z = this._minimumZ; |
43 var current = currentOverlay(); | 47 var current = this.currentOverlay(); |
44 if (current) { | 48 if (current) { |
45 var z1 = window.getComputedStyle(current).zIndex; | 49 var z1 = window.getComputedStyle(current).zIndex; |
46 if (!isNaN(z1)) { | 50 if (!isNaN(z1)) { |
47 z = Number(z1); | 51 z = Number(z1); |
48 } | 52 } |
49 } | 53 } |
50 return z || DEFAULT_Z; | 54 return z; |
51 } | 55 }, |
52 | 56 |
53 function focusOverlay() { | 57 /** |
54 var current = currentOverlay(); | 58 * Ensures that the minimum z-index of new overlays is at least `minimumZ`. |
| 59 * This does not effect the z-index of any existing overlays. |
| 60 * |
| 61 * @param {number} minimumZ |
| 62 */ |
| 63 ensureMinimumZ: function(minimumZ) { |
| 64 this._minimumZ = Math.max(this._minimumZ, minimumZ); |
| 65 }, |
| 66 |
| 67 focusOverlay: function() { |
| 68 var current = this.currentOverlay(); |
55 // We have to be careful to focus the next overlay _after_ any current | 69 // We have to be careful to focus the next overlay _after_ any current |
56 // transitions are complete (due to the state being toggled prior to the | 70 // transitions are complete (due to the state being toggled prior to the |
57 // transition). Otherwise, we risk infinite recursion when a transitioning | 71 // transition). Otherwise, we risk infinite recursion when a transitioning |
58 // (closed) overlay becomes the current overlay. | 72 // (closed) overlay becomes the current overlay. |
59 // | 73 // |
60 // NOTE: We make the assumption that any overlay that completes a transiti
on | 74 // NOTE: We make the assumption that any overlay that completes a transiti
on |
61 // will call into focusOverlay to kick the process back off. Currently: | 75 // will call into focusOverlay to kick the process back off. Currently: |
62 // transitionend -> _applyFocus -> focusOverlay. | 76 // transitionend -> _applyFocus -> focusOverlay. |
63 if (current && !current.transitioning) { | 77 if (current && !current.transitioning) { |
64 current._applyFocus(); | 78 current._applyFocus(); |
65 } | 79 } |
66 } | 80 }, |
67 | 81 |
68 function trackBackdrop(element) { | 82 trackBackdrop: function(element) { |
69 // backdrops contains the overlays with a backdrop that are currently | 83 // backdrops contains the overlays with a backdrop that are currently |
70 // visible | 84 // visible |
71 if (element.opened) { | 85 if (element.opened) { |
72 backdrops.push(element); | 86 this._backdrops.push(element); |
73 } else { | 87 } else { |
74 var index = backdrops.indexOf(element); | 88 var index = this._backdrops.indexOf(element); |
75 if (index >= 0) { | 89 if (index >= 0) { |
76 backdrops.splice(index, 1); | 90 this._backdrops.splice(index, 1); |
77 } | 91 } |
78 } | 92 } |
| 93 }, |
| 94 |
| 95 getBackdrops: function() { |
| 96 return this._backdrops; |
79 } | 97 } |
80 | 98 |
81 function getBackdrops() { | 99 }; |
82 return backdrops; | |
83 } | |
84 | |
85 return { | |
86 addOverlay: addOverlay, | |
87 removeOverlay: removeOverlay, | |
88 currentOverlay: currentOverlay, | |
89 currentOverlayZ: currentOverlayZ, | |
90 focusOverlay: focusOverlay, | |
91 trackBackdrop: trackBackdrop, | |
92 getBackdrops: getBackdrops | |
93 }; | |
94 | |
95 })(); | |
OLD | NEW |