Index: chrome/browser/resources/task_manager/main.js |
diff --git a/chrome/browser/resources/task_manager/main.js b/chrome/browser/resources/task_manager/main.js |
deleted file mode 100644 |
index 6a6a0462b6460493e3ed7b359ba32a914c246c48..0000000000000000000000000000000000000000 |
--- a/chrome/browser/resources/task_manager/main.js |
+++ /dev/null |
@@ -1,696 +0,0 @@ |
-// Copyright (c) 2012 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. |
- |
-/** @constructor */ |
-function TaskManager() { } |
- |
-cr.addSingletonGetter(TaskManager); |
- |
-TaskManager.prototype = { |
- /** |
- * Handle window close. |
- * @this |
- */ |
- onClose: function() { |
- if (!this.disabled_) { |
- this.disabled_ = true; |
- commands.disableTaskManager(); |
- } |
- }, |
- |
- /** |
- * Handles selection changes. |
- * This is also called when data of tasks are refreshed, even if selection |
- * has not been changed. |
- * @this |
- */ |
- onSelectionChange: function() { |
- var sm = this.selectionModel_; |
- var dm = this.dataModel_; |
- var selectedIndexes = sm.selectedIndexes; |
- var isEndProcessEnabled = true; |
- if (selectedIndexes.length == 0) |
- isEndProcessEnabled = false; |
- for (var i = 0; i < selectedIndexes.length; i++) { |
- var index = selectedIndexes[i]; |
- var task = dm.item(index); |
- if (task['type'] == 'BROWSER') |
- isEndProcessEnabled = false; |
- } |
- if (this.isEndProcessEnabled_ != isEndProcessEnabled) { |
- if (isEndProcessEnabled) |
- $('kill-process').removeAttribute('disabled'); |
- else |
- $('kill-process').setAttribute('disabled', 'true'); |
- |
- this.isEndProcessEnabled_ = isEndProcessEnabled; |
- } |
- }, |
- |
- /** |
- * Closes taskmanager dialog. |
- * After this function is called, onClose() will be called. |
- * @this |
- */ |
- close: function() { |
- window.close(); |
- }, |
- |
- /** |
- * Sends commands to kill selected processes. |
- * @this |
- */ |
- killSelectedProcesses: function() { |
- var selectedIndexes = this.selectionModel_.selectedIndexes; |
- var dm = this.dataModel_; |
- var uniqueIds = []; |
- for (var i = 0; i < selectedIndexes.length; i++) { |
- var index = selectedIndexes[i]; |
- var task = dm.item(index); |
- uniqueIds.push(task['uniqueId'][0]); |
- } |
- |
- commands.killSelectedProcesses(uniqueIds); |
- }, |
- |
- /** |
- * Initializes taskmanager. |
- * @this |
- */ |
- initialize: function(dialogDom, opt) { |
- if (!dialogDom) { |
- console.log('ERROR: dialogDom is not defined.'); |
- return; |
- } |
- |
- measureTime.startInterval('Load.DOM'); |
- |
- this.opt_ = opt; |
- |
- this.initialized_ = true; |
- |
- this.elementsCache_ = {}; |
- this.dialogDom_ = dialogDom; |
- this.document_ = dialogDom.ownerDocument; |
- |
- this.localized_column_ = []; |
- for (var i = 0; i < DEFAULT_COLUMNS.length; i++) { |
- var columnLabelId = DEFAULT_COLUMNS[i][1]; |
- this.localized_column_[i] = loadTimeData.getString(columnLabelId); |
- } |
- |
- this.initElements_(); |
- this.initColumnModel_(); |
- this.selectionModel_ = new cr.ui.ListSelectionModel(); |
- this.dataModel_ = new cr.ui.ArrayDataModel([]); |
- |
- this.selectionModel_.addEventListener('change', |
- this.onSelectionChange.bind(this)); |
- |
- // Initializes compare functions for column sort. |
- var dm = this.dataModel_; |
- // List of columns to sort by its numerical value as opposed to the |
- // formatted value, e.g., 20480 vs. 20KB. |
- var COLUMNS_SORTED_BY_VALUE = [ |
- 'cpuUsage', 'physicalMemory', 'sharedMemory', 'privateMemory', |
- 'networkUsage', 'webCoreImageCacheSize', 'webCoreScriptsCacheSize', |
- 'webCoreCSSCacheSize', 'fps', 'videoMemory', 'sqliteMemoryUsed', |
- 'goatsTeleported', 'v8MemoryAllocatedSize']; |
- |
- for (var i = 0; i < DEFAULT_COLUMNS.length; i++) { |
- var columnId = DEFAULT_COLUMNS[i][0]; |
- var compareFunc = (function() { |
- var columnIdToSort = columnId; |
- if (COLUMNS_SORTED_BY_VALUE.indexOf(columnId) != -1) |
- columnIdToSort += 'Value'; |
- |
- return function(a, b) { |
- var aValues = a[columnIdToSort]; |
- var bValues = b[columnIdToSort]; |
- var aValue = aValues && aValues[0] || 0; |
- var bvalue = bValues && bValues[0] || 0; |
- return dm.defaultValuesCompareFunction(aValue, bvalue); |
- }; |
- })(); |
- dm.setCompareFunction(columnId, compareFunc); |
- } |
- |
- if (isColumnEnabled(DEFAULT_SORT_COLUMN)) |
- dm.sort(DEFAULT_SORT_COLUMN, DEFAULT_SORT_DIRECTION); |
- |
- this.initTable_(); |
- |
- commands.enableTaskManager(); |
- |
- // Populate the static localized strings. |
- i18nTemplate.process(this.document_, loadTimeData); |
- |
- measureTime.recordInterval('Load.DOM'); |
- measureTime.recordInterval('Load.Total'); |
- |
- loadDelayedIncludes(this); |
- }, |
- |
- /** |
- * Initializes the visibilities and handlers of the elements. |
- * This method is called by initialize(). |
- * @private |
- * @this |
- */ |
- initElements_: function() { |
- // <if expr="pp_ifdef('chromeos')"> |
- // The 'close-window' element exists only on ChromeOS. |
- // This <if ... /if> section is removed while flattening HTML if chrome is |
- // built as Desktop Chrome. |
- if (!this.opt_['isShowCloseButton']) |
- $('close-window').style.display = 'none'; |
- $('close-window').addEventListener('click', this.close.bind(this)); |
- // </if> |
- |
- $('kill-process').addEventListener('click', |
- this.killSelectedProcesses.bind(this)); |
- $('about-memory-link').addEventListener('click', commands.openAboutMemory); |
- }, |
- |
- /** |
- * Additional initialization of taskmanager. This function is called when |
- * the loading of delayed scripts finished. |
- * @this |
- */ |
- delayedInitialize: function() { |
- this.initColumnMenu_(); |
- this.initTableMenu_(); |
- |
- var dm = this.dataModel_; |
- for (var i = 0; i < dm.length; i++) { |
- var processId = dm.item(i)['processId'][0]; |
- for (var j = 0; j < DEFAULT_COLUMNS.length; j++) { |
- var columnId = DEFAULT_COLUMNS[j][0]; |
- |
- var row = dm.item(i)[columnId]; |
- if (!row) |
- continue; |
- |
- for (var k = 0; k < row.length; k++) { |
- var labelId = 'detail-' + columnId + '-pid' + processId + '-' + k; |
- var label = $(labelId); |
- |
- // Initialize a context-menu, if the label exists and its context- |
- // menu is not initialized yet. |
- if (label && !label.contextMenu) |
- cr.ui.contextMenuHandler.setContextMenu(label, |
- this.tableContextMenu_); |
- } |
- } |
- } |
- |
- this.isFinishedInitDelayed_ = true; |
- var t = this.table_; |
- t.redraw(); |
- addEventListener('resize', t.redraw.bind(t)); |
- }, |
- |
- initColumnModel_: function() { |
- var tableColumns = new Array(); |
- for (var i = 0; i < DEFAULT_COLUMNS.length; i++) { |
- var column = DEFAULT_COLUMNS[i]; |
- var columnId = column[0]; |
- if (!isColumnEnabled(columnId)) |
- continue; |
- |
- tableColumns.push(new cr.ui.table.TableColumn(columnId, |
- this.localized_column_[i], |
- column[2])); |
- } |
- |
- for (var i = 0; i < tableColumns.length; i++) { |
- tableColumns[i].renderFunction = this.renderColumn_.bind(this); |
- } |
- |
- this.columnModel_ = new cr.ui.table.TableColumnModel(tableColumns); |
- }, |
- |
- initColumnMenu_: function() { |
- this.column_menu_commands_ = []; |
- |
- this.commandsElement_ = this.document_.createElement('commands'); |
- this.document_.body.appendChild(this.commandsElement_); |
- |
- this.columnSelectContextMenu_ = this.document_.createElement('menu'); |
- for (var i = 0; i < DEFAULT_COLUMNS.length; i++) { |
- var column = DEFAULT_COLUMNS[i]; |
- |
- // Creates command element to receive event. |
- var command = this.document_.createElement('command'); |
- command.id = COMMAND_CONTEXTMENU_COLUMN_PREFIX + '-' + column[0]; |
- cr.ui.Command.decorate(command); |
- this.column_menu_commands_[command.id] = command; |
- this.commandsElement_.appendChild(command); |
- |
- // Creates menuitem element. |
- var item = this.document_.createElement('menuitem'); |
- item.command = command; |
- command.menuitem = item; |
- item.textContent = this.localized_column_[i]; |
- if (isColumnEnabled(column[0])) |
- item.setAttributeNode(this.document_.createAttribute('checked')); |
- this.columnSelectContextMenu_.appendChild(item); |
- } |
- |
- this.document_.body.appendChild(this.columnSelectContextMenu_); |
- cr.ui.Menu.decorate(this.columnSelectContextMenu_); |
- |
- cr.ui.contextMenuHandler.setContextMenu(this.table_.header, |
- this.columnSelectContextMenu_); |
- cr.ui.contextMenuHandler.setContextMenu(this.table_.list, |
- this.columnSelectContextMenu_); |
- |
- this.document_.addEventListener('command', this.onCommand_.bind(this)); |
- this.document_.addEventListener('canExecute', |
- this.onCommandCanExecute_.bind(this)); |
- }, |
- |
- initTableMenu_: function() { |
- this.table_menu_commands_ = []; |
- this.tableContextMenu_ = this.document_.createElement('menu'); |
- |
- var addMenuItem = function(tm, commandId, string_id) { |
- // Creates command element to receive event. |
- var command = tm.document_.createElement('command'); |
- command.id = COMMAND_CONTEXTMENU_TABLE_PREFIX + '-' + commandId; |
- cr.ui.Command.decorate(command); |
- tm.table_menu_commands_[command.id] = command; |
- tm.commandsElement_.appendChild(command); |
- |
- // Creates menuitem element. |
- var item = tm.document_.createElement('menuitem'); |
- item.command = command; |
- command.menuitem = item; |
- item.textContent = loadTimeData.getString(string_id); |
- tm.tableContextMenu_.appendChild(item); |
- }; |
- |
- addMenuItem(this, 'inspect', 'inspect'); |
- addMenuItem(this, 'activate', 'activate'); |
- |
- this.document_.body.appendChild(this.tableContextMenu_); |
- cr.ui.Menu.decorate(this.tableContextMenu_); |
- }, |
- |
- initTable_: function() { |
- if (!this.dataModel_ || !this.selectionModel_ || !this.columnModel_) { |
- console.log('ERROR: some models are not defined.'); |
- return; |
- } |
- |
- this.table_ = this.dialogDom_.querySelector('.detail-table'); |
- cr.ui.Table.decorate(this.table_); |
- |
- this.table_.dataModel = this.dataModel_; |
- this.table_.selectionModel = this.selectionModel_; |
- this.table_.columnModel = this.columnModel_; |
- |
- // Expands height of row when a process has some tasks. |
- this.table_.fixedHeight = false; |
- |
- this.table_.list.addEventListener('contextmenu', |
- this.onTableContextMenuOpened_.bind(this), |
- true); |
- |
- // Sets custom row render function. |
- this.table_.setRenderFunction(this.getRow_.bind(this)); |
- }, |
- |
- /** |
- * Returns a list item element of the list. This method trys to reuse the |
- * cached element, or creates a new element. |
- * @return {cr.ui.ListItem} list item element which contains the given data. |
- * @private |
- * @this |
- */ |
- getRow_: function(data, table) { |
- // Trys to reuse the cached row; |
- var listItemElement = this.renderRowFromCache_(data, table); |
- if (listItemElement) |
- return listItemElement; |
- |
- // Initializes the cache. |
- var pid = data['processId'][0]; |
- this.elementsCache_[pid] = { |
- listItem: null, |
- cell: [], |
- icon: [], |
- columns: {} |
- }; |
- |
- // Create new row. |
- return this.renderRow_(data, table); |
- }, |
- |
- /** |
- * Returns a list item element with re-using the previous cached element, or |
- * returns null if failed. |
- * @return {cr.ui.ListItem} cached un-used element to be reused. |
- * @private |
- * @this |
- */ |
- renderRowFromCache_: function(data, table) { |
- var pid = data['processId'][0]; |
- |
- // Checks whether the cache exists or not. |
- var cache = this.elementsCache_[pid]; |
- if (!cache) |
- return null; |
- |
- var listItemElement = cache.listItem; |
- var cm = table.columnModel; |
- // Checks whether the number of columns has been changed or not. |
- if (cache.cachedColumnSize != cm.size) |
- return null; |
- // Checks whether the number of childlen tasks has been changed or not. |
- if (cache.cachedChildSize != data['uniqueId'].length) |
- return null; |
- |
- // Updates informations of the task if necessary. |
- for (var i = 0; i < cm.size; i++) { |
- var columnId = cm.getId(i); |
- var columnData = data[columnId]; |
- var oldColumnData = listItemElement.data[columnId]; |
- var columnElements = cache.columns[columnId]; |
- |
- if (!columnData || !oldColumnData || !columnElements) |
- return null; |
- |
- // Sets new width of the cell. |
- var cellElement = cache.cell[i]; |
- cellElement.style.width = cm.getWidth(i) + '%'; |
- |
- for (var j = 0; j < columnData.length; j++) { |
- // Sets the new text, if the text has been changed. |
- if (oldColumnData[j] != columnData[j]) { |
- var textElement = columnElements[j]; |
- textElement.textContent = columnData[j]; |
- } |
- } |
- } |
- |
- // Updates icon of the task if necessary. |
- var oldIcons = listItemElement.data['icon']; |
- var newIcons = data['icon']; |
- if (oldIcons && newIcons) { |
- for (var j = 0; j < columnData.length; j++) { |
- var oldIcon = oldIcons[j]; |
- var newIcon = newIcons[j]; |
- if (oldIcon != newIcon) { |
- var iconElement = cache.icon[j]; |
- iconElement.src = newIcon; |
- } |
- } |
- } |
- listItemElement.data = data; |
- |
- // Removes 'selected' and 'lead' attributes. |
- listItemElement.removeAttribute('selected'); |
- listItemElement.removeAttribute('lead'); |
- |
- return listItemElement; |
- }, |
- |
- /** |
- * Create a new list item element. |
- * @return {cr.ui.ListItem} created new list item element. |
- * @private |
- * @this |
- */ |
- renderRow_: function(data, table) { |
- var pid = data['processId'][0]; |
- var cm = table.columnModel; |
- var listItem = new cr.ui.ListItem({label: ''}); |
- |
- listItem.className = 'table-row'; |
- |
- for (var i = 0; i < cm.size; i++) { |
- var cell = document.createElement('div'); |
- cell.style.width = cm.getWidth(i) + '%'; |
- cell.className = 'table-row-cell'; |
- cell.id = 'column-' + pid + '-' + cm.getId(i); |
- cell.appendChild( |
- cm.getRenderFunction(i).call(null, data, cm.getId(i), table)); |
- |
- listItem.appendChild(cell); |
- |
- // Stores the cell element to the dictionary. |
- this.elementsCache_[pid].cell[i] = cell; |
- } |
- |
- // Specifies the height of the row. The height of each row is |
- // 'num_of_tasks * HEIGHT_OF_TASK' px. |
- listItem.style.height = (data['uniqueId'].length * HEIGHT_OF_TASK) + 'px'; |
- |
- listItem.data = data; |
- |
- // Stores the list item element, the number of columns and the number of |
- // childlen. |
- this.elementsCache_[pid].listItem = listItem; |
- this.elementsCache_[pid].cachedColumnSize = cm.size; |
- this.elementsCache_[pid].cachedChildSize = data['uniqueId'].length; |
- |
- return listItem; |
- }, |
- |
- /** |
- * Create a new element of the cell. |
- * @return {HTMLDIVElement} created cell |
- * @private |
- * @this |
- */ |
- renderColumn_: function(entry, columnId, table) { |
- var container = this.document_.createElement('div'); |
- container.className = 'detail-container-' + columnId; |
- var pid = entry['processId'][0]; |
- |
- var cache = []; |
- var cacheIcon = []; |
- |
- if (entry && entry[columnId]) { |
- container.id = 'detail-container-' + columnId + '-pid' + entry.processId; |
- |
- for (var i = 0; i < entry[columnId].length; i++) { |
- var label = document.createElement('div'); |
- if (columnId == 'title') { |
- // Creates a page title element with icon. |
- var image = this.document_.createElement('img'); |
- image.className = 'detail-title-image'; |
- image.src = entry['icon'][i]; |
- image.id = 'detail-title-icon-pid' + pid + '-' + i; |
- label.appendChild(image); |
- var text = this.document_.createElement('div'); |
- text.className = 'detail-title-text'; |
- text.id = 'detail-title-text-pid' + pid + '-' + i; |
- text.textContent = entry['title'][i]; |
- label.appendChild(text); |
- |
- // Chech if the delayed scripts (included in includes.js) have been |
- // loaded or not. If the delayed scripts ware not loaded yet, a |
- // context menu could not be initialized. In such case, it will be |
- // initialized at delayedInitialize() just after loading of delayed |
- // scripts instead of here. |
- if (this.isFinishedInitDelayed_) |
- cr.ui.contextMenuHandler.setContextMenu(label, |
- this.tableContextMenu_); |
- |
- label.addEventListener('dblclick', (function(uniqueId) { |
- commands.activatePage(uniqueId); |
- }).bind(this, entry['uniqueId'][i])); |
- |
- label.data = entry; |
- label.index_in_group = i; |
- |
- cache[i] = text; |
- cacheIcon[i] = image; |
- } else { |
- label.textContent = entry[columnId][i]; |
- cache[i] = label; |
- } |
- label.id = 'detail-' + columnId + '-pid' + pid + '-' + i; |
- label.className = 'detail-' + columnId + ' pid' + pid; |
- container.appendChild(label); |
- } |
- |
- this.elementsCache_[pid].columns[columnId] = cache; |
- if (columnId == 'title') |
- this.elementsCache_[pid].icon = cacheIcon; |
- } |
- return container; |
- }, |
- |
- /** |
- * Updates the task list with the supplied task. |
- * @private |
- * @this |
- */ |
- processTaskChange: function(task) { |
- var dm = this.dataModel_; |
- var sm = this.selectionModel_; |
- if (!dm || !sm) return; |
- |
- this.table_.list.startBatchUpdates(); |
- sm.beginChange(); |
- |
- var type = task.type; |
- var start = task.start; |
- var length = task.length; |
- var tasks = task.tasks; |
- |
- // We have to store the selected pids and restore them after |
- // splice(), because it might replace some items but the replaced |
- // items would lose the selection. |
- var oldSelectedIndexes = sm.selectedIndexes; |
- |
- // Create map of selected PIDs. |
- var selectedPids = {}; |
- for (var i = 0; i < oldSelectedIndexes.length; i++) { |
- var item = dm.item(oldSelectedIndexes[i]); |
- if (item) selectedPids[item['processId'][0]] = true; |
- } |
- |
- var args = tasks.slice(); |
- args.unshift(start, dm.length); |
- dm.splice.apply(dm, args); |
- |
- // Create new array of selected indexes from map of old PIDs. |
- var newSelectedIndexes = []; |
- for (var i = 0; i < dm.length; i++) { |
- if (selectedPids[dm.item(i)['processId'][0]]) |
- newSelectedIndexes.push(i); |
- } |
- |
- sm.selectedIndexes = newSelectedIndexes; |
- |
- var pids = []; |
- for (var i = 0; i < dm.length; i++) { |
- pids.push(dm.item(i)['processId'][0]); |
- } |
- |
- // Sweeps unused caches, which elements no longer exist on the list. |
- for (var pid in this.elementsCache_) { |
- if (pids.indexOf(pid) == -1) |
- delete this.elementsCache_[pid]; |
- } |
- |
- sm.endChange(); |
- this.table_.list.endBatchUpdates(); |
- }, |
- |
- /** |
- * Respond to a command being executed. |
- * @this |
- */ |
- onCommand_: function(event) { |
- var command = event.command; |
- var commandId = command.id.split('-', 2); |
- |
- var mainCommand = commandId[0]; |
- var subCommand = commandId[1]; |
- |
- if (mainCommand == COMMAND_CONTEXTMENU_COLUMN_PREFIX) { |
- this.onColumnContextMenu_(subCommand, command); |
- } else if (mainCommand == COMMAND_CONTEXTMENU_TABLE_PREFIX) { |
- var targetUniqueId = this.currentContextMenuTarget_; |
- |
- if (!targetUniqueId) |
- return; |
- |
- if (subCommand == 'inspect') |
- commands.inspect(targetUniqueId); |
- else if (subCommand == 'activate') |
- commands.activatePage(targetUniqueId); |
- |
- this.currentContextMenuTarget_ = undefined; |
- } |
- }, |
- |
- onCommandCanExecute_: function(event) { |
- event.canExecute = true; |
- }, |
- |
- /** |
- * Store resourceIndex of target resource of context menu, because resource |
- * will be replaced when it is refreshed. |
- * @this |
- */ |
- onTableContextMenuOpened_: function(e) { |
- if (!this.isFinishedInitDelayed_) |
- return; |
- |
- var mc = this.table_menu_commands_; |
- var inspectMenuitem = |
- mc[COMMAND_CONTEXTMENU_TABLE_PREFIX + '-inspect'].menuitem; |
- var activateMenuitem = |
- mc[COMMAND_CONTEXTMENU_TABLE_PREFIX + '-activate'].menuitem; |
- |
- // Disabled by default. |
- inspectMenuitem.disabled = true; |
- activateMenuitem.disabled = true; |
- |
- var target = e.target; |
- for (;; target = target.parentNode) { |
- if (!target) return; |
- var classes = target.classList; |
- if (classes && |
- Array.prototype.indexOf.call(classes, 'detail-title') != -1) break; |
- } |
- |
- var indexInGroup = target.index_in_group; |
- |
- // Sets the uniqueId for current target page under the mouse corsor. |
- this.currentContextMenuTarget_ = target.data['uniqueId'][indexInGroup]; |
- |
- // Enables if the page can be inspected. |
- if (target.data['canInspect'][indexInGroup]) |
- inspectMenuitem.disabled = false; |
- |
- // Enables if the page can be activated. |
- if (target.data['canActivate'][indexInGroup]) |
- activateMenuitem.disabled = false; |
- }, |
- |
- onColumnContextMenu_: function(columnId, command) { |
- var menuitem = command.menuitem; |
- var checkedItemCount = 0; |
- var checked = isColumnEnabled(columnId); |
- |
- // Leaves a item visible when user tries making invisible but it is the |
- // last one. |
- var enabledColumns = getEnabledColumns(); |
- for (var id in enabledColumns) { |
- if (enabledColumns[id]) |
- checkedItemCount++; |
- } |
- if (checkedItemCount == 1 && checked) |
- return; |
- |
- // Toggles the visibility of the column. |
- var newChecked = !checked; |
- menuitem.checked = newChecked; |
- setColumnEnabled(columnId, newChecked); |
- |
- this.initColumnModel_(); |
- this.table_.columnModel = this.columnModel_; |
- this.table_.redraw(); |
- }, |
-}; |
- |
-// |taskmanager| has been declared in preload.js. |
-taskmanager = TaskManager.getInstance(); |
- |
-function init() { |
- var params = parseQueryParams(window.location); |
- var opt = {}; |
- opt['isShowCloseButton'] = params.showclose; |
- taskmanager.initialize(document.body, opt); |
-} |
- |
-document.addEventListener('DOMContentLoaded', init); |
-document.addEventListener('Close', taskmanager.onClose.bind(taskmanager)); |