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

Unified Diff: chrome/browser/resources/history/other_devices.js

Issue 2830983005: Remove old webui History page on desktop and mobile (Closed)
Patch Set: merge Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/history/other_devices.js
diff --git a/chrome/browser/resources/history/other_devices.js b/chrome/browser/resources/history/other_devices.js
deleted file mode 100644
index 0a10191e0f7c0728249850012f6034644766c930..0000000000000000000000000000000000000000
--- a/chrome/browser/resources/history/other_devices.js
+++ /dev/null
@@ -1,586 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview The section of the history page that shows tabs from sessions
- on other devices.
- */
-
-///////////////////////////////////////////////////////////////////////////////
-// Globals:
-/** @const */ var MAX_NUM_COLUMNS = 3;
-/** @const */ var NB_ENTRIES_FIRST_ROW_COLUMN = 6;
-/** @const */ var NB_ENTRIES_OTHER_ROWS_COLUMN = 0;
-
-// Histogram buckets for UMA tracking of menu usage.
-/** @const */ var HISTOGRAM_EVENT = {
- INITIALIZED: 0,
- SHOW_MENU: 1,
- LINK_CLICKED: 2,
- LINK_RIGHT_CLICKED: 3,
- SESSION_NAME_RIGHT_CLICKED: 4,
- SHOW_SESSION_MENU: 5,
- COLLAPSE_SESSION: 6,
- EXPAND_SESSION: 7,
- OPEN_ALL: 8,
- HAS_FOREIGN_DATA: 9,
- HIDE_FOR_NOW: 10,
- LIMIT: 11 // Should always be the last one.
-};
-
-/**
- * Record an event in the UMA histogram.
- * @param {number} eventId The id of the event to be recorded.
- * @private
- */
-function recordUmaEvent_(eventId) {
- chrome.send('metricsHandler:recordInHistogram',
- ['HistoryPage.OtherDevicesMenu', eventId, HISTOGRAM_EVENT.LIMIT]);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DeviceContextMenuController:
-
-/**
- * Controller for the context menu for device names in the list of sessions.
- * @constructor
- */
-function DeviceContextMenuController() {
- this.__proto__ = DeviceContextMenuController.prototype;
- this.initialize();
-}
-cr.addSingletonGetter(DeviceContextMenuController);
-
-// DeviceContextMenuController, Public: ---------------------------------------
-
-/**
- * Initialize the context menu for device names in the list of sessions.
- */
-DeviceContextMenuController.prototype.initialize = function() {
- var menu = new cr.ui.Menu;
- cr.ui.decorate(menu, cr.ui.Menu);
- this.menu = menu;
- this.collapseItem_ = this.appendMenuItem_('collapseSessionMenuItemText');
- this.collapseItem_.addEventListener('activate',
- this.onCollapseOrExpand_.bind(this));
- this.expandItem_ = this.appendMenuItem_('expandSessionMenuItemText');
- this.expandItem_.addEventListener('activate',
- this.onCollapseOrExpand_.bind(this));
- var openAllItem = this.appendMenuItem_('restoreSessionMenuItemText');
- openAllItem.addEventListener('activate', this.onOpenAll_.bind(this));
- var deleteItem = this.appendMenuItem_('deleteSessionMenuItemText');
- deleteItem.addEventListener('activate', this.onDeleteSession_.bind(this));
-};
-
-/**
- * Set the session data for the session the context menu was invoked on.
- * This should never be called when the menu is visible.
- * @param {Object} session The model object for the session.
- */
-DeviceContextMenuController.prototype.setSession = function(session) {
- this.session_ = session;
- this.updateMenuItems_();
-};
-
-// DeviceContextMenuController, Private: --------------------------------------
-
-/**
- * Appends a menu item to |this.menu|.
- * @param {string} textId The ID for the localized string that acts as
- * the item's label.
- * @return {Element} The button used for a given menu option.
- * @private
- */
-DeviceContextMenuController.prototype.appendMenuItem_ = function(textId) {
- var button = document.createElement('button');
- this.menu.appendChild(button);
- cr.ui.decorate(button, cr.ui.MenuItem);
- button.textContent = loadTimeData.getString(textId);
- return button;
-};
-
-/**
- * Handler for the 'Collapse' and 'Expand' menu items.
- * @param {Event} e The activation event.
- * @private
- */
-DeviceContextMenuController.prototype.onCollapseOrExpand_ = function(e) {
- this.session_.collapsed = !this.session_.collapsed;
- this.updateMenuItems_();
- chrome.send('setForeignSessionCollapsed',
- [this.session_.tag, this.session_.collapsed]);
- chrome.send('getForeignSessions'); // Refresh the list.
-
- var eventId = this.session_.collapsed ?
- HISTOGRAM_EVENT.COLLAPSE_SESSION : HISTOGRAM_EVENT.EXPAND_SESSION;
- recordUmaEvent_(eventId);
-};
-
-/**
- * Handler for the 'Open all' menu item.
- * @param {Event} e The activation event.
- * @private
- */
-DeviceContextMenuController.prototype.onOpenAll_ = function(e) {
- chrome.send('openForeignSession', [this.session_.tag]);
- recordUmaEvent_(HISTOGRAM_EVENT.OPEN_ALL);
-};
-
-/**
- * Handler for the 'Hide for now' menu item.
- * @param {Event} e The activation event.
- * @private
- */
-DeviceContextMenuController.prototype.onDeleteSession_ = function(e) {
- chrome.send('deleteForeignSession', [this.session_.tag]);
- recordUmaEvent_(HISTOGRAM_EVENT.HIDE_FOR_NOW);
-};
-
-/**
- * Set the visibility of the Expand/Collapse menu items based on the state
- * of the session that this menu is currently associated with.
- * @private
- */
-DeviceContextMenuController.prototype.updateMenuItems_ = function() {
- this.collapseItem_.hidden = this.session_.collapsed;
- this.expandItem_.hidden = !this.session_.collapsed;
- this.menu.selectedItem = this.menu.querySelector(':not([hidden])');
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Device:
-
-/**
- * Class to hold all the information about a device entry and generate a DOM
- * node for it.
- * @param {Object} session An object containing the device's session data.
- * @param {DevicesView} view The view object this entry belongs to.
- * @constructor
- */
-function Device(session, view) {
- this.view_ = view;
- this.session_ = session;
- this.searchText_ = view.getSearchText();
-}
-
-// Device, Public: ------------------------------------------------------------
-
-/**
- * Get the DOM node to display this device.
- * @param {int} maxNumTabs The maximum number of tabs to display.
- * @param {int} row The row in which this device is displayed.
- * @return {Object} A DOM node to draw the device.
- */
-Device.prototype.getDOMNode = function(maxNumTabs, row) {
- var deviceDiv = createElementWithClassName('div', 'device');
- this.row_ = row;
- if (!this.session_)
- return deviceDiv;
-
- // Name heading
- var heading = document.createElement('h3');
- var name = heading.appendChild(
- createElementWithClassName('span', 'device-name'));
- name.textContent = this.session_.name;
- heading.sessionData_ = this.session_;
- deviceDiv.appendChild(heading);
-
- // Keep track of the drop down that triggered the menu, so we know
- // which element to apply the command to.
- var session = this.session_;
- function handleDropDownFocus(e) {
- DeviceContextMenuController.getInstance().setSession(session);
- }
- heading.addEventListener('contextmenu', handleDropDownFocus);
-
- var dropDownButton = new cr.ui.ContextMenuButton;
- dropDownButton.tabIndex = 0;
- dropDownButton.classList.add('drop-down');
- dropDownButton.title = loadTimeData.getString('actionMenuDescription');
- dropDownButton.addEventListener('mousedown', function(event) {
- handleDropDownFocus(event);
- // Mousedown handling of cr.ui.MenuButton.handleEvent calls
- // preventDefault, which prevents blur of the focused element. We need to
- // do blur manually.
- document.activeElement.blur();
- });
- dropDownButton.addEventListener('focus', handleDropDownFocus);
- heading.appendChild(dropDownButton);
-
- var timeSpan = createElementWithClassName('div', 'device-timestamp');
- timeSpan.textContent = this.session_.modifiedTime;
- deviceDiv.appendChild(timeSpan);
-
- cr.ui.contextMenuHandler.setContextMenu(
- heading, DeviceContextMenuController.getInstance().menu);
- if (!this.session_.collapsed)
- deviceDiv.appendChild(this.createSessionContents_(maxNumTabs));
-
- return deviceDiv;
-};
-
-/**
- * Marks tabs as hidden or not in our session based on the given searchText.
- * @param {string} searchText The search text used to filter the content.
- */
-Device.prototype.setSearchText = function(searchText) {
- this.searchText_ = searchText.toLowerCase();
- for (var i = 0; i < this.session_.windows.length; i++) {
- var win = this.session_.windows[i];
- var foundMatch = false;
- for (var j = 0; j < win.tabs.length; j++) {
- var tab = win.tabs[j];
- if (tab.title.toLowerCase().indexOf(this.searchText_) != -1) {
- foundMatch = true;
- tab.hidden = false;
- } else {
- tab.hidden = true;
- }
- }
- win.hidden = !foundMatch;
- }
-};
-
-// Device, Private ------------------------------------------------------------
-
-/**
- * Create the DOM tree representing the tabs and windows of this device.
- * @param {int} maxNumTabs The maximum number of tabs to display.
- * @return {Element} A single div containing the list of tabs & windows.
- * @private
- */
-Device.prototype.createSessionContents_ = function(maxNumTabs) {
- var contents = createElementWithClassName('ol', 'device-contents');
-
- var sessionTag = this.session_.tag;
- var numTabsShown = 0;
- var numTabsHidden = 0;
- for (var i = 0; i < this.session_.windows.length; i++) {
- var win = this.session_.windows[i];
- if (win.hidden)
- continue;
-
- // Show a separator between multiple windows in the same session.
- if (i > 0 && numTabsShown < maxNumTabs)
- contents.appendChild(document.createElement('hr'));
-
- for (var j = 0; j < win.tabs.length; j++) {
- var tab = win.tabs[j];
- if (tab.hidden)
- continue;
-
- if (numTabsShown < maxNumTabs) {
- numTabsShown++;
- var a = createElementWithClassName('a', 'device-tab-entry');
- a.href = tab.url;
- a.style.backgroundImage = cr.icon.getFavicon(tab.url);
- this.addHighlightedText_(a, tab.title);
- // Add a tooltip, since it might be ellipsized. The ones that are not
- // necessary will be removed once added to the document, so we can
- // compute sizes.
- a.title = tab.title;
-
- // We need to use this to not lose the ids as we go through other loop
- // turns.
- function makeClickHandler(sessionTag, windowId, tabId) {
- return function(e) {
- if (e.button > 1)
- return; // Ignore buttons other than left and middle.
- recordUmaEvent_(HISTOGRAM_EVENT.LINK_CLICKED);
- chrome.send('openForeignSession', [sessionTag, windowId, tabId,
- e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]);
- e.preventDefault();
- };
- };
- ['click', 'auxclick'].forEach(function(eventName) {
- a.addEventListener(eventName,
- makeClickHandler(sessionTag,
- String(win.sessionId),
- String(tab.sessionId)));
- });
- var wrapper = createElementWithClassName('div', 'device-tab-wrapper');
- wrapper.appendChild(a);
- contents.appendChild(wrapper);
- } else {
- numTabsHidden++;
- }
- }
- }
-
- if (numTabsHidden > 0) {
- var moreLink = document.createElement('a', 'action-link');
- moreLink.classList.add('device-show-more-tabs');
- moreLink.addEventListener('click', this.view_.increaseRowHeight.bind(
- this.view_, this.row_, numTabsHidden));
- // TODO(jshin): Use plural message formatter when available in JS.
- moreLink.textContent = loadTimeData.getStringF('xMore',
- numTabsHidden.toLocaleString());
- var moreWrapper = createElementWithClassName('div', 'more-wrapper');
- moreWrapper.appendChild(moreLink);
- contents.appendChild(moreWrapper);
- }
-
- return contents;
-};
-
-/**
- * Add child text nodes to a node such that occurrences of this.searchText_ are
- * highlighted.
- * @param {Node} node The node under which new text nodes will be made as
- * children.
- * @param {string} content Text to be added beneath |node| as one or more
- * text nodes.
- * @private
- */
-Device.prototype.addHighlightedText_ = function(node, content) {
- var endOfPreviousMatch = 0;
- if (this.searchText_) {
- var lowerContent = content.toLowerCase();
- var searchTextLenght = this.searchText_.length;
- var newMatch = lowerContent.indexOf(this.searchText_, 0);
- while (newMatch != -1) {
- if (newMatch > endOfPreviousMatch) {
- node.appendChild(document.createTextNode(
- content.slice(endOfPreviousMatch, newMatch)));
- }
- endOfPreviousMatch = newMatch + searchTextLenght;
- // Mark the highlighted text in bold.
- var b = document.createElement('b');
- b.textContent = content.substring(newMatch, endOfPreviousMatch);
- node.appendChild(b);
- newMatch = lowerContent.indexOf(this.searchText_, endOfPreviousMatch);
- }
- }
- if (endOfPreviousMatch < content.length) {
- node.appendChild(document.createTextNode(
- content.slice(endOfPreviousMatch)));
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// DevicesView:
-
-/**
- * Functions and state for populating the page with HTML.
- * @constructor
- */
-function DevicesView() {
- this.devices_ = []; // List of individual devices.
- this.resultDiv_ = $('other-devices');
- this.searchText_ = '';
- this.rowHeights_ = [NB_ENTRIES_FIRST_ROW_COLUMN];
- this.focusGrids_ = [];
- this.updateSignInState(loadTimeData.getBoolean('isUserSignedIn'));
- this.hasSeenForeignData_ = false;
- recordUmaEvent_(HISTOGRAM_EVENT.INITIALIZED);
-}
-
-// DevicesView, public: -------------------------------------------------------
-
-/**
- * Updates our sign in state by clearing the view is not signed in or sending
- * a request to get the data to display otherwise.
- * @param {boolean} signedIn Whether the user is signed in or not.
- */
-DevicesView.prototype.updateSignInState = function(signedIn) {
- if (signedIn)
- chrome.send('getForeignSessions');
- else
- this.clearDOM();
-};
-
-/**
- * Resets the view sessions.
- * @param {Object} sessionList The sessions to add.
- */
-DevicesView.prototype.setSessionList = function(sessionList) {
- this.devices_ = [];
- for (var i = 0; i < sessionList.length; i++)
- this.devices_.push(new Device(sessionList[i], this));
- this.displayResults_();
-
- // This metric should only be emitted if we see foreign data, and it should
- // only be emitted once per page refresh. Flip flag to remember because this
- // method is called upon any update.
- if (!this.hasSeenForeignData_ && sessionList.length > 0) {
- this.hasSeenForeignData_ = true;
- recordUmaEvent_(HISTOGRAM_EVENT.HAS_FOREIGN_DATA);
- }
-};
-
-
-/**
- * Sets the current search text.
- * @param {string} searchText The text to search.
- */
-DevicesView.prototype.setSearchText = function(searchText) {
- if (this.searchText_ != searchText) {
- this.searchText_ = searchText;
- for (var i = 0; i < this.devices_.length; i++)
- this.devices_[i].setSearchText(searchText);
- this.displayResults_();
- }
-};
-
-/**
- * @return {string} The current search text.
- */
-DevicesView.prototype.getSearchText = function() {
- return this.searchText_;
-};
-
-/**
- * Clears the DOM content of the view.
- */
-DevicesView.prototype.clearDOM = function() {
- while (this.resultDiv_.hasChildNodes()) {
- this.resultDiv_.removeChild(this.resultDiv_.lastChild);
- }
-};
-
-/**
- * Increase the height of a row by the given amount.
- * @param {int} row The row number.
- * @param {int} height The extra height to add to the givent row.
- */
-DevicesView.prototype.increaseRowHeight = function(row, height) {
- for (var i = this.rowHeights_.length; i <= row; i++)
- this.rowHeights_.push(NB_ENTRIES_OTHER_ROWS_COLUMN);
- this.rowHeights_[row] += height;
- this.displayResults_();
-};
-
-// DevicesView, Private -------------------------------------------------------
-
-/**
- * @param {!Element} root
- * @param {?Node} boundary
- * @constructor
- * @extends {cr.ui.FocusRow}
- */
-function DevicesViewFocusRow(root, boundary) {
- cr.ui.FocusRow.call(this, root, boundary);
- assert(this.addItem('menu-button', 'button.drop-down') ||
- this.addItem('device-tab', '.device-tab-entry') ||
- this.addItem('more-tabs', '.device-show-more-tabs'));
-}
-
-DevicesViewFocusRow.prototype = {__proto__: cr.ui.FocusRow.prototype};
-
-/**
- * Update the page with results.
- * @private
- */
-DevicesView.prototype.displayResults_ = function() {
- this.clearDOM();
- var resultsFragment = document.createDocumentFragment();
- if (this.devices_.length == 0)
- return;
-
- // We'll increase to 0 as we create the first row.
- var rowIndex = -1;
- // We need to access the last row and device when we get out of the loop.
- var currentRowElement;
- // This is only set when changing rows, yet used on all device columns.
- var maxNumTabs;
- for (var i = 0; i < this.devices_.length; i++) {
- var device = this.devices_[i];
- // Should we start a new row?
- if (i % MAX_NUM_COLUMNS == 0) {
- if (currentRowElement)
- resultsFragment.appendChild(currentRowElement);
- currentRowElement = createElementWithClassName('div', 'device-row');
- rowIndex++;
- if (rowIndex < this.rowHeights_.length)
- maxNumTabs = this.rowHeights_[rowIndex];
- else
- maxNumTabs = 0;
- }
-
- currentRowElement.appendChild(device.getDOMNode(maxNumTabs, rowIndex));
- }
- if (currentRowElement)
- resultsFragment.appendChild(currentRowElement);
-
- this.resultDiv_.appendChild(resultsFragment);
- // Remove the tootltip on all lines that don't need it. It's easier to
- // remove them here, after adding them all above, since we have the data
- // handy above, but we don't have the width yet. Whereas here, we have the
- // width, and the nodeValue could contain sub nodes for highlighting, which
- // makes it harder to extract the text data here.
- tabs = document.getElementsByClassName('device-tab-entry');
- for (var i = 0; i < tabs.length; i++) {
- if (tabs[i].scrollWidth <= tabs[i].clientWidth)
- tabs[i].title = '';
- }
-
- this.resultDiv_.appendChild(
- createElementWithClassName('div', 'other-devices-bottom'));
-
- this.focusGrids_.forEach(function(grid) { grid.destroy(); });
- this.focusGrids_.length = 0;
-
- var devices = this.resultDiv_.querySelectorAll('.device-contents');
- for (var i = 0; i < devices.length; ++i) {
- var rows = devices[i].querySelectorAll(
- 'h3, .device-tab-wrapper, .more-wrapper');
- if (!rows.length)
- continue;
-
- var grid = new cr.ui.FocusGrid();
- for (var j = 0; j < rows.length; ++j) {
- grid.addRow(new DevicesViewFocusRow(rows[j], devices[i]));
- }
- grid.ensureRowActive();
- this.focusGrids_.push(grid);
- }
-};
-
-/**
- * Sets the menu model data. An empty list means that either there are no
- * foreign sessions, or tab sync is disabled for this profile.
- *
- * @param {Array} sessionList Array of objects describing the sessions
- * from other devices.
- */
-function setForeignSessions(sessionList) {
- devicesView.setSessionList(sessionList);
-}
-
-/**
- * Called when initialized or the user's signed in state changes,
- * @param {boolean} isUserSignedIn Is the user currently signed in?
- */
-function updateSignInState(isUserSignedIn) {
- if (devicesView)
- devicesView.updateSignInState(isUserSignedIn);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Document Functions:
-/**
- * Window onload handler, sets up the other devices view.
- */
-function load() {
- if (!loadTimeData.getBoolean('isInstantExtendedApiEnabled'))
- return;
-
- devicesView = new DevicesView();
-
- // Create the context menu that appears when the user right clicks
- // on a device name or hit click on the button besides the device name
- document.body.appendChild(DeviceContextMenuController.getInstance().menu);
-
- var doSearch = function(e) {
- devicesView.setSearchText($('search-field').value);
- };
- $('search-field').addEventListener('search', doSearch);
- $('search-button').addEventListener('click', doSearch);
-
- chrome.send('otherDevicesInitialized');
-}
-
-// Add handlers to HTML elements.
-document.addEventListener('DOMContentLoaded', load);
« no previous file with comments | « chrome/browser/resources/history/other_devices.css ('k') | chrome/browser/resources/md_history/compiled_resources2.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698