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

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

Issue 2633003003: Update iron-overlay-behavior to version 1.10.2. (Closed)
Patch Set: Rebased. Created 3 years, 11 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 (function() { 1 (function() {
2 'use strict'; 2 'use strict';
3 3
4 /** 4 /** @polymerBehavior */
5 Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays
6 on top of other content. It includes an optional backdrop, and can be used to im plement a variety
7 of UI controls including dialogs and drop downs. Multiple overlays may be displa yed at once.
8
9 See the [demo source code](https://github.com/PolymerElements/iron-overlay-behav ior/blob/master/demo/simple-overlay.html)
10 for an example.
11
12 ### Closing and canceling
13
14 An overlay may be hidden by closing or canceling. The difference between close a nd cancel is user
15 intent. Closing generally implies that the user acknowledged the content on the overlay. By default,
16 it will cancel whenever the user taps outside it or presses the escape key. This behavior is
17 configurable with the `no-cancel-on-esc-key` and the `no-cancel-on-outside-click ` properties.
18 `close()` should be called explicitly by the implementer when the user interacts with a control
19 in the overlay element. When the dialog is canceled, the overlay fires an 'iron- overlay-canceled'
20 event. Call `preventDefault` on this event to prevent the overlay from closing.
21
22 ### Positioning
23
24 By default the element is sized and positioned to fit and centered inside the wi ndow. You can
25 position and size it manually using CSS. See `Polymer.IronFitBehavior`.
26
27 ### Backdrop
28
29 Set the `with-backdrop` attribute to display a backdrop behind the overlay. The backdrop is
30 appended to `<body>` and is of type `<iron-overlay-backdrop>`. See its doc page for styling
31 options.
32
33 In addition, `with-backdrop` will wrap the focus within the content in the light DOM.
34 Override the [`_focusableNodes` getter](#Polymer.IronOverlayBehavior:property-_f ocusableNodes)
35 to achieve a different behavior.
36
37 ### Limitations
38
39 The element is styled to appear on top of other content by setting its `z-index` property. You
40 must ensure no element has a stacking context with a higher `z-index` than its p arent stacking
41 context. You should place this element as a child of `<body>` whenever possible.
42
43 @demo demo/index.html
44 @polymerBehavior Polymer.IronOverlayBehavior
45 */
46
47 Polymer.IronOverlayBehaviorImpl = { 5 Polymer.IronOverlayBehaviorImpl = {
48 6
49 properties: { 7 properties: {
50 8
51 /** 9 /**
52 * True if the overlay is currently displayed. 10 * True if the overlay is currently displayed.
53 */ 11 */
54 opened: { 12 opened: {
55 observer: '_openedChanged', 13 observer: '_openedChanged',
56 type: Boolean, 14 type: Boolean,
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 * Array of nodes that can receive focus (overlay included), ordered by `tab index`. 130 * Array of nodes that can receive focus (overlay included), ordered by `tab index`.
173 * This is used to retrieve which is the first and last focusable nodes in o rder 131 * This is used to retrieve which is the first and last focusable nodes in o rder
174 * to wrap the focus for overlays `with-backdrop`. 132 * to wrap the focus for overlays `with-backdrop`.
175 * 133 *
176 * If you know what is your content (specifically the first and last focusab le children), 134 * If you know what is your content (specifically the first and last focusab le children),
177 * you can override this method to return only `[firstFocusable, lastFocusab le];` 135 * you can override this method to return only `[firstFocusable, lastFocusab le];`
178 * @type {Array<Node>} 136 * @type {Array<Node>}
179 * @protected 137 * @protected
180 */ 138 */
181 get _focusableNodes() { 139 get _focusableNodes() {
182 // Elements that can be focused even if they have [disabled] attribute. 140 return Polymer.IronFocusablesHelper.getTabbableNodes(this);
183 var FOCUSABLE_WITH_DISABLED = [
184 'a[href]',
185 'area[href]',
186 'iframe',
187 '[tabindex]',
188 '[contentEditable=true]'
189 ];
190
191 // Elements that cannot be focused if they have [disabled] attribute.
192 var FOCUSABLE_WITHOUT_DISABLED = [
193 'input',
194 'select',
195 'textarea',
196 'button'
197 ];
198
199 // Discard elements with tabindex=-1 (makes them not focusable).
200 var selector = FOCUSABLE_WITH_DISABLED.join(':not([tabindex="-1"]),') +
201 ':not([tabindex="-1"]),' +
202 FOCUSABLE_WITHOUT_DISABLED.join(':not([disabled]):not([tabindex="-1"]),' ) +
203 ':not([disabled]):not([tabindex="-1"])';
204
205 var focusables = Polymer.dom(this).querySelectorAll(selector);
206 if (this.tabIndex >= 0) {
207 // Insert at the beginning because we might have all elements with tabIn dex = 0,
208 // and the overlay should be the first of the list.
209 focusables.splice(0, 0, this);
210 }
211 // Sort by tabindex.
212 return focusables.sort(function (a, b) {
213 if (a.tabIndex === b.tabIndex) {
214 return 0;
215 }
216 if (a.tabIndex === 0 || a.tabIndex > b.tabIndex) {
217 return 1;
218 }
219 return -1;
220 });
221 }, 141 },
222 142
223 ready: function() { 143 ready: function() {
224 // Used to skip calls to notifyResize and refit while the overlay is anima ting. 144 // Used to skip calls to notifyResize and refit while the overlay is anima ting.
225 this.__isAnimating = false; 145 this.__isAnimating = false;
226 // with-backdrop needs tabindex to be set in order to trap the focus. 146 // with-backdrop needs tabindex to be set in order to trap the focus.
227 // If it is not set, IronOverlayBehavior will set it, and remove it if wit h-backdrop = false. 147 // If it is not set, IronOverlayBehavior will set it, and remove it if wit h-backdrop = false.
228 this.__shouldRemoveTabIndex = false; 148 this.__shouldRemoveTabIndex = false;
229 // Used for wrapping the focus on TAB / Shift+TAB. 149 // Used for wrapping the focus on TAB / Shift+TAB.
230 this.__firstFocusableNode = this.__lastFocusableNode = null; 150 this.__firstFocusableNode = this.__lastFocusableNode = null;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 cancel: function(event) { 204 cancel: function(event) {
285 var cancelEvent = this.fire('iron-overlay-canceled', event, {cancelable: t rue}); 205 var cancelEvent = this.fire('iron-overlay-canceled', event, {cancelable: t rue});
286 if (cancelEvent.defaultPrevented) { 206 if (cancelEvent.defaultPrevented) {
287 return; 207 return;
288 } 208 }
289 209
290 this._setCanceled(true); 210 this._setCanceled(true);
291 this.opened = false; 211 this.opened = false;
292 }, 212 },
293 213
214 /**
215 * Invalidates the cached tabbable nodes. To be called when any of the focus able
216 * content changes (e.g. a button is disabled).
217 */
218 invalidateTabbables: function() {
219 this.__firstFocusableNode = this.__lastFocusableNode = null;
220 },
221
294 _ensureSetup: function() { 222 _ensureSetup: function() {
295 if (this._overlaySetup) { 223 if (this._overlaySetup) {
296 return; 224 return;
297 } 225 }
298 this._overlaySetup = true; 226 this._overlaySetup = true;
299 this.style.outline = 'none'; 227 this.style.outline = 'none';
300 this.style.display = 'none'; 228 this.style.display = 'none';
301 }, 229 },
302 230
303 /** 231 /**
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 }, 310 },
383 311
384 /** 312 /**
385 * Tasks to be performed at the end of open action. Will fire `iron-overlay- opened`. 313 * Tasks to be performed at the end of open action. Will fire `iron-overlay- opened`.
386 * @protected 314 * @protected
387 */ 315 */
388 _finishRenderOpened: function() { 316 _finishRenderOpened: function() {
389 this.notifyResize(); 317 this.notifyResize();
390 this.__isAnimating = false; 318 this.__isAnimating = false;
391 319
392 // Store it so we don't query too much.
393 var focusableNodes = this._focusableNodes;
394 this.__firstFocusableNode = focusableNodes[0];
395 this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];
396
397 this.fire('iron-overlay-opened'); 320 this.fire('iron-overlay-opened');
398 }, 321 },
399 322
400 /** 323 /**
401 * Tasks to be performed at the end of close action. Will fire `iron-overlay -closed`. 324 * Tasks to be performed at the end of close action. Will fire `iron-overlay -closed`.
402 * @protected 325 * @protected
403 */ 326 */
404 _finishRenderClosed: function() { 327 _finishRenderClosed: function() {
405 // Hide the overlay. 328 // Hide the overlay.
406 this.style.display = 'none'; 329 this.style.display = 'none';
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 /** 426 /**
504 * Handles TAB key events to track focus changes. 427 * Handles TAB key events to track focus changes.
505 * Will wrap focus for overlays withBackdrop. 428 * Will wrap focus for overlays withBackdrop.
506 * @param {!Event} event 429 * @param {!Event} event
507 * @protected 430 * @protected
508 */ 431 */
509 _onCaptureTab: function(event) { 432 _onCaptureTab: function(event) {
510 if (!this.withBackdrop) { 433 if (!this.withBackdrop) {
511 return; 434 return;
512 } 435 }
436 this.__ensureFirstLastFocusables();
513 // TAB wraps from last to first focusable. 437 // TAB wraps from last to first focusable.
514 // Shift + TAB wraps from first to last focusable. 438 // Shift + TAB wraps from first to last focusable.
515 var shift = event.shiftKey; 439 var shift = event.shiftKey;
516 var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusable Node; 440 var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusable Node;
517 var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNo de; 441 var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNo de;
518 var shouldWrap = false; 442 var shouldWrap = false;
519 if (nodeToCheck === nodeToSet) { 443 if (nodeToCheck === nodeToSet) {
520 // If nodeToCheck is the same as nodeToSet, it means we have an overlay 444 // If nodeToCheck is the same as nodeToSet, it means we have an overlay
521 // with 0 or 1 focusables; in either case we still need to trap the 445 // with 0 or 1 focusables; in either case we still need to trap the
522 // focus within the overlay. 446 // focus within the overlay.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 483 }
560 }, 484 },
561 485
562 /** 486 /**
563 * Will call notifyResize if overlay is opened. 487 * Will call notifyResize if overlay is opened.
564 * Can be overridden in order to avoid multiple observers on the same node. 488 * Can be overridden in order to avoid multiple observers on the same node.
565 * @protected 489 * @protected
566 */ 490 */
567 _onNodesChange: function() { 491 _onNodesChange: function() {
568 if (this.opened && !this.__isAnimating) { 492 if (this.opened && !this.__isAnimating) {
493 // It might have added focusable nodes, so invalidate cached values.
494 this.invalidateTabbables();
569 this.notifyResize(); 495 this.notifyResize();
570 } 496 }
571 }, 497 },
572 498
573 /** 499 /**
500 * Will set first and last focusable nodes if any of them is not set.
501 * @private
502 */
503 __ensureFirstLastFocusables: function() {
504 if (!this.__firstFocusableNode || !this.__lastFocusableNode) {
505 var focusableNodes = this._focusableNodes;
506 this.__firstFocusableNode = focusableNodes[0];
507 this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];
508 }
509 },
510
511 /**
574 * Tasks executed when opened changes: prepare for the opening, move the 512 * Tasks executed when opened changes: prepare for the opening, move the
575 * focus, update the manager, render opened/closed. 513 * focus, update the manager, render opened/closed.
576 * @private 514 * @private
577 */ 515 */
578 __openedChanged: function() { 516 __openedChanged: function() {
579 if (this.opened) { 517 if (this.opened) {
580 // Make overlay visible, then add it to the manager. 518 // Make overlay visible, then add it to the manager.
581 this._prepareRenderOpened(); 519 this._prepareRenderOpened();
582 this._manager.addOverlay(this); 520 this._manager.addOverlay(this);
583 // Move the focus to the child node with [autofocus]. 521 // Move the focus to the child node with [autofocus].
(...skipping 23 matching lines...) Expand all
607 } 545 }
608 var self = this; 546 var self = this;
609 this.__raf = window.requestAnimationFrame(function nextAnimationFrame() { 547 this.__raf = window.requestAnimationFrame(function nextAnimationFrame() {
610 self.__raf = null; 548 self.__raf = null;
611 callback.call(self); 549 callback.call(self);
612 }); 550 });
613 } 551 }
614 552
615 }; 553 };
616 554
617 /** @polymerBehavior */ 555 /**
556 Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden o r shown, and displays
557 on top of other content. It includes an optional backdrop, and can be used to implement a variety
558 of UI controls including dialogs and drop downs. Multiple overlays may be disp layed at once.
559
560 See the [demo source code](https://github.com/PolymerElements/iron-overlay-beh avior/blob/master/demo/simple-overlay.html)
561 for an example.
562
563 ### Closing and canceling
564
565 An overlay may be hidden by closing or canceling. The difference between close and cancel is user
566 intent. Closing generally implies that the user acknowledged the content on th e overlay. By default,
567 it will cancel whenever the user taps outside it or presses the escape key. Th is behavior is
568 configurable with the `no-cancel-on-esc-key` and the `no-cancel-on-outside-cli ck` properties.
569 `close()` should be called explicitly by the implementer when the user interac ts with a control
570 in the overlay element. When the dialog is canceled, the overlay fires an 'iro n-overlay-canceled'
571 event. Call `preventDefault` on this event to prevent the overlay from closing .
572
573 ### Positioning
574
575 By default the element is sized and positioned to fit and centered inside the window. You can
576 position and size it manually using CSS. See `Polymer.IronFitBehavior`.
577
578 ### Backdrop
579
580 Set the `with-backdrop` attribute to display a backdrop behind the overlay. Th e backdrop is
581 appended to `<body>` and is of type `<iron-overlay-backdrop>`. See its doc pag e for styling
582 options.
583
584 In addition, `with-backdrop` will wrap the focus within the content in the lig ht DOM.
585 Override the [`_focusableNodes` getter](#Polymer.IronOverlayBehavior:property- _focusableNodes)
586 to achieve a different behavior.
587
588 ### Limitations
589
590 The element is styled to appear on top of other content by setting its `z-inde x` property. You
591 must ensure no element has a stacking context with a higher `z-index` than its parent stacking
592 context. You should place this element as a child of `<body>` whenever possibl e.
593
594 @demo demo/index.html
595 @polymerBehavior
596 */
618 Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableB ehavior, Polymer.IronOverlayBehaviorImpl]; 597 Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableB ehavior, Polymer.IronOverlayBehaviorImpl];
619 598
620 /** 599 /**
621 * Fired after the overlay opens. 600 * Fired after the overlay opens.
622 * @event iron-overlay-opened 601 * @event iron-overlay-opened
623 */ 602 */
624 603
625 /** 604 /**
626 * Fired when the overlay is canceled, but before it is closed. 605 * Fired when the overlay is canceled, but before it is closed.
627 * @event iron-overlay-canceled 606 * @event iron-overlay-canceled
628 * @param {Event} event The closing of the overlay can be prevented 607 * @param {Event} event The closing of the overlay can be prevented
629 * by calling `event.preventDefault()`. The `event.detail` is the original eve nt that 608 * by calling `event.preventDefault()`. The `event.detail` is the original eve nt that
630 * originated the canceling (e.g. ESC keyboard event or click event outside th e overlay). 609 * originated the canceling (e.g. ESC keyboard event or click event outside th e overlay).
631 */ 610 */
632 611
633 /** 612 /**
634 * Fired after the overlay closes. 613 * Fired after the overlay closes.
635 * @event iron-overlay-closed 614 * @event iron-overlay-closed
636 * @param {Event} event The `event.detail` is the `closingReason` property 615 * @param {Event} event The `event.detail` is the `closingReason` property
637 * (contains `canceled`, whether the overlay was canceled). 616 * (contains `canceled`, whether the overlay was canceled).
638 */ 617 */
639 618
640 })(); 619 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698