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 |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f9707fec947d23dcf59b65beba4ac486b92d1200 |
--- /dev/null |
+++ b/chrome/browser/resources/shared/js/cr/ui/bubble.js |
@@ -0,0 +1,111 @@ |
+// Copyright (c) 2011 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() { |
+ |
+ /** |
+ * Bubble is a free-floating informational bubble with a triangular arrow |
+ * that points at a place of interest on the page. Currently the arrow is |
+ * always positioned at the bottom left and points down. |
+ */ |
Rick Byers
2011/08/12 21:54:00
Nice, I like this class.
Evan Stade
2011/08/12 22:35:13
side note: the alternative I have heard is used by
|
+ var Bubble = cr.ui.define('div'); |
+ |
+ Bubble.prototype = { |
+ __proto__: HTMLDivElement.prototype, |
+ |
+ decorate: function() { |
+ this.className = 'bubble'; |
+ this.innerHTML = |
+ '<div class=\"bubble-contents\"></div>' + |
+ '<div class=\"bubble-shadow\"></div>' + |
+ '<div class=\"bubble-arrow\"></div>'; |
+ |
+ this.hidden = true; |
+ }, |
+ |
+ /** |
+ * Sets the text message within the bubble. |
+ * @param {String} text The message string. |
+ */ |
+ setText: function(text) { |
+ this.querySelector('.bubble-contents').textContent = text; |
+ }, |
+ |
+ /** |
+ * Sets the anchor node, i.e. the node that this bubble points at. |
+ * @param {HTMLElement} node The new anchor node. |
+ */ |
+ attach: function(node) { |
+ this.anchorNode_ = node; |
+ }, |
+ |
+ /** |
+ * Updates the position of the bubble. This is automatically called when |
+ * the window is resized, but should also be called any time the layout |
+ * may have changed. |
+ */ |
+ reposition: function() { |
+ var node = this.anchorNode_; |
+ var clientRect = node.getBoundingClientRect(); |
+ |
+ this.style.left = (clientRect.left + clientRect.right) / 2 + 'px'; |
+ this.style.top = (clientRect.top - this.clientHeight) + 'px'; |
+ }, |
+ |
+ /** |
+ * Starts showing the bubble. The bubble will grab input and show until the |
+ * user clicks away. |
+ */ |
+ show: function() { |
Rick Byers
2011/08/12 21:54:00
add some protection against calling show twice (do
Evan Stade
2011/08/12 22:35:13
done (also improved attach)
|
+ document.body.appendChild(this); |
+ this.hidden = false; |
+ this.reposition(); |
+ |
+ this.eventTracker_ = new EventTracker; |
+ this.eventTracker_.add(window, 'resize', this.reposition.bind(this)); |
+ |
+ 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.eventTracker_.removeAll(); |
+ this.parentNode.removeChild(this); |
+ }, |
+ |
+ /** |
+ * Handles keywdown and mousedown events, dismissing the bubble if |
+ * necessary. |
+ * @param {Event} e The event. |
+ */ |
+ handleEvent: function(e) { |
+ switch (e.type) { |
+ case 'keydown': |
+ if (e.keyCode == 27 /* Esc */) |
+ this.hide(); |
+ break; |
+ |
+ case 'mousedown': |
+ if (!this.contains(e.target)) |
+ this.hide(); |
+ break; |
+ } |
+ |
+ e.stopPropagation(); |
+ e.preventDefault(); |
Rick Byers
2011/08/12 21:54:00
you really want to swallow all input on the docume
Evan Stade
2011/08/12 22:35:13
I guess this is up to one of the UI leads; I could
Rick Byers
2011/08/12 23:46:08
I agree this should match behavior of other bubble
|
+ return; |
+ }, |
+ }; |
+ |
+ return { |
+ Bubble: Bubble |
+ }; |
+}); |