OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // require: event_tracker.js | |
6 | |
7 cr.define('cr.ui', function() { | |
8 | |
9 /** | |
10 * Bubble is a free-floating informational bubble with a triangular arrow | |
11 * that points at a place of interest on the page. Currently the arrow is | |
12 * always positioned at the bottom left and points down. | |
13 */ | |
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
| |
14 var Bubble = cr.ui.define('div'); | |
15 | |
16 Bubble.prototype = { | |
17 __proto__: HTMLDivElement.prototype, | |
18 | |
19 decorate: function() { | |
20 this.className = 'bubble'; | |
21 this.innerHTML = | |
22 '<div class=\"bubble-contents\"></div>' + | |
23 '<div class=\"bubble-shadow\"></div>' + | |
24 '<div class=\"bubble-arrow\"></div>'; | |
25 | |
26 this.hidden = true; | |
27 }, | |
28 | |
29 /** | |
30 * Sets the text message within the bubble. | |
31 * @param {String} text The message string. | |
32 */ | |
33 setText: function(text) { | |
34 this.querySelector('.bubble-contents').textContent = text; | |
35 }, | |
36 | |
37 /** | |
38 * Sets the anchor node, i.e. the node that this bubble points at. | |
39 * @param {HTMLElement} node The new anchor node. | |
40 */ | |
41 attach: function(node) { | |
42 this.anchorNode_ = node; | |
43 }, | |
44 | |
45 /** | |
46 * Updates the position of the bubble. This is automatically called when | |
47 * the window is resized, but should also be called any time the layout | |
48 * may have changed. | |
49 */ | |
50 reposition: function() { | |
51 var node = this.anchorNode_; | |
52 var clientRect = node.getBoundingClientRect(); | |
53 | |
54 this.style.left = (clientRect.left + clientRect.right) / 2 + 'px'; | |
55 this.style.top = (clientRect.top - this.clientHeight) + 'px'; | |
56 }, | |
57 | |
58 /** | |
59 * Starts showing the bubble. The bubble will grab input and show until the | |
60 * user clicks away. | |
61 */ | |
62 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)
| |
63 document.body.appendChild(this); | |
64 this.hidden = false; | |
65 this.reposition(); | |
66 | |
67 this.eventTracker_ = new EventTracker; | |
68 this.eventTracker_.add(window, 'resize', this.reposition.bind(this)); | |
69 | |
70 var doc = this.ownerDocument; | |
71 this.eventTracker_.add(doc, 'keydown', this, true); | |
72 this.eventTracker_.add(doc, 'mousedown', this, true); | |
73 }, | |
74 | |
75 /** | |
76 * Hides the bubble from view. | |
77 */ | |
78 hide: function() { | |
79 this.hidden = true; | |
80 this.eventTracker_.removeAll(); | |
81 this.parentNode.removeChild(this); | |
82 }, | |
83 | |
84 /** | |
85 * Handles keywdown and mousedown events, dismissing the bubble if | |
86 * necessary. | |
87 * @param {Event} e The event. | |
88 */ | |
89 handleEvent: function(e) { | |
90 switch (e.type) { | |
91 case 'keydown': | |
92 if (e.keyCode == 27 /* Esc */) | |
93 this.hide(); | |
94 break; | |
95 | |
96 case 'mousedown': | |
97 if (!this.contains(e.target)) | |
98 this.hide(); | |
99 break; | |
100 } | |
101 | |
102 e.stopPropagation(); | |
103 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
| |
104 return; | |
105 }, | |
106 }; | |
107 | |
108 return { | |
109 Bubble: Bubble | |
110 }; | |
111 }); | |
OLD | NEW |