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..5e2d62efff46d686c68b6dbb1b9fb42adbf08b3f 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_ = DeviceContextMenuController.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,31 @@ 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. |
+ DeviceContextMenuController.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 +148,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 +222,63 @@ cr.define('ntp', function() { |
}, |
}; |
+ /** |
+ * Controller for the context menu for device names in the list of sessions. |
+ * This class is designed to be used as a singleton. |
+ * |
+ * @constructor |
+ */ |
+ function DeviceContextMenuController() { |
+ this.__proto__ = DeviceContextMenuController.prototype; |
+ this.initialize(); |
+ } |
+ cr.addSingletonGetter(DeviceContextMenuController); |
+ |
+ DeviceContextMenuController.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, |
}; |