| Index: chrome/browser/resources/shared/js/cr/ui/expandable_bubble.js
|
| ===================================================================
|
| --- chrome/browser/resources/shared/js/cr/ui/expandable_bubble.js (revision 177292)
|
| +++ chrome/browser/resources/shared/js/cr/ui/expandable_bubble.js (working copy)
|
| @@ -1,303 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -// require: event_tracker.js
|
| -
|
| -cr.define('cr.ui', function() {
|
| - 'use strict';
|
| -
|
| - /**
|
| - * ExpandableBubble is a free-floating compact informational bubble with an
|
| - * arrow that points at a place of interest on the page. When clicked, the
|
| - * bubble expands to show more of its content. Width of the bubble is the
|
| - * width of the node it is overlapping when unexpanded. Expanded, it is of a
|
| - * fixed width, but variable height. Currently the arrow is always positioned
|
| - * at the bottom right and points down.
|
| - * @constructor
|
| - * @extends {cr.ui.div}
|
| - */
|
| - var ExpandableBubble = cr.ui.define('div');
|
| -
|
| - ExpandableBubble.prototype = {
|
| - __proto__: HTMLDivElement.prototype,
|
| -
|
| - /** @override */
|
| - decorate: function() {
|
| - this.className = 'expandable-bubble';
|
| - this.innerHTML =
|
| - '<div class="expandable-bubble-contents">' +
|
| - '<div class="expandable-bubble-title"></div>' +
|
| - '<div class="expandable-bubble-main" hidden></div>' +
|
| - '</div>' +
|
| - '<div class="expandable-bubble-close" hidden></div>';
|
| -
|
| - this.hidden = true;
|
| - this.bubbleSuppressed = false;
|
| - this.handleCloseEvent = this.hide;
|
| - },
|
| -
|
| - /**
|
| - * Sets the title of the bubble. The title is always visible when the
|
| - * bubble is visible.
|
| - * @type {Node} An HTML element to set as the title.
|
| - */
|
| - set contentTitle(node) {
|
| - var bubbleTitle = this.querySelector('.expandable-bubble-title');
|
| - bubbleTitle.textContent = '';
|
| - bubbleTitle.appendChild(node);
|
| - },
|
| -
|
| - /**
|
| - * Sets the content node of the bubble. The content node is only visible
|
| - * when the bubble is expanded.
|
| - * @param {Node} An HTML element.
|
| - */
|
| - set content(node) {
|
| - var bubbleMain = this.querySelector('.expandable-bubble-main');
|
| - bubbleMain.textContent = '';
|
| - bubbleMain.appendChild(node);
|
| - },
|
| -
|
| - /**
|
| - * Sets the anchor node, i.e. the node that this bubble points at and
|
| - * partially overlaps.
|
| - * @param {HTMLElement} node The new anchor node.
|
| - */
|
| - set anchorNode(node) {
|
| - this.anchorNode_ = node;
|
| -
|
| - if (!this.hidden)
|
| - this.resizeAndReposition();
|
| - },
|
| -
|
| - /**
|
| - * Handles the close event which is triggered when the close button
|
| - * is clicked. By default is set to this.hide.
|
| - * @param {function} A function with no parameters
|
| - */
|
| - set handleCloseEvent(func) {
|
| - this.handleCloseEvent_ = func;
|
| - },
|
| -
|
| - /**
|
| - * Temporarily suppresses the bubble from view (and toggles it back).
|
| - * 'Suppressed' and 'hidden' are two bubble states that both indicate that
|
| - * the bubble should not be visible, but when you 'un-suppress' a bubble,
|
| - * only a suppressed bubble becomes visible. This can be handy, for example,
|
| - * if the user switches away from the app card (then we need to know which
|
| - * bubbles to show (only the suppressed ones, not the hidden ones). Hiding
|
| - * and un-hiding a bubble overrides the suppressed state (a bubble cannot
|
| - * be suppressed but not hidden).
|
| - */
|
| - set suppressed(suppress) {
|
| - if (suppress) {
|
| - // If the bubble is already hidden, then we don't need to suppress it.
|
| - if (this.hidden)
|
| - return;
|
| -
|
| - this.hidden = true;
|
| - } else if (this.bubbleSuppressed) {
|
| - this.hidden = false;
|
| - }
|
| - this.bubbleSuppressed = suppress;
|
| - this.resizeAndReposition(this);
|
| - },
|
| -
|
| - /**
|
| - * Updates the position of the bubble.
|
| - * @private
|
| - */
|
| - reposition_: function() {
|
| - var clientRect = this.anchorNode_.getBoundingClientRect();
|
| -
|
| - // Center bubble in collapsed mode (if it doesn't take up all the room we
|
| - // have).
|
| - var offset = 0;
|
| - if (!this.expanded)
|
| - offset = (clientRect.width - parseInt(this.style.width)) / 2;
|
| - this.style.left = this.style.right = clientRect.left + offset + 'px';
|
| -
|
| - var top = Math.max(0, clientRect.top - 4);
|
| - this.style.top = this.expanded ?
|
| - (top - this.offsetHeight + this.unexpandedHeight) + 'px' :
|
| - top + 'px';
|
| - },
|
| -
|
| - /**
|
| - * Resizes the bubble and then repositions it.
|
| - * @private
|
| - */
|
| - resizeAndReposition: function() {
|
| - var clientRect = this.anchorNode_.getBoundingClientRect();
|
| - var width = clientRect.width;
|
| -
|
| - var bubbleTitle = this.querySelector('.expandable-bubble-title');
|
| - var closeElement = this.querySelector('.expandable-bubble-close');
|
| - var closeWidth = this.expanded ? closeElement.clientWidth : 0;
|
| - var margin = 15;
|
| -
|
| - // Suppress the width style so we can get it to calculate its width.
|
| - // We'll set the right width again when we are done.
|
| - bubbleTitle.style.width = '';
|
| -
|
| - if (this.expanded) {
|
| - // We always show the full title but never show less width than 250
|
| - // pixels.
|
| - var expandedWidth =
|
| - Math.max(250, bubbleTitle.scrollWidth + closeWidth + margin);
|
| - this.style.marginLeft = (width - expandedWidth) + 'px';
|
| - width = expandedWidth;
|
| - } else {
|
| - var newWidth = Math.min(bubbleTitle.scrollWidth + margin, width);
|
| - // If we've maxed out in width then apply the mask.
|
| - this.masked = newWidth == width;
|
| - width = newWidth;
|
| - this.style.marginLeft = '0';
|
| - }
|
| -
|
| - // Width is determined by the width of the title (when not expanded) but
|
| - // capped to the width of the anchor node.
|
| - this.style.width = width + 'px';
|
| - bubbleTitle.style.width = Math.max(0, width - margin - closeWidth) + 'px';
|
| -
|
| - // Also reposition the bubble -- dimensions have potentially changed.
|
| - this.reposition_();
|
| - },
|
| -
|
| - /*
|
| - * Expand the bubble (bringing the full content into view).
|
| - * @private
|
| - */
|
| - expandBubble_: function() {
|
| - this.querySelector('.expandable-bubble-main').hidden = false;
|
| - this.querySelector('.expandable-bubble-close').hidden = false;
|
| - this.expanded = true;
|
| - this.resizeAndReposition();
|
| - },
|
| -
|
| - /**
|
| - * Collapse the bubble, hiding the main content and the close button.
|
| - * This is automatically called when the window is resized.
|
| - * @private
|
| - */
|
| - collapseBubble_: function() {
|
| - this.querySelector('.expandable-bubble-main').hidden = true;
|
| - this.querySelector('.expandable-bubble-close').hidden = true;
|
| - this.expanded = false;
|
| - this.resizeAndReposition();
|
| - },
|
| -
|
| - /**
|
| - * The onclick handler for the notification (expands the bubble).
|
| - * @param {Event} e The event.
|
| - * @private
|
| - */
|
| - onNotificationClick_: function(e) {
|
| - if (!this.contains(e.target))
|
| - return;
|
| -
|
| - if (!this.expanded) {
|
| - // Save the height of the unexpanded bubble, so we can make sure to
|
| - // position it correctly (arrow points in the same location) after
|
| - // we expand it.
|
| - this.unexpandedHeight = this.offsetHeight;
|
| - }
|
| -
|
| - this.expandBubble_();
|
| - },
|
| -
|
| - /**
|
| - * Shows the bubble. The bubble will start collapsed and expand when
|
| - * clicked.
|
| - */
|
| - show: function() {
|
| - if (!this.hidden)
|
| - return;
|
| -
|
| - document.body.appendChild(this);
|
| - this.hidden = false;
|
| - this.resizeAndReposition();
|
| -
|
| - this.eventTracker_ = new EventTracker;
|
| - this.eventTracker_.add(window,
|
| - 'load', this.resizeAndReposition.bind(this));
|
| - this.eventTracker_.add(window,
|
| - 'resize', this.resizeAndReposition.bind(this));
|
| - this.eventTracker_.add(this, 'click', this.onNotificationClick_);
|
| -
|
| - var doc = this.ownerDocument;
|
| - this.eventTracker_.add(doc, 'keydown', this, true);
|
| - this.eventTracker_.add(doc, 'mousedown', this, true);
|
| - },
|
| -
|
| - /**
|
| - * Hides the bubble from view.
|
| - */
|
| - hide: function() {
|
| - this.hidden = true;
|
| - this.bubbleSuppressed = false;
|
| - this.eventTracker_.removeAll();
|
| - this.parentNode.removeChild(this);
|
| - },
|
| -
|
| - /**
|
| - * Handles keydown and mousedown events, dismissing the bubble if
|
| - * necessary.
|
| - * @param {Event} e The event.
|
| - * @private
|
| - */
|
| - handleEvent: function(e) {
|
| - var handled = false;
|
| - switch (e.type) {
|
| - case 'keydown':
|
| - if (e.keyCode == 27) { // Esc.
|
| - if (this.expanded) {
|
| - this.collapseBubble_();
|
| - handled = true;
|
| - }
|
| - }
|
| - break;
|
| -
|
| - case 'mousedown':
|
| - if (e.target == this.querySelector('.expandable-bubble-close')) {
|
| - this.handleCloseEvent_();
|
| - handled = true;
|
| - } else if (!this.contains(e.target)) {
|
| - if (this.expanded) {
|
| - this.collapseBubble_();
|
| - handled = true;
|
| - }
|
| - }
|
| - break;
|
| - }
|
| -
|
| - if (handled) {
|
| - // The bubble emulates a focus grab when expanded, so when we've
|
| - // collapsed/hide the bubble we consider the event handles and don't
|
| - // need to propagate it further.
|
| - e.stopPropagation();
|
| - e.preventDefault();
|
| - }
|
| - },
|
| - };
|
| -
|
| - /**
|
| - * Whether the bubble is expanded or not.
|
| - * @type {boolean}
|
| - */
|
| - cr.defineProperty(ExpandableBubble, 'expanded', cr.PropertyKind.BOOL_ATTR);
|
| -
|
| - /**
|
| - * Whether the title needs to be masked out towards the right, which indicates
|
| - * to the user that part of the text is clipped. This is only used when the
|
| - * bubble is collapsed and the title doesn't fit because it is maxed out in
|
| - * width within the anchored node.
|
| - * @type {boolean}
|
| - */
|
| - cr.defineProperty(ExpandableBubble, 'masked', cr.PropertyKind.BOOL_ATTR);
|
| -
|
| - return {
|
| - ExpandableBubble: ExpandableBubble
|
| - };
|
| -});
|
|
|