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

Side by Side Diff: chrome/browser/resources/shared/js/cr/ui/expandable_bubble.js

Issue 8208014: Update the notification bubble. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/shared/css/expandable_bubble.css ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(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 'use strict';
9
10 /**
11 * ExpandableBubble is a free-floating compact informational bubble with an
12 * arrow that points at a place of interest on the page. When clicked, the
13 * bubble expands to show more of its content. Width of the bubble is the
14 * width of the node it is overlapping when unexpanded. Expanded, it is of a
15 * fixed width, but variable height. Currently the arrow is always positioned
16 * at the bottom right and points down.
17 * @constructor
18 * @extends {cr.ui.div}
19 */
20 var ExpandableBubble = cr.ui.define('div');
21
22 ExpandableBubble.prototype = {
23 __proto__: HTMLDivElement.prototype,
24
25 /** @inheritDoc */
26 decorate: function() {
27 this.className = 'expandable-bubble';
28 this.innerHTML =
29 '<div class="expandable-bubble-contents">' +
30 '<div class="expandable-bubble-title"></div>' +
31 '<div class="expandable-bubble-main" hidden></div>' +
32 '</div>' +
33 '<div class="expandable-bubble-close" hidden></div>' +
34 '<div class="expandable-bubble-shadow"></div>' +
35 '<div class="expandable-bubble-arrow"></div>';
36
37 this.hidden = true;
38 },
39
40 /**
41 * Sets the title of the bubble. The title is always visible when the
42 * bubble is visible.
43 * @type {Node} An HTML element to set as the title.
44 */
45 set contentTitle(node) {
46 var bubbleTitle = this.querySelector('.expandable-bubble-title');
47 bubbleTitle.textContent = '';
48 bubbleTitle.appendChild(node);
49 },
50
51 /**
52 * Sets the content node of the bubble. The content node is only visible
53 * when the bubble is expanded.
54 * @param {Node} An HTML element.
55 */
56 set content(node) {
57 var bubbleMain = this.querySelector('.expandable-bubble-main');
58 bubbleMain.textContent = '';
59 bubbleMain.appendChild(node);
60 },
61
62 /**
63 * Sets the anchor node, i.e. the node that this bubble points at and
64 * partially overlaps.
65 * @param {HTMLElement} node The new anchor node.
66 */
67 set anchorNode(node) {
68 this.anchorNode_ = node;
69
70 if (!this.hidden)
71 this.resizeAndReposition_();
72 },
73
74 /**
75 * Updates the position of the bubble.
76 * @private
77 */
78 reposition_: function() {
79 var clientRect = this.anchorNode_.getBoundingClientRect();
80 this.style.left = this.style.right = clientRect.left + 'px';
81
82 var top = clientRect.top - 1;
83 if (this.expanded) {
Evan Stade 2011/11/01 20:47:24 prefer ternary
84 this.style.top =
85 (top - this.offsetHeight + this.unexpandedHeight) + 'px';
86 } else {
87 this.style.top = top + 'px';
88 }
89 },
90
91 /**
92 * Resizes the bubble and then repositions it.
93 * @private
94 */
95 resizeAndReposition_: function() {
96 var clientRect = this.anchorNode_.getBoundingClientRect();
97 var width = clientRect.width;
98 if (this.expanded) {
99 var expandedWidth = 250;
100 this.style.marginLeft = (width - expandedWidth) + 'px';
101 width = expandedWidth;
102 } else {
103 this.style.marginLeft = '0';
104 }
105
106 // Width is dynamic (when not expanded) based on the width of the anchor
107 // node, and the title and shadow need to follow suit.
108 this.style.width = width + 'px';
109 var bubbleTitle = this.querySelector('.expandable-bubble-title');
110 bubbleTitle.style.width = width - 2 + 'px';
111 var bubbleContent = this.querySelector('.expandable-bubble-main');
112 bubbleContent.style.width = width - 12 + 'px';
113 var bubbleShadow = this.querySelector('.expandable-bubble-shadow');
114 bubbleShadow.style.width = width + 2 + 'px';
115
116 // Also reposition the bubble -- dimensions have potentially changed.
117 this.reposition_();
118 },
119
120 /*
121 * Expand the bubble (bringing the full content into view).
122 * @private
123 */
124 expandBubble_: function() {
125 this.querySelector('.expandable-bubble-main').hidden = false;
126 this.querySelector('.expandable-bubble-close').hidden = false;
127 this.expanded = true;
128 this.resizeAndReposition_();
129 },
130
131 /**
132 * Collapse the bubble, hiding the main content and the close button.
133 * This is automatically called when the window is resized.
134 * @private
135 */
136 collapseBubble_: function() {
137 this.querySelector('.expandable-bubble-main').hidden = true;
138 this.querySelector('.expandable-bubble-close').hidden = true;
139 this.expanded = false;
140 this.resizeAndReposition_();
141 },
142
143 /**
144 * The onclick handler for the notification (expands the bubble).
145 * @param {Event} e The event.
146 * @private
147 */
148 onNotificationClick_ : function(e) {
149 if (!this.contains(e.target))
150 return;
151
152 if (!this.expanded) {
153 // Save the height of the unexpanded bubble, so we can make sure to
154 // position it correctly (arrow points in the same location) after
155 // we expand it.
156 this.unexpandedHeight = this.offsetHeight;
157 }
158
159 this.expandBubble_();
160 },
161
162 /**
163 * Shows the bubble. The bubble will start collapsed and expand when
164 * clicked.
165 */
166 show: function() {
167 if (!this.hidden)
168 return;
169
170 document.body.appendChild(this);
171 this.hidden = false;
172 this.resizeAndReposition_();
173
174 this.eventTracker_ = new EventTracker;
175 this.eventTracker_.add(window,
176 'load', this.resizeAndReposition_.bind(this));
Evan Stade 2011/11/01 20:47:24 why is this one necessary? I should have thought l
Finnur 2011/11/03 12:25:04 Nope. The show call can come before load is called
177 this.eventTracker_.add(window,
178 'resize', this.collapseBubble_.bind(this));
Evan Stade 2011/11/01 20:47:24 Why have you made this collapse instead of just re
Finnur 2011/11/03 12:25:04 We can start with re-position and see how it goes.
179 this.eventTracker_.add(this,
180 'click', this.onNotificationClick_.bind(this));
Evan Stade 2011/11/01 20:47:24 the bind(this) part is no longer necessary
181
182 var doc = this.ownerDocument;
183 this.eventTracker_.add(doc, 'keydown', this, true);
184 this.eventTracker_.add(doc, 'mousedown', this, true);
185 },
186
187 /**
188 * Hides the bubble from view.
189 */
190 hide: function() {
191 this.hidden = true;
192 this.eventTracker_.removeAll();
193 this.parentNode.removeChild(this);
194 },
195
196 /**
197 * Handles keydown and mousedown events, dismissing the bubble if
198 * necessary.
199 * @param {Event} e The event.
200 * @private
201 */
202 handleEvent: function(e) {
203 var handled = false;
204 switch (e.type) {
205 case 'keydown':
206 if (e.keyCode == 27) { // Esc.
207 if (this.expanded) {
208 this.collapseBubble_();
209 handled = true;
210 }
211 }
212 break;
213
214 case 'mousedown':
215 if (e.target == this.querySelector('.expandable-bubble-close')) {
216 this.hide();
217 handled = true;
218 } else if (!this.contains(e.target)) {
219 if (this.expanded) {
220 this.collapseBubble_();
221 handled = true;
222 }
223 }
224 break;
225 }
226
227 if (handled) {
228 // The bubble emulates a focus grab when expanded, so when we've
229 // collapsed/hide the bubble we consider the event handles and don't
230 // need to propagate it further.
231 e.stopPropagation();
232 e.preventDefault();
233 }
234 },
235 };
236
237 /**
238 * Whether the bubble is expanded or not.
239 * @type {boolean}
240 */
241 cr.defineProperty(ExpandableBubble, 'expanded', cr.PropertyKind.BOOL_ATTR);
242
243 return {
244 ExpandableBubble: ExpandableBubble
245 };
246 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/shared/css/expandable_bubble.css ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698