Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: third_party/polymer/v0_8/components-chromium/iron-overlay-behavior/iron-overlay-behavior-extracted.js

Issue 1162563004: Upgrade to 1.0 and switch clients to dom-repeat where needed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix a layout import and remove the gzipped webanimation in reproduce.sh Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1
2
3 /*
4 Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays
5 on top of other content. It includes an optional backdrop, and can be used to im plement a variety
6 of UI controls including dialogs and drop downs. Multiple overlays may be displa yed at once.
7
8 ### Closing and canceling
9
10 A dialog may be hidden by closing or canceling. The difference between close and cancel is user
11 intent. Closing generally implies that the user acknowledged the content on the overlay. By default,
12 it will cancel whenever the user taps outside it or presses the escape key. This behavior is
13 configurable with the `no-cancel-on-esc-key` and the `no-cancel-on-outside-click ` properties.
14 `close()` should be called explicitly by the implementer when the user interacts with a control
15 in the overlay element.
16
17 ### Positioning
18
19 By default the element is sized and positioned to fit and centered inside the wi ndow. You can
20 position and size it manually using CSS. See `Polymer.IronFitBehavior`.
21
22 ### Backdrop
23
24 Set the `with-backdrop` attribute to display a backdrop behind the overlay. The backdrop is
25 appended to `<body>` and is of type `<iron-overlay-backdrop>`. See its doc page for styling
26 options.
27
28 ### Limitations
29
30 The element is styled to appear on top of other content by setting its `z-index` property. You
31 must ensure no element has a stacking context with a higher `z-index` than its p arent stacking
32 context. You should place this element as a child of `<body>` whenever possible.
33
34 @demo demo/index.html
35 @polymerBehavior Polymer.IronOverlayBehavior
36 */
37
38 Polymer.IronOverlayBehaviorImpl = {
39
40 properties: {
41
42 /**
43 * True if the overlay is currently displayed.
44 */
45 opened: {
46 observer: '_openedChanged',
47 type: Boolean,
48 value: false
49 },
50
51 /**
52 * True if the overlay was canceled when it was last closed.
53 */
54 canceled: {
55 observer: '_canceledChanged',
56 readOnly: true,
57 type: Boolean,
58 value: false
59 },
60
61 /**
62 * Set to true to display a backdrop behind the overlay.
63 */
64 withBackdrop: {
65 type: Boolean,
66 value: false
67 },
68
69 /**
70 * Set to true to disable auto-focusing the overlay or child nodes with
71 * the `autofocus` attribute` when the overlay is opened.
72 */
73 noAutoFocus: {
74 type: Boolean,
75 value: false
76 },
77
78 /**
79 * Set to true to disable canceling the overlay with the ESC key.
80 */
81 noCancelOnEscKey: {
82 type: Boolean,
83 value: false
84 },
85
86 /**
87 * Set to true to disable canceling the overlay by clicking outside it.
88 */
89 noCancelOnOutsideClick: {
90 type: Boolean,
91 value: false
92 },
93
94 /**
95 * Returns the reason this dialog was last closed.
96 */
97 closingReason: {
98 // was a getter before, but needs to be a property so other
99 // behaviors can override this.
100 type: Object
101 },
102
103 _manager: {
104 type: Object,
105 value: Polymer.IronOverlayManager
106 },
107
108 _boundOnCaptureClick: {
109 type: Function,
110 value: function() {
111 return this._onCaptureClick.bind(this);
112 }
113 },
114
115 _boundOnCaptureKeydown: {
116 type: Function,
117 value: function() {
118 return this._onCaptureKeydown.bind(this);
119 }
120 }
121
122 },
123
124 listeners: {
125 'click': '_onClick',
126 'iron-resize': '_onIronResize'
127 },
128
129 /**
130 * The backdrop element.
131 * @type Node
132 */
133 get backdropElement() {
134 return this._backdrop;
135 },
136
137 get _focusNode() {
138 return Polymer.dom(this).querySelector('[autofocus]') || this;
139 },
140
141 registered: function() {
142 this._backdrop = document.createElement('iron-overlay-backdrop');
143 },
144
145 ready: function() {
146 this._ensureSetup();
147 if (this._callOpenedWhenReady) {
148 this._openedChanged();
149 }
150 },
151
152 detached: function() {
153 this.opened = false;
154 this._completeBackdrop();
155 this._manager.removeOverlay(this);
156 },
157
158 /**
159 * Toggle the opened state of the overlay.
160 */
161 toggle: function() {
162 this.opened = !this.opened;
163 },
164
165 /**
166 * Open the overlay.
167 */
168 open: function() {
169 this.opened = true;
170 this.closingReason = {canceled: false};
171 },
172
173 /**
174 * Close the overlay.
175 */
176 close: function() {
177 this.opened = false;
178 this._setCanceled(false);
179 },
180
181 /**
182 * Cancels the overlay.
183 */
184 cancel: function() {
185 this.opened = false,
186 this._setCanceled(true);
187 },
188
189 _ensureSetup: function() {
190 if (this._overlaySetup) {
191 return;
192 }
193 this._overlaySetup = true;
194 this.style.outline = 'none';
195 this.style.display = 'none';
196 },
197
198 _openedChanged: function() {
199 if (this.opened) {
200 this.removeAttribute('aria-hidden');
201 } else {
202 this.setAttribute('aria-hidden', 'true');
203 }
204
205 // wait to call after ready only if we're initially open
206 if (!this._overlaySetup) {
207 this._callOpenedWhenReady = this.opened;
208 return;
209 }
210 if (this._openChangedAsync) {
211 this.cancelAsync(this._openChangedAsync);
212 }
213
214 this._toggleListeners();
215
216 if (this.opened) {
217 this._prepareRenderOpened();
218 }
219
220 // async here to allow overlay layer to become visible.
221 this._openChangedAsync = this.async(function() {
222 // overlay becomes visible here
223 this.style.display = '';
224 // force layout to ensure transitions will go
225 this.offsetWidth;
226 if (this.opened) {
227 this._renderOpened();
228 } else {
229 this._renderClosed();
230 }
231 this._openChangedAsync = null;
232 });
233
234 },
235
236 _canceledChanged: function() {
237 this.closingReason = this.closingReason || {};
238 this.closingReason.canceled = this.canceled;
239 },
240
241 _toggleListener: function(enable, node, event, boundListener, capture) {
242 if (enable) {
243 node.addEventListener(event, boundListener, capture);
244 } else {
245 node.removeEventListener(event, boundListener, capture);
246 }
247 },
248
249 _toggleListeners: function() {
250 if (this._toggleListenersAsync) {
251 this.cancelAsync(this._toggleListenersAsync);
252 }
253 // async so we don't auto-close immediately via a click.
254 this._toggleListenersAsync = this.async(function() {
255 this._toggleListener(this.opened, document, 'click', this._boundOnCaptur eClick, true);
256 this._toggleListener(this.opened, document, 'keydown', this._boundOnCapt ureKeydown, true);
257 this._toggleListenersAsync = null;
258 });
259 },
260
261 // tasks which must occur before opening; e.g. making the element visible
262 _prepareRenderOpened: function() {
263 this._manager.addOverlay(this);
264
265 if (this.withBackdrop) {
266 this.backdropElement.prepare();
267 this._manager.trackBackdrop(this);
268 }
269
270 this._preparePositioning();
271 this.fit();
272 this._finishPositioning();
273 },
274
275 // tasks which cause the overlay to actually open; typically play an
276 // animation
277 _renderOpened: function() {
278 if (this.withBackdrop) {
279 this.backdropElement.open();
280 }
281 this._finishRenderOpened();
282 },
283
284 _renderClosed: function() {
285 if (this.withBackdrop) {
286 this.backdropElement.close();
287 }
288 this._finishRenderClosed();
289 },
290
291 _onTransitionend: function(event) {
292 // make sure this is our transition event.
293 if (event && event.target !== this) {
294 return;
295 }
296 if (this.opened) {
297 this._finishRenderOpened();
298 } else {
299 this._finishRenderClosed();
300 }
301 },
302
303 _finishRenderOpened: function() {
304 // focus the child node with [autofocus]
305 if (!this.noAutoFocus) {
306 this._focusNode.focus();
307 }
308
309 this.fire('iron-overlay-opened');
310
311 this._squelchNextResize = true;
312 this.async(this.notifyResize);
313 },
314
315 _finishRenderClosed: function() {
316 // hide the overlay and remove the backdrop
317 this.resetFit();
318 this.style.display = 'none';
319 this._completeBackdrop();
320 this._manager.removeOverlay(this);
321
322 this._focusNode.blur();
323 // focus the next overlay, if there is one
324 this._manager.focusOverlay();
325
326 this.fire('iron-overlay-closed', this.closingReason);
327
328 this._squelchNextResize = true;
329 this.async(this.notifyResize);
330 },
331
332 _completeBackdrop: function() {
333 if (this.withBackdrop) {
334 this._manager.trackBackdrop(this);
335 this.backdropElement.complete();
336 }
337 },
338
339 _preparePositioning: function() {
340 this.style.transition = this.style.webkitTransition = 'none';
341 this.style.transform = this.style.webkitTransform = 'none';
342 this.style.display = '';
343 },
344
345 _finishPositioning: function(target) {
346 this.style.display = 'none';
347 this.style.transform = this.style.webkitTransform = '';
348 // force layout to avoid application of transform
349 this.offsetWidth;
350 this.style.transition = this.style.webkitTransition = '';
351 },
352
353 _applyFocus: function() {
354 if (this.opened) {
355 if (!this.noAutoFocus) {
356 this._focusNode.focus();
357 }
358 } else {
359 this._focusNode.blur();
360 this._manager.focusOverlay();
361 }
362 },
363
364 _onCaptureClick: function(event) {
365 // attempt to close asynchronously and prevent the close of a tap event is immediately heard
366 // on target. This is because in shadow dom due to event retargetting even t.target is not
367 // useful.
368 if (!this.noCancelOnOutsideClick && (this._manager.currentOverlay() == thi s)) {
369 this._cancelJob = this.async(function() {
370 this.cancel();
371 }, 10);
372 }
373 },
374
375 _onClick: function(event) {
376 if (this._cancelJob) {
377 this.cancelAsync(this._cancelJob);
378 this._cancelJob = null;
379 }
380 },
381
382 _onCaptureKeydown: function(event) {
383 var ESC = 27;
384 if (!this.noCancelOnEscKey && (event.keyCode === ESC)) {
385 this.cancel();
386 event.stopPropagation();
387 }
388 },
389
390 _onIronResize: function() {
391 if (this._squelchNextResize) {
392 this._squelchNextResize = false;
393 return;
394 }
395 if (this.opened) {
396 this.refit();
397 }
398 }
399
400 };
401
402 /** @polymerBehavior */
403 Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableB ehavior, Polymer.IronOverlayBehaviorImpl];
404
405 /*
406 * Fired after the `iron-overlay` opens.
407 * @event iron-overlay-opened
408 */
409
410 /*
411 * Fired after the `iron-overlay` closes.
412 * @event iron-overlay-closed {{canceled: boolean}} detail -
413 * canceled: True if the overlay was canceled.
414 */
415
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698