| Index: third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-overlay-behavior-extracted.js
|
| diff --git a/third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-overlay-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-overlay-behavior-extracted.js
|
| index d3fddcba28261837e79065bf42c0fd86daee09e6..50810d5dd782c001a59d8dc8d5f1a5415b4640f8 100644
|
| --- a/third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-overlay-behavior-extracted.js
|
| +++ b/third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-overlay-behavior-extracted.js
|
| @@ -1,3 +1,7 @@
|
| +// IIFE to help scripts concatenation.
|
| +(function() {
|
| +'use strict';
|
| +
|
| /**
|
| Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays
|
| on top of other content. It includes an optional backdrop, and can be used to implement a variety
|
| @@ -101,15 +105,6 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| },
|
|
|
| /**
|
| - * The HTMLElement that will be firing relevant KeyboardEvents.
|
| - * Used for capturing esc and tab. Overridden from `IronA11yKeysBehavior`.
|
| - */
|
| - keyEventTarget: {
|
| - type: Object,
|
| - value: document
|
| - },
|
| -
|
| - /**
|
| * Set to true to enable restoring of focus when overlay is closed.
|
| */
|
| restoreFocusOnClose: {
|
| @@ -117,25 +112,23 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| value: false
|
| },
|
|
|
| + /**
|
| + * Set to true to keep overlay always on top.
|
| + */
|
| + alwaysOnTop: {
|
| + type: Boolean
|
| + },
|
| +
|
| + /**
|
| + * Shortcut to access to the overlay manager.
|
| + * @private
|
| + * @type {Polymer.IronOverlayManagerClass}
|
| + */
|
| _manager: {
|
| type: Object,
|
| value: Polymer.IronOverlayManager
|
| },
|
|
|
| - _boundOnCaptureClick: {
|
| - type: Function,
|
| - value: function() {
|
| - return this._onCaptureClick.bind(this);
|
| - }
|
| - },
|
| -
|
| - _boundOnCaptureFocus: {
|
| - type: Function,
|
| - value: function() {
|
| - return this._onCaptureFocus.bind(this);
|
| - }
|
| - },
|
| -
|
| /**
|
| * The node being focused.
|
| * @type {?Node}
|
| @@ -146,18 +139,13 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|
|
| },
|
|
|
| - keyBindings: {
|
| - 'esc': '__onEsc',
|
| - 'tab': '__onTab'
|
| - },
|
| -
|
| listeners: {
|
| 'iron-resize': '_onIronResize'
|
| },
|
|
|
| /**
|
| * The backdrop element.
|
| - * @type {Node}
|
| + * @type {Element}
|
| */
|
| get backdropElement() {
|
| return this._manager.backdropElement;
|
| @@ -178,7 +166,7 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| *
|
| * If you know what is your content (specifically the first and last focusable children),
|
| * you can override this method to return only `[firstFocusable, lastFocusable];`
|
| - * @type {[Node]}
|
| + * @type {Array<Node>}
|
| * @protected
|
| */
|
| get _focusableNodes() {
|
| @@ -224,11 +212,17 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| },
|
|
|
| ready: function() {
|
| + // Used to skip calls to notifyResize and refit while the overlay is animating.
|
| + this.__isAnimating = false;
|
| // with-backdrop needs tabindex to be set in order to trap the focus.
|
| // If it is not set, IronOverlayBehavior will set it, and remove it if with-backdrop = false.
|
| this.__shouldRemoveTabIndex = false;
|
| // Used for wrapping the focus on TAB / Shift+TAB.
|
| this.__firstFocusableNode = this.__lastFocusableNode = null;
|
| + // Used for requestAnimationFrame when opened changes.
|
| + this.__openChangedAsync = null;
|
| + // Used for requestAnimationFrame when iron-resize is fired.
|
| + this.__onIronResizeAsync = null;
|
| this._ensureSetup();
|
| },
|
|
|
| @@ -244,8 +238,10 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| Polymer.dom(this).unobserveNodes(this._observer);
|
| this._observer = null;
|
| this.opened = false;
|
| - this._manager.trackBackdrop(this);
|
| - this._manager.removeOverlay(this);
|
| + if (this.withBackdrop) {
|
| + // Allow user interactions right away.
|
| + this.backdropElement.close();
|
| + }
|
| },
|
|
|
| /**
|
| @@ -274,7 +270,7 @@ context. You should place this element as a child of `<body>` whenever possible.
|
|
|
| /**
|
| * Cancels the overlay.
|
| - * @param {?Event} event The original event
|
| + * @param {Event=} event The original event
|
| */
|
| cancel: function(event) {
|
| var cancelEvent = this.fire('iron-overlay-canceled', event, {cancelable: true});
|
| @@ -307,31 +303,26 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| return;
|
| }
|
|
|
| - this._manager.trackBackdrop(this);
|
| + this._manager.addOrRemoveOverlay(this);
|
|
|
| - if (this.opened) {
|
| - this._prepareRenderOpened();
|
| - }
|
| + this.__isAnimating = true;
|
|
|
| - if (this._openChangedAsync) {
|
| - this.cancelAsync(this._openChangedAsync);
|
| + // requestAnimationFrame for non-blocking rendering
|
| + if (this.__openChangedAsync) {
|
| + cancelAnimationFrame(this.__openChangedAsync);
|
| }
|
| - // Async here to allow overlay layer to become visible, and to avoid
|
| - // listeners to immediately close via a click.
|
| - this._openChangedAsync = this.async(function() {
|
| - // overlay becomes visible here
|
| - this.style.display = '';
|
| - // Force layout to ensure transition will go. Set offsetWidth to itself
|
| - // so that compilers won't remove it.
|
| - this.offsetWidth = this.offsetWidth;
|
| - if (this.opened) {
|
| - this._renderOpened();
|
| - } else {
|
| - this._renderClosed();
|
| + if (this.opened) {
|
| + if (this.withBackdrop) {
|
| + this.backdropElement.prepare();
|
| }
|
| - this._toggleListeners();
|
| - this._openChangedAsync = null;
|
| - }, 1);
|
| + this.__openChangedAsync = requestAnimationFrame(function() {
|
| + this.__openChangedAsync = null;
|
| + this._prepareRenderOpened();
|
| + this._renderOpened();
|
| + }.bind(this));
|
| + } else {
|
| + this._renderClosed();
|
| + }
|
| },
|
|
|
| _canceledChanged: function() {
|
| @@ -349,7 +340,7 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| this.__shouldRemoveTabIndex = false;
|
| }
|
| if (this.opened) {
|
| - this._manager.trackBackdrop(this);
|
| + this._manager.trackBackdrop();
|
| if (this.withBackdrop) {
|
| this.backdropElement.prepare();
|
| // Give time to be added to document.
|
| @@ -362,42 +353,18 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| }
|
| },
|
|
|
| - _toggleListener: function(enable, node, event, boundListener, capture) {
|
| - if (enable) {
|
| - // enable document-wide tap recognizer
|
| - if (event === 'tap') {
|
| - Polymer.Gestures.add(document, 'tap', null);
|
| - }
|
| - node.addEventListener(event, boundListener, capture);
|
| - } else {
|
| - // disable document-wide tap recognizer
|
| - if (event === 'tap') {
|
| - Polymer.Gestures.remove(document, 'tap', null);
|
| - }
|
| - node.removeEventListener(event, boundListener, capture);
|
| - }
|
| - },
|
| -
|
| - _toggleListeners: function() {
|
| - this._toggleListener(this.opened, document, 'tap', this._boundOnCaptureClick, true);
|
| - this._toggleListener(this.opened, document, 'focus', this._boundOnCaptureFocus, true);
|
| - },
|
| -
|
| - // tasks which must occur before opening; e.g. making the element visible
|
| + /**
|
| + * tasks which must occur before opening; e.g. making the element visible.
|
| + * @protected
|
| + */
|
| _prepareRenderOpened: function() {
|
|
|
| - this._manager.addOverlay(this);
|
| -
|
| // Needed to calculate the size of the overlay so that transitions on its size
|
| // will have the correct starting points.
|
| this._preparePositioning();
|
| - this.fit();
|
| + this.refit();
|
| this._finishPositioning();
|
|
|
| - if (this.withBackdrop) {
|
| - this.backdropElement.prepare();
|
| - }
|
| -
|
| // Safari will apply the focus to the autofocus element when displayed for the first time,
|
| // so we blur it. Later, _applyFocus will set the focus if necessary.
|
| if (this.noAutoFocus && document.activeElement === this._focusNode) {
|
| @@ -405,8 +372,10 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| }
|
| },
|
|
|
| - // tasks which cause the overlay to actually open; typically play an
|
| - // animation
|
| + /**
|
| + * Tasks which cause the overlay to actually open; typically play an animation.
|
| + * @protected
|
| + */
|
| _renderOpened: function() {
|
| if (this.withBackdrop) {
|
| this.backdropElement.open();
|
| @@ -414,6 +383,10 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| this._finishRenderOpened();
|
| },
|
|
|
| + /**
|
| + * Tasks which cause the overlay to actually close; typically play an animation.
|
| + * @protected
|
| + */
|
| _renderClosed: function() {
|
| if (this.withBackdrop) {
|
| this.backdropElement.close();
|
| @@ -421,25 +394,33 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| this._finishRenderClosed();
|
| },
|
|
|
| + /**
|
| + * Tasks to be performed at the end of open action. Will fire `iron-overlay-opened`.
|
| + * @protected
|
| + */
|
| _finishRenderOpened: function() {
|
| - // This ensures the overlay is visible before we set the focus
|
| - // (by calling _onIronResize -> refit).
|
| - this.notifyResize();
|
| // Focus the child node with [autofocus]
|
| this._applyFocus();
|
|
|
| + this.notifyResize();
|
| + this.__isAnimating = false;
|
| this.fire('iron-overlay-opened');
|
| },
|
|
|
| + /**
|
| + * Tasks to be performed at the end of close action. Will fire `iron-overlay-closed`.
|
| + * @protected
|
| + */
|
| _finishRenderClosed: function() {
|
| // Hide the overlay and remove the backdrop.
|
| - this.resetFit();
|
| this.style.display = 'none';
|
| - this._manager.removeOverlay(this);
|
| + // Reset z-index only at the end of the animation.
|
| + this.style.zIndex = '';
|
|
|
| this._applyFocus();
|
| - this.notifyResize();
|
|
|
| + this.notifyResize();
|
| + this.__isAnimating = false;
|
| this.fire('iron-overlay-closed', this.closingReason);
|
| },
|
|
|
| @@ -450,14 +431,24 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| },
|
|
|
| _finishPositioning: function() {
|
| + // First, make it invisible & reactivate animations.
|
| this.style.display = 'none';
|
| - this.style.transform = this.style.webkitTransform = '';
|
| - // Force layout layout to avoid application of transform.
|
| - // Set offsetWidth to itself so that compilers won't remove it.
|
| - this.offsetWidth = this.offsetWidth;
|
| + // Force reflow before re-enabling animations so that they don't start.
|
| + // Set scrollTop to itself so that Closure Compiler doesn't remove this.
|
| + this.scrollTop = this.scrollTop;
|
| this.style.transition = this.style.webkitTransition = '';
|
| + this.style.transform = this.style.webkitTransform = '';
|
| + // Now that animations are enabled, make it visible again
|
| + this.style.display = '';
|
| + // Force reflow, so that following animations are properly started.
|
| + // Set scrollTop to itself so that Closure Compiler doesn't remove this.
|
| + this.scrollTop = this.scrollTop;
|
| },
|
|
|
| + /**
|
| + * Applies focus according to the opened state.
|
| + * @protected
|
| + */
|
| _applyFocus: function() {
|
| if (this.opened) {
|
| if (!this.noAutoFocus) {
|
| @@ -470,68 +461,56 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| }
|
| },
|
|
|
| + /**
|
| + * Cancels (closes) the overlay. Call when click happens outside the overlay.
|
| + * @param {!Event} event
|
| + * @protected
|
| + */
|
| _onCaptureClick: function(event) {
|
| - if (this._manager.currentOverlay() === this &&
|
| - Polymer.dom(event).path.indexOf(this) === -1) {
|
| - if (this.noCancelOnOutsideClick) {
|
| - this._applyFocus();
|
| - } else {
|
| - this.cancel(event);
|
| - }
|
| + if (!this.noCancelOnOutsideClick) {
|
| + this.cancel(event);
|
| }
|
| },
|
|
|
| + /**
|
| + * Keeps track of the focused child. If withBackdrop, traps focus within overlay.
|
| + * @param {!Event} event
|
| + * @protected
|
| + */
|
| _onCaptureFocus: function (event) {
|
| - if (this._manager.currentOverlay() === this && this.withBackdrop) {
|
| - var path = Polymer.dom(event).path;
|
| - if (path.indexOf(this) === -1) {
|
| - event.stopPropagation();
|
| - this._applyFocus();
|
| - } else {
|
| - this._focusedChild = path[0];
|
| - }
|
| + if (!this.withBackdrop) {
|
| + return;
|
| }
|
| - },
|
| -
|
| - _onIronResize: function() {
|
| - if (this.opened) {
|
| - this.refit();
|
| + var path = Polymer.dom(event).path;
|
| + if (path.indexOf(this) === -1) {
|
| + event.stopPropagation();
|
| + this._applyFocus();
|
| + } else {
|
| + this._focusedChild = path[0];
|
| }
|
| },
|
|
|
| /**
|
| + * Handles the ESC key event and cancels (closes) the overlay.
|
| + * @param {!Event} event
|
| * @protected
|
| - * Will call notifyResize if overlay is opened.
|
| - * Can be overridden in order to avoid multiple observers on the same node.
|
| */
|
| - _onNodesChange: function() {
|
| - if (this.opened) {
|
| - this.notifyResize();
|
| - }
|
| - // Store it so we don't query too much.
|
| - var focusableNodes = this._focusableNodes;
|
| - this.__firstFocusableNode = focusableNodes[0];
|
| - this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];
|
| - },
|
| -
|
| - __onEsc: function(event) {
|
| - // Not opened or not on top, so return.
|
| - if (this._manager.currentOverlay() !== this) {
|
| - return;
|
| - }
|
| + _onCaptureEsc: function(event) {
|
| if (!this.noCancelOnEscKey) {
|
| this.cancel(event);
|
| }
|
| },
|
|
|
| - __onTab: function(event) {
|
| - // Not opened or not on top, so return.
|
| - if (this._manager.currentOverlay() !== this) {
|
| - return;
|
| - }
|
| + /**
|
| + * Handles TAB key events to track focus changes.
|
| + * Will wrap focus for overlays withBackdrop.
|
| + * @param {!Event} event
|
| + * @protected
|
| + */
|
| + _onCaptureTab: function(event) {
|
| // TAB wraps from last to first focusable.
|
| // Shift + TAB wraps from first to last focusable.
|
| - var shift = event.detail.keyboardEvent.shiftKey;
|
| + var shift = event.shiftKey;
|
| var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusableNode;
|
| var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNode;
|
| if (this.withBackdrop && this._focusedChild === nodeToCheck) {
|
| @@ -539,11 +518,43 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| // wrapping of the focus (the next event after tab is focus).
|
| this._focusedChild = nodeToSet;
|
| }
|
| + },
|
| +
|
| + /**
|
| + * Refits if the overlay is opened and not animating.
|
| + * @protected
|
| + */
|
| + _onIronResize: function() {
|
| + if (this.__onIronResizeAsync) {
|
| + cancelAnimationFrame(this.__onIronResizeAsync);
|
| + this.__onIronResizeAsync = null;
|
| + }
|
| + if (this.opened && !this.__isAnimating) {
|
| + this.__onIronResizeAsync = requestAnimationFrame(function() {
|
| + this.__onIronResizeAsync = null;
|
| + this.refit();
|
| + }.bind(this));
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Will call notifyResize if overlay is opened.
|
| + * Can be overridden in order to avoid multiple observers on the same node.
|
| + * @protected
|
| + */
|
| + _onNodesChange: function() {
|
| + if (this.opened && !this.__isAnimating) {
|
| + this.notifyResize();
|
| + }
|
| + // Store it so we don't query too much.
|
| + var focusableNodes = this._focusableNodes;
|
| + this.__firstFocusableNode = focusableNodes[0];
|
| + this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];
|
| }
|
| };
|
|
|
| /** @polymerBehavior */
|
| - Polymer.IronOverlayBehavior = [Polymer.IronA11yKeysBehavior, Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl];
|
| + Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl];
|
|
|
| /**
|
| * Fired after the `iron-overlay` opens.
|
| @@ -563,4 +574,6 @@ context. You should place this element as a child of `<body>` whenever possible.
|
| * Fired after the `iron-overlay` closes.
|
| * @event iron-overlay-closed
|
| * @param {{canceled: (boolean|undefined)}} closingReason Contains `canceled` (whether the overlay was canceled).
|
| - */
|
| + */
|
| +
|
| +})();
|
|
|