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

Side by Side Diff: chrome/browser/resources/ntp4/other_sessions.js

Issue 9959030: Allow hiding of sessions from Other Devices via context menu. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 months 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview The menu that shows tabs from sessions on other devices. 6 * @fileoverview The menu that shows tabs from sessions on other devices.
7 */ 7 */
8 8
9 cr.define('ntp', function() { 9 cr.define('ntp', function() {
10 'use strict'; 10 'use strict';
11 11
12 var localStrings = new LocalStrings(); 12 var localStrings = new LocalStrings();
13 var Menu = cr.ui.Menu; 13 var Menu = cr.ui.Menu;
14 var MenuItem = cr.ui.MenuItem; 14 var MenuItem = cr.ui.MenuItem;
15 var MenuButton = cr.ui.MenuButton; 15 var MenuButton = cr.ui.MenuButton;
16 var OtherSessionsMenuButton = cr.ui.define('button'); 16 var OtherSessionsMenuButton = cr.ui.define('button');
17 17
18 // Histogram buckets for UMA tracking of menu usage. 18 // Histogram buckets for UMA tracking of menu usage.
19 var HISTOGRAM_EVENT = { 19 var HISTOGRAM_EVENT = {
20 INITIALIZED: 0, 20 INITIALIZED: 0,
21 SHOW_MENU: 1, 21 SHOW_MENU: 1,
22 LINK_CLICKED: 2, 22 LINK_CLICKED: 2,
23 LINK_RIGHT_CLICKED: 3 23 LINK_RIGHT_CLICKED: 3,
24 SESSION_NAME_RIGHT_CLICKED: 4
24 }; 25 };
25 var HISTOGRAM_EVENT_LIMIT = HISTOGRAM_EVENT.LINK_RIGHT_CLICKED + 1; 26 var HISTOGRAM_EVENT_LIMIT = HISTOGRAM_EVENT.SESSION_NAME_RIGHT_CLICKED + 1;
26 27
27 OtherSessionsMenuButton.prototype = { 28 OtherSessionsMenuButton.prototype = {
28 __proto__: MenuButton.prototype, 29 __proto__: MenuButton.prototype,
29 30
30 decorate: function() { 31 decorate: function() {
31 MenuButton.prototype.decorate.call(this); 32 MenuButton.prototype.decorate.call(this);
32 this.menu = new Menu; 33 this.menu = new Menu;
33 cr.ui.decorate(this.menu, Menu); 34 cr.ui.decorate(this.menu, Menu);
34 this.menu.classList.add('footer-menu'); 35 this.menu.classList.add('footer-menu');
35 this.menu.addEventListener('contextmenu', 36 this.menu.addEventListener('contextmenu',
36 this.onContextMenu_.bind(this), true); 37 this.onContextMenu_.bind(this), true);
37 document.body.appendChild(this.menu); 38 document.body.appendChild(this.menu);
38 39
40 // Create the context menu that appears when the user right clicks
41 // on a device name.
42 this.deviceContextMenu_ = DeviceContextMenu.getInstance().menu;
43 document.body.appendChild(this.deviceContextMenu_);
44
39 this.promoMessage_ = $('other-sessions-promo-template').cloneNode(true); 45 this.promoMessage_ = $('other-sessions-promo-template').cloneNode(true);
40 this.promoMessage_.removeAttribute('id'); // Prevent a duplicate id. 46 this.promoMessage_.removeAttribute('id'); // Prevent a duplicate id.
41 47
42 this.sessions_ = []; 48 this.sessions_ = [];
43 this.anchorType = cr.ui.AnchorType.ABOVE; 49 this.anchorType = cr.ui.AnchorType.ABOVE;
44 this.invertLeftRight = true; 50 this.invertLeftRight = true;
45 51
46 this.recordUmaEvent_(HISTOGRAM_EVENT.INITIALIZED); 52 this.recordUmaEvent_(HISTOGRAM_EVENT.INITIALIZED);
47 }, 53 },
48 54
(...skipping 11 matching lines...) Expand all
60 */ 66 */
61 recordUmaEvent_: function(eventId) { 67 recordUmaEvent_: function(eventId) {
62 chrome.send('metricsHandler:recordInHistogram', 68 chrome.send('metricsHandler:recordInHistogram',
63 ['NewTabPage.OtherSessionsMenu', eventId, HISTOGRAM_EVENT_LIMIT]); 69 ['NewTabPage.OtherSessionsMenu', eventId, HISTOGRAM_EVENT_LIMIT]);
64 }, 70 },
65 71
66 /** 72 /**
67 * Handle a context menu event for an object in the menu's DOM subtree. 73 * Handle a context menu event for an object in the menu's DOM subtree.
68 */ 74 */
69 onContextMenu_: function(e) { 75 onContextMenu_: function(e) {
70 // Only record the action if it occurred in one of the menu items. 76 // Only record the action if it occurred in one of the menu items or
71 if (findAncestorByClass(e.target, 'footer-menu-item')) 77 // on one of the session headings.
78 if (findAncestorByClass(e.target, 'footer-menu-item')) {
72 this.recordUmaEvent_(HISTOGRAM_EVENT.LINK_RIGHT_CLICKED); 79 this.recordUmaEvent_(HISTOGRAM_EVENT.LINK_RIGHT_CLICKED);
80 } else if (findAncestorByClass(e.target, 'session-heading')) {
81 this.recordUmaEvent_(
82 HISTOGRAM_EVENT.SESSION_NAME_RIGHT_CLICKED);
83
84 // Let the context menu know which session it was invoked on,
85 // since they all share the same instance of the menu.
86 DeviceContextMenu.getInstance().setSessionTag(e.target.sessionTag_);
87 }
73 }, 88 },
74 89
75 /** 90 /**
91 * Hides the menu.
92 * @override
93 */
94 hideMenu: function() {
95 // Don't hide if the device context menu is currently showing.
96 if (cr.ui.contextMenuHandler.menu != this.deviceContextMenu_)
97 MenuButton.prototype.hideMenu.call(this);
98 },
99
100 /**
76 * Shows the menu, first rebuilding it if necessary. 101 * Shows the menu, first rebuilding it if necessary.
77 * TODO(estade): the right of the menu should align with the right of the 102 * TODO(estade): the right of the menu should align with the right of the
78 * button. 103 * button.
79 * @override 104 * @override
80 */ 105 */
81 showMenu: function() { 106 showMenu: function() {
82 if (this.sessions_.length == 0) 107 if (this.sessions_.length == 0)
83 chrome.send('getForeignSessions'); 108 chrome.send('getForeignSessions');
84 this.recordUmaEvent_(HISTOGRAM_EVENT.SHOW_MENU); 109 this.recordUmaEvent_(HISTOGRAM_EVENT.SHOW_MENU);
85 MenuButton.prototype.showMenu.call(this); 110 MenuButton.prototype.showMenu.call(this);
(...skipping 27 matching lines...) Expand all
113 * Add the UI for a foreign session to the menu. 138 * Add the UI for a foreign session to the menu.
114 * @param {Object} session Object describing the foreign session. 139 * @param {Object} session Object describing the foreign session.
115 */ 140 */
116 addSession_: function(session) { 141 addSession_: function(session) {
117 var doc = this.ownerDocument; 142 var doc = this.ownerDocument;
118 143
119 var section = doc.createElement('section'); 144 var section = doc.createElement('section');
120 this.menu.appendChild(section); 145 this.menu.appendChild(section);
121 146
122 var heading = doc.createElement('h3'); 147 var heading = doc.createElement('h3');
148 heading.classList.add('session-heading');
Evan Stade 2012/03/30 21:00:30 className =
Patrick Dubroy 2012/03/30 21:21:20 Done.
123 heading.textContent = session.name; 149 heading.textContent = session.name;
150 heading.sessionTag_ = session.tag;
124 section.appendChild(heading); 151 section.appendChild(heading);
125 152
153 var timeSpan = doc.createElement('span');
154 timeSpan.classList.add('details');
Evan Stade 2012/03/30 21:00:30 className =
Patrick Dubroy 2012/03/30 21:21:20 Done.
155 timeSpan.textContent = session.modifiedTime;
156 heading.appendChild(timeSpan);
157
158 cr.ui.contextMenuHandler.setContextMenu(heading,
159 this.deviceContextMenu_);
160
126 for (var i = 0; i < session.windows.length; i++) { 161 for (var i = 0; i < session.windows.length; i++) {
127 var window = session.windows[i]; 162 var window = session.windows[i];
163
164 // Show a separator between multiple windows in the same session.
165 if (i > 0)
166 section.appendChild(doc.createElement('hr'));
167
128 for (var j = 0; j < window.tabs.length; j++) { 168 for (var j = 0; j < window.tabs.length; j++) {
129 var tab = window.tabs[j]; 169 var tab = window.tabs[j];
130 var a = doc.createElement('a'); 170 var a = doc.createElement('a');
131 a.className = 'footer-menu-item'; 171 a.className = 'footer-menu-item';
132 a.textContent = tab.title; 172 a.textContent = tab.title;
133 a.href = tab.url; 173 a.href = tab.url;
134 a.style.backgroundImage = 'url(chrome://favicon/' + tab.url + ')'; 174 a.style.backgroundImage = 'url(chrome://favicon/' + tab.url + ')';
135 var clickHandler = this.makeClickHandler_( 175 var clickHandler = this.makeClickHandler_(
136 session.tag, String(window.sessionId), String(tab.sessionId)); 176 session.tag, String(window.sessionId), String(tab.sessionId));
137 a.addEventListener('click', clickHandler); 177 a.addEventListener('click', clickHandler);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 * @param {boolean} signedIn Is the user currently signed in? 212 * @param {boolean} signedIn Is the user currently signed in?
173 */ 213 */
174 updateSignInState: function(signedIn) { 214 updateSignInState: function(signedIn) {
175 if (signedIn) 215 if (signedIn)
176 chrome.send('getForeignSessions'); 216 chrome.send('getForeignSessions');
177 else 217 else
178 this.classList.add('invisible'); 218 this.classList.add('invisible');
179 }, 219 },
180 }; 220 };
181 221
222 /**
223 * Context menu for device names in the list of sessions.
224 * This class is designed to be used as a singleton.
225 *
226 * @constructor
227 */
228 function DeviceContextMenu() {
229 this.__proto__ = DeviceContextMenu.prototype;
230 this.initialize();
231 }
232 cr.addSingletonGetter(DeviceContextMenu);
233
234 DeviceContextMenu.prototype = {
235
236 initialize: function() {
237 var menu = new cr.ui.Menu;
238 cr.ui.decorate(menu, cr.ui.Menu);
239 menu.classList.add('device-context-menu');
240 menu.classList.add('footer-menu-context-menu');
241 this.menu = menu;
242 this.hideItem_ = this.appendMenuItem_('hide');
243 this.hideItem_.addEventListener('activate', this.onHide_.bind(this));
244 },
245
246 /**
247 * Appends a menu item to |this.menu|.
248 * @param {String} textId The ID for the localized string that acts as
249 * the item's label.
250 */
251 appendMenuItem_: function(textId) {
252 var button = cr.doc.createElement('button');
253 this.menu.appendChild(button);
254 cr.ui.decorate(button, cr.ui.MenuItem);
255 button.textContent = localStrings.getString(textId);
256 return button;
257 },
258
259 /**
260 * Handler for the 'hide' menu item.
261 * @param {Event} e The activation event.
262 * @private
263 */
264 onHide_: function(e) {
265 chrome.send('deleteForeignSession', [this.sessionTag_]);
266 chrome.send('getForeignSessions'); // Refresh the list.
267 },
268
269 /**
270 * Set the session tag which identifies the session that the context menu
271 * was invoked on.
272 * @param {String} tag The session tag.
273 */
274 setSessionTag: function(tag) {
275 this.sessionTag_ = tag;
276 }
277 };
278
182 return { 279 return {
183 OtherSessionsMenuButton: OtherSessionsMenuButton, 280 OtherSessionsMenuButton: OtherSessionsMenuButton,
184 }; 281 };
185 }); 282 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698