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

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

Issue 1862213002: Roll third_party/polymer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove obsolete appearance_browsertest.js, result of a previous bad merge. Created 4 years, 8 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
1 // IIFE to help scripts concatenation.
2 (function() {
3 'use strict';
4
1 /** 5 /**
2 Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays 6 Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays
3 on top of other content. It includes an optional backdrop, and can be used to im plement a variety 7 on top of other content. It includes an optional backdrop, and can be used to im plement a variety
4 of UI controls including dialogs and drop downs. Multiple overlays may be displa yed at once. 8 of UI controls including dialogs and drop downs. Multiple overlays may be displa yed at once.
5 9
6 ### Closing and canceling 10 ### Closing and canceling
7 11
8 A dialog may be hidden by closing or canceling. The difference between close and cancel is user 12 A dialog may be hidden by closing or canceling. The difference between close and cancel is user
9 intent. Closing generally implies that the user acknowledged the content on the overlay. By default, 13 intent. Closing generally implies that the user acknowledged the content on the overlay. By default,
10 it will cancel whenever the user taps outside it or presses the escape key. This behavior is 14 it will cancel whenever the user taps outside it or presses the escape key. This behavior is
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 /** 98 /**
95 * Returns the reason this dialog was last closed. 99 * Returns the reason this dialog was last closed.
96 */ 100 */
97 closingReason: { 101 closingReason: {
98 // was a getter before, but needs to be a property so other 102 // was a getter before, but needs to be a property so other
99 // behaviors can override this. 103 // behaviors can override this.
100 type: Object 104 type: Object
101 }, 105 },
102 106
103 /** 107 /**
104 * The HTMLElement that will be firing relevant KeyboardEvents.
105 * Used for capturing esc and tab. Overridden from `IronA11yKeysBehavior`.
106 */
107 keyEventTarget: {
108 type: Object,
109 value: document
110 },
111
112 /**
113 * Set to true to enable restoring of focus when overlay is closed. 108 * Set to true to enable restoring of focus when overlay is closed.
114 */ 109 */
115 restoreFocusOnClose: { 110 restoreFocusOnClose: {
116 type: Boolean, 111 type: Boolean,
117 value: false 112 value: false
118 }, 113 },
119 114
115 /**
116 * Set to true to keep overlay always on top.
117 */
118 alwaysOnTop: {
119 type: Boolean
120 },
121
122 /**
123 * Shortcut to access to the overlay manager.
124 * @private
125 * @type {Polymer.IronOverlayManagerClass}
126 */
120 _manager: { 127 _manager: {
121 type: Object, 128 type: Object,
122 value: Polymer.IronOverlayManager 129 value: Polymer.IronOverlayManager
123 }, 130 },
124 131
125 _boundOnCaptureClick: {
126 type: Function,
127 value: function() {
128 return this._onCaptureClick.bind(this);
129 }
130 },
131
132 _boundOnCaptureFocus: {
133 type: Function,
134 value: function() {
135 return this._onCaptureFocus.bind(this);
136 }
137 },
138
139 /** 132 /**
140 * The node being focused. 133 * The node being focused.
141 * @type {?Node} 134 * @type {?Node}
142 */ 135 */
143 _focusedChild: { 136 _focusedChild: {
144 type: Object 137 type: Object
145 } 138 }
146 139
147 }, 140 },
148 141
149 keyBindings: {
150 'esc': '__onEsc',
151 'tab': '__onTab'
152 },
153
154 listeners: { 142 listeners: {
155 'iron-resize': '_onIronResize' 143 'iron-resize': '_onIronResize'
156 }, 144 },
157 145
158 /** 146 /**
159 * The backdrop element. 147 * The backdrop element.
160 * @type {Node} 148 * @type {Element}
161 */ 149 */
162 get backdropElement() { 150 get backdropElement() {
163 return this._manager.backdropElement; 151 return this._manager.backdropElement;
164 }, 152 },
165 153
166 /** 154 /**
167 * Returns the node to give focus to. 155 * Returns the node to give focus to.
168 * @type {Node} 156 * @type {Node}
169 */ 157 */
170 get _focusNode() { 158 get _focusNode() {
171 return this._focusedChild || Polymer.dom(this).querySelector('[autofocus]' ) || this; 159 return this._focusedChild || Polymer.dom(this).querySelector('[autofocus]' ) || this;
172 }, 160 },
173 161
174 /** 162 /**
175 * Array of nodes that can receive focus (overlay included), ordered by `tab index`. 163 * Array of nodes that can receive focus (overlay included), ordered by `tab index`.
176 * This is used to retrieve which is the first and last focusable nodes in o rder 164 * This is used to retrieve which is the first and last focusable nodes in o rder
177 * to wrap the focus for overlays `with-backdrop`. 165 * to wrap the focus for overlays `with-backdrop`.
178 * 166 *
179 * If you know what is your content (specifically the first and last focusab le children), 167 * If you know what is your content (specifically the first and last focusab le children),
180 * you can override this method to return only `[firstFocusable, lastFocusab le];` 168 * you can override this method to return only `[firstFocusable, lastFocusab le];`
181 * @type {[Node]} 169 * @type {Array<Node>}
182 * @protected 170 * @protected
183 */ 171 */
184 get _focusableNodes() { 172 get _focusableNodes() {
185 // Elements that can be focused even if they have [disabled] attribute. 173 // Elements that can be focused even if they have [disabled] attribute.
186 var FOCUSABLE_WITH_DISABLED = [ 174 var FOCUSABLE_WITH_DISABLED = [
187 'a[href]', 175 'a[href]',
188 'area[href]', 176 'area[href]',
189 'iframe', 177 'iframe',
190 '[tabindex]', 178 '[tabindex]',
191 '[contentEditable=true]' 179 '[contentEditable=true]'
(...skipping 25 matching lines...) Expand all
217 return 0; 205 return 0;
218 } 206 }
219 if (a.tabIndex === 0 || a.tabIndex > b.tabIndex) { 207 if (a.tabIndex === 0 || a.tabIndex > b.tabIndex) {
220 return 1; 208 return 1;
221 } 209 }
222 return -1; 210 return -1;
223 }); 211 });
224 }, 212 },
225 213
226 ready: function() { 214 ready: function() {
215 // Used to skip calls to notifyResize and refit while the overlay is anima ting.
216 this.__isAnimating = false;
227 // with-backdrop needs tabindex to be set in order to trap the focus. 217 // with-backdrop needs tabindex to be set in order to trap the focus.
228 // If it is not set, IronOverlayBehavior will set it, and remove it if wit h-backdrop = false. 218 // If it is not set, IronOverlayBehavior will set it, and remove it if wit h-backdrop = false.
229 this.__shouldRemoveTabIndex = false; 219 this.__shouldRemoveTabIndex = false;
230 // Used for wrapping the focus on TAB / Shift+TAB. 220 // Used for wrapping the focus on TAB / Shift+TAB.
231 this.__firstFocusableNode = this.__lastFocusableNode = null; 221 this.__firstFocusableNode = this.__lastFocusableNode = null;
222 // Used for requestAnimationFrame when opened changes.
223 this.__openChangedAsync = null;
224 // Used for requestAnimationFrame when iron-resize is fired.
225 this.__onIronResizeAsync = null;
232 this._ensureSetup(); 226 this._ensureSetup();
233 }, 227 },
234 228
235 attached: function() { 229 attached: function() {
236 // Call _openedChanged here so that position can be computed correctly. 230 // Call _openedChanged here so that position can be computed correctly.
237 if (this.opened) { 231 if (this.opened) {
238 this._openedChanged(); 232 this._openedChanged();
239 } 233 }
240 this._observer = Polymer.dom(this).observeNodes(this._onNodesChange); 234 this._observer = Polymer.dom(this).observeNodes(this._onNodesChange);
241 }, 235 },
242 236
243 detached: function() { 237 detached: function() {
244 Polymer.dom(this).unobserveNodes(this._observer); 238 Polymer.dom(this).unobserveNodes(this._observer);
245 this._observer = null; 239 this._observer = null;
246 this.opened = false; 240 this.opened = false;
247 this._manager.trackBackdrop(this); 241 if (this.withBackdrop) {
248 this._manager.removeOverlay(this); 242 // Allow user interactions right away.
243 this.backdropElement.close();
244 }
249 }, 245 },
250 246
251 /** 247 /**
252 * Toggle the opened state of the overlay. 248 * Toggle the opened state of the overlay.
253 */ 249 */
254 toggle: function() { 250 toggle: function() {
255 this._setCanceled(false); 251 this._setCanceled(false);
256 this.opened = !this.opened; 252 this.opened = !this.opened;
257 }, 253 },
258 254
259 /** 255 /**
260 * Open the overlay. 256 * Open the overlay.
261 */ 257 */
262 open: function() { 258 open: function() {
263 this._setCanceled(false); 259 this._setCanceled(false);
264 this.opened = true; 260 this.opened = true;
265 }, 261 },
266 262
267 /** 263 /**
268 * Close the overlay. 264 * Close the overlay.
269 */ 265 */
270 close: function() { 266 close: function() {
271 this._setCanceled(false); 267 this._setCanceled(false);
272 this.opened = false; 268 this.opened = false;
273 }, 269 },
274 270
275 /** 271 /**
276 * Cancels the overlay. 272 * Cancels the overlay.
277 * @param {?Event} event The original event 273 * @param {Event=} event The original event
278 */ 274 */
279 cancel: function(event) { 275 cancel: function(event) {
280 var cancelEvent = this.fire('iron-overlay-canceled', event, {cancelable: t rue}); 276 var cancelEvent = this.fire('iron-overlay-canceled', event, {cancelable: t rue});
281 if (cancelEvent.defaultPrevented) { 277 if (cancelEvent.defaultPrevented) {
282 return; 278 return;
283 } 279 }
284 280
285 this._setCanceled(true); 281 this._setCanceled(true);
286 this.opened = false; 282 this.opened = false;
287 }, 283 },
(...skipping 12 matching lines...) Expand all
300 this.removeAttribute('aria-hidden'); 296 this.removeAttribute('aria-hidden');
301 } else { 297 } else {
302 this.setAttribute('aria-hidden', 'true'); 298 this.setAttribute('aria-hidden', 'true');
303 } 299 }
304 300
305 // wait to call after ready only if we're initially open 301 // wait to call after ready only if we're initially open
306 if (!this._overlaySetup) { 302 if (!this._overlaySetup) {
307 return; 303 return;
308 } 304 }
309 305
310 this._manager.trackBackdrop(this); 306 this._manager.addOrRemoveOverlay(this);
311 307
308 this.__isAnimating = true;
309
310 // requestAnimationFrame for non-blocking rendering
311 if (this.__openChangedAsync) {
312 cancelAnimationFrame(this.__openChangedAsync);
313 }
312 if (this.opened) { 314 if (this.opened) {
313 this._prepareRenderOpened(); 315 if (this.withBackdrop) {
316 this.backdropElement.prepare();
317 }
318 this.__openChangedAsync = requestAnimationFrame(function() {
319 this.__openChangedAsync = null;
320 this._prepareRenderOpened();
321 this._renderOpened();
322 }.bind(this));
323 } else {
324 this._renderClosed();
314 } 325 }
315
316 if (this._openChangedAsync) {
317 this.cancelAsync(this._openChangedAsync);
318 }
319 // Async here to allow overlay layer to become visible, and to avoid
320 // listeners to immediately close via a click.
321 this._openChangedAsync = this.async(function() {
322 // overlay becomes visible here
323 this.style.display = '';
324 // Force layout to ensure transition will go. Set offsetWidth to itself
325 // so that compilers won't remove it.
326 this.offsetWidth = this.offsetWidth;
327 if (this.opened) {
328 this._renderOpened();
329 } else {
330 this._renderClosed();
331 }
332 this._toggleListeners();
333 this._openChangedAsync = null;
334 }, 1);
335 }, 326 },
336 327
337 _canceledChanged: function() { 328 _canceledChanged: function() {
338 this.closingReason = this.closingReason || {}; 329 this.closingReason = this.closingReason || {};
339 this.closingReason.canceled = this.canceled; 330 this.closingReason.canceled = this.canceled;
340 }, 331 },
341 332
342 _withBackdropChanged: function() { 333 _withBackdropChanged: function() {
343 // If tabindex is already set, no need to override it. 334 // If tabindex is already set, no need to override it.
344 if (this.withBackdrop && !this.hasAttribute('tabindex')) { 335 if (this.withBackdrop && !this.hasAttribute('tabindex')) {
345 this.setAttribute('tabindex', '-1'); 336 this.setAttribute('tabindex', '-1');
346 this.__shouldRemoveTabIndex = true; 337 this.__shouldRemoveTabIndex = true;
347 } else if (this.__shouldRemoveTabIndex) { 338 } else if (this.__shouldRemoveTabIndex) {
348 this.removeAttribute('tabindex'); 339 this.removeAttribute('tabindex');
349 this.__shouldRemoveTabIndex = false; 340 this.__shouldRemoveTabIndex = false;
350 } 341 }
351 if (this.opened) { 342 if (this.opened) {
352 this._manager.trackBackdrop(this); 343 this._manager.trackBackdrop();
353 if (this.withBackdrop) { 344 if (this.withBackdrop) {
354 this.backdropElement.prepare(); 345 this.backdropElement.prepare();
355 // Give time to be added to document. 346 // Give time to be added to document.
356 this.async(function(){ 347 this.async(function(){
357 this.backdropElement.open(); 348 this.backdropElement.open();
358 }, 1); 349 }, 1);
359 } else { 350 } else {
360 this.backdropElement.close(); 351 this.backdropElement.close();
361 } 352 }
362 } 353 }
363 }, 354 },
364 355
365 _toggleListener: function(enable, node, event, boundListener, capture) { 356 /**
366 if (enable) { 357 * tasks which must occur before opening; e.g. making the element visible.
367 // enable document-wide tap recognizer 358 * @protected
368 if (event === 'tap') { 359 */
369 Polymer.Gestures.add(document, 'tap', null);
370 }
371 node.addEventListener(event, boundListener, capture);
372 } else {
373 // disable document-wide tap recognizer
374 if (event === 'tap') {
375 Polymer.Gestures.remove(document, 'tap', null);
376 }
377 node.removeEventListener(event, boundListener, capture);
378 }
379 },
380
381 _toggleListeners: function() {
382 this._toggleListener(this.opened, document, 'tap', this._boundOnCaptureCli ck, true);
383 this._toggleListener(this.opened, document, 'focus', this._boundOnCaptureF ocus, true);
384 },
385
386 // tasks which must occur before opening; e.g. making the element visible
387 _prepareRenderOpened: function() { 360 _prepareRenderOpened: function() {
388 361
389 this._manager.addOverlay(this);
390
391 // Needed to calculate the size of the overlay so that transitions on its size 362 // Needed to calculate the size of the overlay so that transitions on its size
392 // will have the correct starting points. 363 // will have the correct starting points.
393 this._preparePositioning(); 364 this._preparePositioning();
394 this.fit(); 365 this.refit();
395 this._finishPositioning(); 366 this._finishPositioning();
396 367
397 if (this.withBackdrop) {
398 this.backdropElement.prepare();
399 }
400
401 // Safari will apply the focus to the autofocus element when displayed for the first time, 368 // Safari will apply the focus to the autofocus element when displayed for the first time,
402 // so we blur it. Later, _applyFocus will set the focus if necessary. 369 // so we blur it. Later, _applyFocus will set the focus if necessary.
403 if (this.noAutoFocus && document.activeElement === this._focusNode) { 370 if (this.noAutoFocus && document.activeElement === this._focusNode) {
404 this._focusNode.blur(); 371 this._focusNode.blur();
405 } 372 }
406 }, 373 },
407 374
408 // tasks which cause the overlay to actually open; typically play an 375 /**
409 // animation 376 * Tasks which cause the overlay to actually open; typically play an animati on.
377 * @protected
378 */
410 _renderOpened: function() { 379 _renderOpened: function() {
411 if (this.withBackdrop) { 380 if (this.withBackdrop) {
412 this.backdropElement.open(); 381 this.backdropElement.open();
413 } 382 }
414 this._finishRenderOpened(); 383 this._finishRenderOpened();
415 }, 384 },
416 385
386 /**
387 * Tasks which cause the overlay to actually close; typically play an animat ion.
388 * @protected
389 */
417 _renderClosed: function() { 390 _renderClosed: function() {
418 if (this.withBackdrop) { 391 if (this.withBackdrop) {
419 this.backdropElement.close(); 392 this.backdropElement.close();
420 } 393 }
421 this._finishRenderClosed(); 394 this._finishRenderClosed();
422 }, 395 },
423 396
397 /**
398 * Tasks to be performed at the end of open action. Will fire `iron-overlay- opened`.
399 * @protected
400 */
424 _finishRenderOpened: function() { 401 _finishRenderOpened: function() {
425 // This ensures the overlay is visible before we set the focus
426 // (by calling _onIronResize -> refit).
427 this.notifyResize();
428 // Focus the child node with [autofocus] 402 // Focus the child node with [autofocus]
429 this._applyFocus(); 403 this._applyFocus();
430 404
405 this.notifyResize();
406 this.__isAnimating = false;
431 this.fire('iron-overlay-opened'); 407 this.fire('iron-overlay-opened');
432 }, 408 },
433 409
410 /**
411 * Tasks to be performed at the end of close action. Will fire `iron-overlay -closed`.
412 * @protected
413 */
434 _finishRenderClosed: function() { 414 _finishRenderClosed: function() {
435 // Hide the overlay and remove the backdrop. 415 // Hide the overlay and remove the backdrop.
436 this.resetFit();
437 this.style.display = 'none'; 416 this.style.display = 'none';
438 this._manager.removeOverlay(this); 417 // Reset z-index only at the end of the animation.
418 this.style.zIndex = '';
439 419
440 this._applyFocus(); 420 this._applyFocus();
421
441 this.notifyResize(); 422 this.notifyResize();
442 423 this.__isAnimating = false;
443 this.fire('iron-overlay-closed', this.closingReason); 424 this.fire('iron-overlay-closed', this.closingReason);
444 }, 425 },
445 426
446 _preparePositioning: function() { 427 _preparePositioning: function() {
447 this.style.transition = this.style.webkitTransition = 'none'; 428 this.style.transition = this.style.webkitTransition = 'none';
448 this.style.transform = this.style.webkitTransform = 'none'; 429 this.style.transform = this.style.webkitTransform = 'none';
449 this.style.display = ''; 430 this.style.display = '';
450 }, 431 },
451 432
452 _finishPositioning: function() { 433 _finishPositioning: function() {
434 // First, make it invisible & reactivate animations.
453 this.style.display = 'none'; 435 this.style.display = 'none';
436 // Force reflow before re-enabling animations so that they don't start.
437 // Set scrollTop to itself so that Closure Compiler doesn't remove this.
438 this.scrollTop = this.scrollTop;
439 this.style.transition = this.style.webkitTransition = '';
454 this.style.transform = this.style.webkitTransform = ''; 440 this.style.transform = this.style.webkitTransform = '';
455 // Force layout layout to avoid application of transform. 441 // Now that animations are enabled, make it visible again
456 // Set offsetWidth to itself so that compilers won't remove it. 442 this.style.display = '';
457 this.offsetWidth = this.offsetWidth; 443 // Force reflow, so that following animations are properly started.
458 this.style.transition = this.style.webkitTransition = ''; 444 // Set scrollTop to itself so that Closure Compiler doesn't remove this.
445 this.scrollTop = this.scrollTop;
459 }, 446 },
460 447
448 /**
449 * Applies focus according to the opened state.
450 * @protected
451 */
461 _applyFocus: function() { 452 _applyFocus: function() {
462 if (this.opened) { 453 if (this.opened) {
463 if (!this.noAutoFocus) { 454 if (!this.noAutoFocus) {
464 this._focusNode.focus(); 455 this._focusNode.focus();
465 } 456 }
466 } else { 457 } else {
467 this._focusNode.blur(); 458 this._focusNode.blur();
468 this._focusedChild = null; 459 this._focusedChild = null;
469 this._manager.focusOverlay(); 460 this._manager.focusOverlay();
470 } 461 }
471 }, 462 },
472 463
473 _onCaptureClick: function(event) {
474 if (this._manager.currentOverlay() === this &&
475 Polymer.dom(event).path.indexOf(this) === -1) {
476 if (this.noCancelOnOutsideClick) {
477 this._applyFocus();
478 } else {
479 this.cancel(event);
480 }
481 }
482 },
483
484 _onCaptureFocus: function (event) {
485 if (this._manager.currentOverlay() === this && this.withBackdrop) {
486 var path = Polymer.dom(event).path;
487 if (path.indexOf(this) === -1) {
488 event.stopPropagation();
489 this._applyFocus();
490 } else {
491 this._focusedChild = path[0];
492 }
493 }
494 },
495
496 _onIronResize: function() {
497 if (this.opened) {
498 this.refit();
499 }
500 },
501
502 /** 464 /**
465 * Cancels (closes) the overlay. Call when click happens outside the overlay .
466 * @param {!Event} event
503 * @protected 467 * @protected
504 * Will call notifyResize if overlay is opened.
505 * Can be overridden in order to avoid multiple observers on the same node.
506 */ 468 */
507 _onNodesChange: function() { 469 _onCaptureClick: function(event) {
508 if (this.opened) { 470 if (!this.noCancelOnOutsideClick) {
509 this.notifyResize(); 471 this.cancel(event);
510 } 472 }
511 // Store it so we don't query too much.
512 var focusableNodes = this._focusableNodes;
513 this.__firstFocusableNode = focusableNodes[0];
514 this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];
515 }, 473 },
516 474
517 __onEsc: function(event) { 475 /**
518 // Not opened or not on top, so return. 476 * Keeps track of the focused child. If withBackdrop, traps focus within ove rlay.
519 if (this._manager.currentOverlay() !== this) { 477 * @param {!Event} event
478 * @protected
479 */
480 _onCaptureFocus: function (event) {
481 if (!this.withBackdrop) {
520 return; 482 return;
521 } 483 }
484 var path = Polymer.dom(event).path;
485 if (path.indexOf(this) === -1) {
486 event.stopPropagation();
487 this._applyFocus();
488 } else {
489 this._focusedChild = path[0];
490 }
491 },
492
493 /**
494 * Handles the ESC key event and cancels (closes) the overlay.
495 * @param {!Event} event
496 * @protected
497 */
498 _onCaptureEsc: function(event) {
522 if (!this.noCancelOnEscKey) { 499 if (!this.noCancelOnEscKey) {
523 this.cancel(event); 500 this.cancel(event);
524 } 501 }
525 }, 502 },
526 503
527 __onTab: function(event) { 504 /**
528 // Not opened or not on top, so return. 505 * Handles TAB key events to track focus changes.
529 if (this._manager.currentOverlay() !== this) { 506 * Will wrap focus for overlays withBackdrop.
530 return; 507 * @param {!Event} event
531 } 508 * @protected
509 */
510 _onCaptureTab: function(event) {
532 // TAB wraps from last to first focusable. 511 // TAB wraps from last to first focusable.
533 // Shift + TAB wraps from first to last focusable. 512 // Shift + TAB wraps from first to last focusable.
534 var shift = event.detail.keyboardEvent.shiftKey; 513 var shift = event.shiftKey;
535 var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusable Node; 514 var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusable Node;
536 var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNo de; 515 var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNo de;
537 if (this.withBackdrop && this._focusedChild === nodeToCheck) { 516 if (this.withBackdrop && this._focusedChild === nodeToCheck) {
538 // We set here the _focusedChild so that _onCaptureFocus will handle the 517 // We set here the _focusedChild so that _onCaptureFocus will handle the
539 // wrapping of the focus (the next event after tab is focus). 518 // wrapping of the focus (the next event after tab is focus).
540 this._focusedChild = nodeToSet; 519 this._focusedChild = nodeToSet;
541 } 520 }
521 },
522
523 /**
524 * Refits if the overlay is opened and not animating.
525 * @protected
526 */
527 _onIronResize: function() {
528 if (this.__onIronResizeAsync) {
529 cancelAnimationFrame(this.__onIronResizeAsync);
530 this.__onIronResizeAsync = null;
531 }
532 if (this.opened && !this.__isAnimating) {
533 this.__onIronResizeAsync = requestAnimationFrame(function() {
534 this.__onIronResizeAsync = null;
535 this.refit();
536 }.bind(this));
537 }
538 },
539
540 /**
541 * Will call notifyResize if overlay is opened.
542 * Can be overridden in order to avoid multiple observers on the same node.
543 * @protected
544 */
545 _onNodesChange: function() {
546 if (this.opened && !this.__isAnimating) {
547 this.notifyResize();
548 }
549 // Store it so we don't query too much.
550 var focusableNodes = this._focusableNodes;
551 this.__firstFocusableNode = focusableNodes[0];
552 this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];
542 } 553 }
543 }; 554 };
544 555
545 /** @polymerBehavior */ 556 /** @polymerBehavior */
546 Polymer.IronOverlayBehavior = [Polymer.IronA11yKeysBehavior, Polymer.IronFitBe havior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl]; 557 Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableB ehavior, Polymer.IronOverlayBehaviorImpl];
547 558
548 /** 559 /**
549 * Fired after the `iron-overlay` opens. 560 * Fired after the `iron-overlay` opens.
550 * @event iron-overlay-opened 561 * @event iron-overlay-opened
551 */ 562 */
552 563
553 /** 564 /**
554 * Fired when the `iron-overlay` is canceled, but before it is closed. 565 * Fired when the `iron-overlay` is canceled, but before it is closed.
555 * Cancel the event to prevent the `iron-overlay` from closing. 566 * Cancel the event to prevent the `iron-overlay` from closing.
556 * @event iron-overlay-canceled 567 * @event iron-overlay-canceled
557 * @param {Event} event The closing of the `iron-overlay` can be prevented 568 * @param {Event} event The closing of the `iron-overlay` can be prevented
558 * by calling `event.preventDefault()`. The `event.detail` is the original even t that originated 569 * by calling `event.preventDefault()`. The `event.detail` is the original even t that originated
559 * the canceling (e.g. ESC keyboard event or click event outside the `iron-over lay`). 570 * the canceling (e.g. ESC keyboard event or click event outside the `iron-over lay`).
560 */ 571 */
561 572
562 /** 573 /**
563 * Fired after the `iron-overlay` closes. 574 * Fired after the `iron-overlay` closes.
564 * @event iron-overlay-closed 575 * @event iron-overlay-closed
565 * @param {{canceled: (boolean|undefined)}} closingReason Contains `canceled` ( whether the overlay was canceled). 576 * @param {{canceled: (boolean|undefined)}} closingReason Contains `canceled` ( whether the overlay was canceled).
566 */ 577 */
578
579 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698