OLD | NEW |
| (Empty) |
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.g
ithub.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/CONTRI
BUTORS.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/PATEN
TS.txt | |
8 --> | |
9 | |
10 <link rel="import" href="../polymer/polymer.html"> | |
11 <link rel="import" href="../core-overlay/core-overlay.html"> | |
12 | |
13 <!-- | |
14 | |
15 `core-dropdown-overlay` is a helper class to position an overlay relative to ano
ther | |
16 element within the same offsetParent. | |
17 | |
18 @group Polymer Core Elements | |
19 @element core-dropdown-overlay | |
20 @extends core-overlay | |
21 @homepage github.io | |
22 --> | |
23 | |
24 <polymer-element name="core-dropdown-overlay" extends="core-overlay"> | |
25 <script> | |
26 Polymer({ | |
27 | |
28 publish: { | |
29 | |
30 /** | |
31 * The `relatedTarget` is an element used to position the overlay. It sh
ould have | |
32 * the same offsetParent as the target. | |
33 * | |
34 * @attribute relatedTarget | |
35 * @type Node | |
36 */ | |
37 relatedTarget: null, | |
38 | |
39 /** | |
40 * The horizontal alignment of the overlay relative to the `relatedTarge
t`. | |
41 * `left` means the left edges are aligned together and `right` means th
e right | |
42 * edges are aligned together. | |
43 * | |
44 * @attribute halign | |
45 * @type 'left' | 'right' | |
46 * @default 'auto' | |
47 */ | |
48 halign: 'left', | |
49 | |
50 /** | |
51 * The vertical alignment of the overlay relative to the `relatedTarget`
. `top` | |
52 * means the top edges are aligned together and `bottom` means the botto
m edges | |
53 * are aligned together. | |
54 * | |
55 * @attribute valign | |
56 * @type 'top' | 'bottom' | |
57 * @default 'top' | |
58 */ | |
59 valign: 'top' | |
60 | |
61 }, | |
62 | |
63 measure: function() { | |
64 var target = this.target; | |
65 // remember position, because core-overlay may have set the property | |
66 var pos = target.style.position; | |
67 | |
68 // get the size of the target as if it's positioned in the top left | |
69 // corner of the screen | |
70 target.style.position = 'fixed'; | |
71 target.style.left = '0px'; | |
72 target.style.top = '0px'; | |
73 | |
74 var rect = target.getBoundingClientRect(); | |
75 | |
76 target.style.position = pos; | |
77 target.style.left = null; | |
78 target.style.top = null; | |
79 | |
80 return rect; | |
81 }, | |
82 | |
83 resetTargetDimensions: function() { | |
84 var dims = this.dimensions; | |
85 var style = this.target.style; | |
86 if (dims.position.h_by === this.localName) { | |
87 style[dims.position.h] = null; | |
88 } | |
89 if (dims.position.v_by === this.localName) { | |
90 style[dims.position.v] = null; | |
91 } | |
92 this.super(); | |
93 }, | |
94 | |
95 positionTarget: function() { | |
96 if (!this.relatedTarget) { | |
97 this.super(); | |
98 return; | |
99 } | |
100 | |
101 var target = this.target; | |
102 var related = this.relatedTarget; | |
103 | |
104 // explicitly set width/height, because we don't want it constrained | |
105 // to the offsetParent | |
106 var rect = this.measure(); | |
107 target.style.width = rect.width + 'px'; | |
108 target.style.height = rect.height + 'px'; | |
109 | |
110 var t_op = target.offsetParent; | |
111 var r_op = related.offsetParent; | |
112 if (window.ShadowDOMPolyfill) { | |
113 t_op = wrap(t_op); | |
114 r_op = wrap(r_op); | |
115 } | |
116 | |
117 if (t_op !== r_op && t_op !== related) { | |
118 console.warn('core-dropdown-overlay: dropdown\'s offsetParent must be
the relatedTarget or the relatedTarget\'s offsetParent!'); | |
119 } | |
120 | |
121 // Don't use CSS to handle halign/valign so we can use | |
122 // dimensions.position to detect custom positioning | |
123 | |
124 var dims = this.dimensions; | |
125 var margin = dims.margin; | |
126 var inside = t_op === related; | |
127 | |
128 if (!dims.position.h) { | |
129 if (this.halign === 'right') { | |
130 target.style.right = ((inside ? 0 : t_op.offsetWidth - related.offse
tLeft - related.offsetWidth) - margin.right) + 'px'; | |
131 dims.position.h = 'right'; | |
132 } else { | |
133 target.style.left = ((inside ? 0 : related.offsetLeft) - margin.left
) + 'px'; | |
134 dims.position.h = 'left'; | |
135 } | |
136 dims.position.h_by = this.localName; | |
137 } | |
138 | |
139 if (!dims.position.v) { | |
140 if (this.valign === 'bottom') { | |
141 target.style.bottom = ((inside ? 0 : t_op.offsetHeight - related.off
setTop - related.offsetHeight) - margin.bottom) + 'px'; | |
142 dims.position.v = 'bottom'; | |
143 } else { | |
144 target.style.top = ((inside ? 0 : related.offsetTop) - margin.top) +
'px'; | |
145 dims.position.v = 'top'; | |
146 } | |
147 dims.position.v_by = this.localName; | |
148 } | |
149 } | |
150 | |
151 }); | |
152 </script> | |
153 </polymer-element> | |
OLD | NEW |