| Index: chrome/browser/resources/shared/js/cr/ui/bubble.js
|
| diff --git a/chrome/browser/resources/shared/js/cr/ui/bubble.js b/chrome/browser/resources/shared/js/cr/ui/bubble.js
|
| index 998b4584a1bba1c28bd0bb230e93c229aa937100..e938c7af1b069f31a1d263140b8b0452bc48405d 100644
|
| --- a/chrome/browser/resources/shared/js/cr/ui/bubble.js
|
| +++ b/chrome/browser/resources/shared/js/cr/ui/bubble.js
|
| @@ -314,7 +314,7 @@ cr.define('cr.ui', function() {
|
| var Bubble = cr.ui.define('div');
|
|
|
| Bubble.prototype = {
|
| - // Set up the prototype chain
|
| + // Set up the prototype chain.
|
| __proto__: BubbleBase.prototype,
|
|
|
| /**
|
| @@ -397,10 +397,118 @@ cr.define('cr.ui', function() {
|
| },
|
| };
|
|
|
| + /**
|
| + * A bubble that closes automatically when the user clicks or moves the focus
|
| + * outside the bubble and its target element, scrolls the underlying document
|
| + * or resizes the window.
|
| + */
|
| + var AutoCloseBubble = cr.ui.define('div');
|
| +
|
| + AutoCloseBubble.prototype = {
|
| + // Set up the prototype chain.
|
| + __proto__: BubbleBase.prototype,
|
| +
|
| + /**
|
| + * Initialization function for the cr.ui framework.
|
| + */
|
| + decorate: function() {
|
| + BubbleBase.prototype.decorate.call(this);
|
| + this.classList.add('auto-close-bubble');
|
| + },
|
| +
|
| + /**
|
| + * Set the DOM sibling node, i.e. the node as whose sibling the bubble
|
| + * should join the DOM to ensure that focusable elements inside the bubble
|
| + * follow the target element in the document's tab order. Only available
|
| + * when the bubble is not being shown.
|
| + * @param {HTMLElement} node The new DOM sibling node.
|
| + */
|
| + set domSibling(node) {
|
| + if (!this.hidden)
|
| + return;
|
| +
|
| + this.domSibling_ = node;
|
| + },
|
| +
|
| + /**
|
| + * Show the bubble.
|
| + */
|
| + show: function() {
|
| + if (!this.hidden)
|
| + return;
|
| +
|
| + BubbleBase.prototype.show.call(this);
|
| + this.domSibling_.showingBubble = true;
|
| +
|
| + var doc = this.ownerDocument;
|
| + this.eventTracker_.add(doc, 'mousewheel', this, true);
|
| + this.eventTracker_.add(doc, 'scroll', this, true);
|
| + this.eventTracker_.add(doc, 'elementFocused', this, true);
|
| + this.eventTracker_.add(window, 'resize', this);
|
| + },
|
| +
|
| + /**
|
| + * Hide the bubble.
|
| + */
|
| + hide: function() {
|
| + BubbleBase.prototype.hide.call(this);
|
| + this.domSibling_.showingBubble = false;
|
| + },
|
| +
|
| + /**
|
| + * Handle events, closing the bubble when the user clicks or moves the focus
|
| + * outside the bubble and its target element, scrolls the underlying
|
| + * document or resizes the window.
|
| + * @param {Event} event The event.
|
| + */
|
| + handleEvent: function(event) {
|
| + BubbleBase.prototype.handleEvent.call(this, event);
|
| +
|
| + switch (event.type) {
|
| + // Close the bubble when the user clicks outside it, except if it is a
|
| + // left-click on the bubble's target element (allowing the target to
|
| + // handle the event and close the bubble itself).
|
| + case 'mousedown':
|
| + if (event.button == 0 && this.anchorNode_.contains(event.target))
|
| + break;
|
| + // Close the bubble when the underlying document is scrolled.
|
| + case 'mousewheel':
|
| + case 'scroll':
|
| + if (this.contains(event.target))
|
| + break;
|
| + // Close the bubble when the window is resized.
|
| + case 'resize':
|
| + this.hide();
|
| + break;
|
| + // Close the bubble when the focus moves to an element that is not the
|
| + // bubble target and is not inside the bubble.
|
| + case 'elementFocused':
|
| + if (!this.anchorNode_.contains(event.target) &&
|
| + !this.contains(event.target)) {
|
| + this.hide();
|
| + }
|
| + break;
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Attach the bubble to the document's DOM, making it a sibling of the
|
| + * |domSibling_| so that focusable elements inside the bubble follow the
|
| + * target element in the document's tab order.
|
| + * @private
|
| + */
|
| + attachToDOM_: function() {
|
| + var parent = this.domSibling_.parentNode;
|
| + parent.insertBefore(this, this.domSibling_.nextSibling);
|
| + },
|
| + };
|
| +
|
| +
|
| return {
|
| ArrowLocation: ArrowLocation,
|
| BubbleAlignment: BubbleAlignment,
|
| BubbleBase: BubbleBase,
|
| - Bubble: Bubble
|
| + Bubble: Bubble,
|
| + AutoCloseBubble: AutoCloseBubble
|
| };
|
| });
|
|
|