Chromium Code Reviews| Index: chrome/browser/resources/ntp4/other_sessions.js |
| diff --git a/chrome/browser/resources/ntp4/other_sessions.js b/chrome/browser/resources/ntp4/other_sessions.js |
| index 9abd87550e3db175d6179bbfb693aa7a6e1c39ca..0474a0e638b923a165dd2e9196b40183bb7f643b 100644 |
| --- a/chrome/browser/resources/ntp4/other_sessions.js |
| +++ b/chrome/browser/resources/ntp4/other_sessions.js |
| @@ -20,9 +20,10 @@ cr.define('ntp', function() { |
| INITIALIZED: 0, |
| SHOW_MENU: 1, |
| LINK_CLICKED: 2, |
| - LINK_RIGHT_CLICKED: 3 |
| + LINK_RIGHT_CLICKED: 3, |
| + SESSION_NAME_RIGHT_CLICKED: 4 |
| }; |
| - var HISTOGRAM_EVENT_LIMIT = HISTOGRAM_EVENT.LINK_RIGHT_CLICKED + 1; |
| + var HISTOGRAM_EVENT_LIMIT = HISTOGRAM_EVENT.SESSION_NAME_RIGHT_CLICKED + 1; |
| OtherSessionsMenuButton.prototype = { |
| __proto__: MenuButton.prototype, |
| @@ -36,6 +37,11 @@ cr.define('ntp', function() { |
| this.onContextMenu_.bind(this), true); |
| document.body.appendChild(this.menu); |
| + // Create the context menu that appears when the user right clicks |
| + // on a device name. |
| + this.deviceContextMenu_ = DeviceContextMenu.getInstance().menu; |
| + document.body.appendChild(this.deviceContextMenu_); |
| + |
| this.promoMessage_ = $('other-sessions-promo-template').cloneNode(true); |
| this.promoMessage_.removeAttribute('id'); // Prevent a duplicate id. |
| @@ -67,9 +73,30 @@ cr.define('ntp', function() { |
| * Handle a context menu event for an object in the menu's DOM subtree. |
| */ |
| onContextMenu_: function(e) { |
| - // Only record the action if it occurred in one of the menu items. |
| - if (findAncestorByClass(e.target, 'footer-menu-item')) |
| + // Only record the action if it occurred in one of the menu items or |
| + // on one of the session headings. |
| + if (findAncestorByClass(e.target, 'footer-menu-item')) { |
| this.recordUmaEvent_(HISTOGRAM_EVENT.LINK_RIGHT_CLICKED); |
| + } else { |
| + var heading = findAncestorByClass(e.target, 'session-heading'); |
| + if (heading) { |
| + this.recordUmaEvent_(HISTOGRAM_EVENT.SESSION_NAME_RIGHT_CLICKED); |
| + |
| + // Let the context menu know which session it was invoked on, |
| + // since they all share the same instance of the menu. |
| + DeviceContextMenu.getInstance().setSessionTag(heading.sessionTag_); |
| + } |
| + } |
| + }, |
| + |
| + /** |
| + * Hides the menu. |
| + * @override |
| + */ |
| + hideMenu: function() { |
| + // Don't hide if the device context menu is currently showing. |
| + if (cr.ui.contextMenuHandler.menu != this.deviceContextMenu_) |
| + MenuButton.prototype.hideMenu.call(this); |
| }, |
| /** |
| @@ -120,11 +147,26 @@ cr.define('ntp', function() { |
| this.menu.appendChild(section); |
| var heading = doc.createElement('h3'); |
| + heading.className = 'session-heading'; |
| heading.textContent = session.name; |
| + heading.sessionTag_ = session.tag; |
| section.appendChild(heading); |
| + var timeSpan = doc.createElement('span'); |
| + timeSpan.className = 'details'; |
| + timeSpan.textContent = session.modifiedTime; |
| + heading.appendChild(timeSpan); |
| + |
| + cr.ui.contextMenuHandler.setContextMenu(heading, |
| + this.deviceContextMenu_); |
| + |
| for (var i = 0; i < session.windows.length; i++) { |
| var window = session.windows[i]; |
| + |
| + // Show a separator between multiple windows in the same session. |
| + if (i > 0) |
| + section.appendChild(doc.createElement('hr')); |
| + |
| for (var j = 0; j < window.tabs.length; j++) { |
| var tab = window.tabs[j]; |
| var a = doc.createElement('a'); |
| @@ -179,6 +221,63 @@ cr.define('ntp', function() { |
| }, |
| }; |
| + /** |
| + * Context menu for device names in the list of sessions. |
| + * This class is designed to be used as a singleton. |
| + * |
| + * @constructor |
| + */ |
| + function DeviceContextMenu() { |
|
Evan Stade
2012/03/30 21:40:58
probably should be called DeviceContextMenuControl
|
| + this.__proto__ = DeviceContextMenu.prototype; |
| + this.initialize(); |
| + } |
| + cr.addSingletonGetter(DeviceContextMenu); |
| + |
| + DeviceContextMenu.prototype = { |
| + |
| + initialize: function() { |
| + var menu = new cr.ui.Menu; |
| + cr.ui.decorate(menu, cr.ui.Menu); |
| + menu.classList.add('device-context-menu'); |
| + menu.classList.add('footer-menu-context-menu'); |
| + this.menu = menu; |
| + this.hideItem_ = this.appendMenuItem_('hideSessionMenuItemText'); |
| + this.hideItem_.addEventListener('activate', this.onHide_.bind(this)); |
| + }, |
| + |
| + /** |
| + * Appends a menu item to |this.menu|. |
| + * @param {String} textId The ID for the localized string that acts as |
| + * the item's label. |
| + */ |
| + appendMenuItem_: function(textId) { |
| + var button = cr.doc.createElement('button'); |
| + this.menu.appendChild(button); |
| + cr.ui.decorate(button, cr.ui.MenuItem); |
| + button.textContent = localStrings.getString(textId); |
| + return button; |
| + }, |
| + |
| + /** |
| + * Handler for the 'hide' menu item. |
| + * @param {Event} e The activation event. |
| + * @private |
| + */ |
| + onHide_: function(e) { |
| + chrome.send('deleteForeignSession', [this.sessionTag_]); |
| + chrome.send('getForeignSessions'); // Refresh the list. |
| + }, |
| + |
| + /** |
| + * Set the session tag which identifies the session that the context menu |
| + * was invoked on. |
| + * @param {String} tag The session tag. |
| + */ |
| + setSessionTag: function(tag) { |
| + this.sessionTag_ = tag; |
| + } |
| + }; |
| + |
| return { |
| OtherSessionsMenuButton: OtherSessionsMenuButton, |
| }; |