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

Unified 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 side-by-side diff with in-line comments
Download patch
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).
- */
+ */
+
+})();

Powered by Google App Engine
This is Rietveld 408576698