update confirm

This commit is contained in:
Luke Pulverenti 2016-02-22 14:31:28 -05:00
parent 166a16b60d
commit 1ea5d5f307
191 changed files with 8714 additions and 48569 deletions

View file

@ -9,6 +9,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
<link rel="import" href="../iron-fit-behavior/iron-fit-behavior.html">
<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
<link rel="import" href="iron-overlay-backdrop.html">
@ -118,6 +119,15 @@ context. You should place this element as a child of `<body>` whenever possible.
type: Object
},
/**
* The HTMLElement that will be firing relevant KeyboardEvents.
* Used for capturing esc and tab. Overridden from `IronA11yKeysBehavior`.
*/
keyEventTarget: {
type: Object,
value: document
},
_manager: {
type: Object,
value: Polymer.IronOverlayManager
@ -130,13 +140,6 @@ context. You should place this element as a child of `<body>` whenever possible.
}
},
_boundOnCaptureKeydown: {
type: Function,
value: function() {
return this._onCaptureKeydown.bind(this);
}
},
_boundOnCaptureFocus: {
type: Function,
value: function() {
@ -144,33 +147,99 @@ context. You should place this element as a child of `<body>` whenever possible.
}
},
/** @type {?Node} */
/**
* The node being focused.
* @type {?Node}
*/
_focusedChild: {
type: Object
}
},
keyBindings: {
'esc': '__onEsc',
'tab': '__onTab'
},
listeners: {
'iron-resize': '_onIronResize'
},
/**
* The backdrop element.
* @type Node
* @type {Node}
*/
get backdropElement() {
return this._manager.backdropElement;
},
/**
* Returns the node to give focus to.
* @type {Node}
*/
get _focusNode() {
return this._focusedChild || Polymer.dom(this).querySelector('[autofocus]') || this;
return this._focusedChild || Polymer.dom(this).querySelector('[autofocus]') || this.__firstFocusableNode || this;
},
/**
* Array of nodes that can receive focus (overlay included), ordered by `tabindex`.
* This is used to retrieve which is the first and last focusable nodes in order
* to wrap the focus for overlays `with-backdrop`.
*
* 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]}
* @protected
*/
get _focusableNodes() {
// Elements that can be focused even if they have [disabled] attribute.
var FOCUSABLE_WITH_DISABLED = [
'a[href]',
'area[href]',
'iframe',
'[tabindex]',
'[contentEditable=true]'
];
// Elements that cannot be focused if they have [disabled] attribute.
var FOCUSABLE_WITHOUT_DISABLED = [
'input',
'select',
'textarea',
'button'
];
// Discard elements with tabindex=-1 (makes them not focusable).
var selector = FOCUSABLE_WITH_DISABLED.join(':not([tabindex="-1"]),') +
':not([tabindex="-1"]),' +
FOCUSABLE_WITHOUT_DISABLED.join(':not([disabled]):not([tabindex="-1"]),') +
':not([disabled]):not([tabindex="-1"])';
var focusables = Polymer.dom(this).querySelectorAll(selector);
if (this.tabIndex >= 0) {
// Insert at the beginning because we might have all elements with tabIndex = 0,
// and the overlay should be the first of the list.
focusables.splice(0, 0, this);
}
// Sort by tabindex.
return focusables.sort(function (a, b) {
if (a.tabIndex === b.tabIndex) {
return 0;
}
if (a.tabIndex === 0 || a.tabIndex > b.tabIndex) {
return 1;
}
return -1;
});
},
ready: function() {
// with-backdrop need 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;
this._ensureSetup();
},
@ -321,9 +390,8 @@ context. You should place this element as a child of `<body>` whenever possible.
}
},
_toggleListeners: function () {
_toggleListeners: function() {
this._toggleListener(this.opened, document, 'tap', this._boundOnCaptureClick, true);
this._toggleListener(this.opened, document, 'keydown', this._boundOnCaptureKeydown, true);
this._toggleListener(this.opened, document, 'focus', this._boundOnCaptureFocus, true);
},
@ -425,18 +493,8 @@ context. You should place this element as a child of `<body>` whenever possible.
}
},
_onCaptureKeydown: function(event) {
var ESC = 27;
if (this._manager.currentOverlay() === this &&
!this.noCancelOnEscKey &&
event.keyCode === ESC) {
this.cancel(event);
}
},
_onCaptureFocus: function (event) {
if (this._manager.currentOverlay() === this &&
this.withBackdrop) {
if (this._manager.currentOverlay() === this && this.withBackdrop) {
var path = Polymer.dom(event).path;
if (path.indexOf(this) === -1) {
event.stopPropagation();
@ -462,6 +520,37 @@ context. You should place this element as a child of `<body>` whenever possible.
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;
}
if (!this.noCancelOnEscKey) {
this.cancel(event);
}
},
__onTab: function(event) {
// Not opened or not on top, so return.
if (this._manager.currentOverlay() !== this) {
return;
}
// TAB wraps from last to first focusable.
// Shift + TAB wraps from first to last focusable.
var shift = event.detail.keyboardEvent.shiftKey;
var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusableNode;
var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNode;
if (this.withBackdrop && this._focusedChild === nodeToCheck) {
// We set here the _focusedChild so that _onCaptureFocus will handle the
// wrapping of the focus (the next event after tab is focus).
this._focusedChild = nodeToSet;
}
}
/**
@ -484,7 +573,7 @@ context. You should place this element as a child of `<body>` whenever possible.
};
/** @polymerBehavior */
Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl];
Polymer.IronOverlayBehavior = [Polymer.IronA11yKeysBehavior, Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl];
</script>