| Index: chrome/browser/resources/file_manager/js/volume_list.js
|
| diff --git a/chrome/browser/resources/file_manager/js/volume_list.js b/chrome/browser/resources/file_manager/js/volume_list.js
|
| deleted file mode 100644
|
| index 5bdb7b4214a4087c9480d56a9cab2a79cd71d9ec..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/resources/file_manager/js/volume_list.js
|
| +++ /dev/null
|
| @@ -1,432 +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.
|
| -
|
| -'use strict';
|
| -
|
| -/**
|
| - * A volume list model. This model combines the 2 lists.
|
| - * @param {cr.ui.ArrayDataModel} volumesList The first list of the model.
|
| - * @param {cr.ui.ArrayDataModel} pinnedList The second list of the model.
|
| - * @constructor
|
| - * @extends {cr.EventTarget}
|
| - */
|
| -function VolumeListModel(volumesList, pinnedList) {
|
| - this.volumesList_ = volumesList;
|
| - this.pinnedList_ = pinnedList;
|
| -
|
| - // Generates a combined 'permuted' event from an event of either list.
|
| - var permutedHandler = function(listNum, e) {
|
| - var permutedEvent = new Event('permuted');
|
| - var newPermutation = [];
|
| - var newLength;
|
| - if (listNum == 1) {
|
| - newLength = e.newLength + this.pinnedList_.length;
|
| - for (var i = 0; i < e.permutation.length; i++) {
|
| - newPermutation[i] = e.permutation[i];
|
| - }
|
| - for (var i = 0; i < this.pinnedList_.length; i++) {
|
| - newPermutation[i + e.permutation.length] = i + e.newLength;
|
| - }
|
| - } else {
|
| - var volumesLen = this.volumesList_.length;
|
| - newLength = e.newLength + volumesLen;
|
| - for (var i = 0; i < volumesLen; i++) {
|
| - newPermutation[i] = i;
|
| - }
|
| - for (var i = 0; i < e.permutation.length; i++) {
|
| - newPermutation[i + volumesLen] =
|
| - (e.permutation[i] !== -1) ? (e.permutation[i] + volumesLen) : -1;
|
| - }
|
| - }
|
| -
|
| - permutedEvent.newLength = newLength;
|
| - permutedEvent.permutation = newPermutation;
|
| - this.dispatchEvent(permutedEvent);
|
| - };
|
| - this.volumesList_.addEventListener('permuted', permutedHandler.bind(this, 1));
|
| - this.pinnedList_.addEventListener('permuted', permutedHandler.bind(this, 2));
|
| -
|
| - // Generates a combined 'change' event from an event of either list.
|
| - var changeHandler = function(listNum, e) {
|
| - var changeEvent = new Event('change');
|
| - changeEvent.index =
|
| - (listNum == 1) ? e.index : (e.index + this.volumesList_.length);
|
| - this.dispatchEvent(changeEvent);
|
| - };
|
| - this.volumesList_.addEventListener('change', changeHandler.bind(this, 1));
|
| - this.pinnedList_.addEventListener('change', changeHandler.bind(this, 2));
|
| -
|
| - // 'splice' and 'sorted' events are not implemented, since they are not used
|
| - // in list.js.
|
| -}
|
| -
|
| -/**
|
| - * VolumeList inherits cr.EventTarget.
|
| - */
|
| -VolumeListModel.prototype = {
|
| - __proto__: cr.EventTarget.prototype,
|
| - get length() { return this.length_(); }
|
| -};
|
| -
|
| -/**
|
| - * Returns the item at the given index.
|
| - * @param {number} index The index of the entry to get.
|
| - * @return {?string} The path at the given index.
|
| - */
|
| -VolumeListModel.prototype.item = function(index) {
|
| - var offset = this.volumesList_.length;
|
| - if (index < offset) {
|
| - var entry = this.volumesList_.item(index);
|
| - return entry ? entry.fullPath : undefined;
|
| - } else {
|
| - return this.pinnedList_.item(index - offset);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Type of the item on the volume list.
|
| - * @enum {number}
|
| - */
|
| -VolumeListModel.ItemType = {
|
| - ROOT: 1,
|
| - PINNED: 2
|
| -};
|
| -
|
| -/**
|
| - * Returns the type of the item at the given index.
|
| - * @param {number} index The index of the entry to get.
|
| - * @return {VolumeListModel.ItemType} The type of the item.
|
| - */
|
| -VolumeListModel.prototype.getItemType = function(index) {
|
| - var offset = this.volumesList_.length;
|
| - return index < offset ?
|
| - VolumeListModel.ItemType.ROOT : VolumeListModel.ItemType.PINNED;
|
| -};
|
| -
|
| -/**
|
| - * Returns the number of items in the model.
|
| - * @return {number} The length of the model.
|
| - * @private
|
| - */
|
| -VolumeListModel.prototype.length_ = function() {
|
| - return this.volumesList_.length + this.pinnedList_.length;
|
| -};
|
| -
|
| -/**
|
| - * Returns the first matching item.
|
| - * @param {Entry} item The entry to find.
|
| - * @param {number=} opt_fromIndex If provided, then the searching start at
|
| - * the {@code opt_fromIndex}.
|
| - * @return {number} The index of the first found element or -1 if not found.
|
| - */
|
| -VolumeListModel.prototype.indexOf = function(item, opt_fromIndex) {
|
| - for (var i = opt_fromIndex || 0; i < this.length; i++) {
|
| - if (item === this.item(i))
|
| - return i;
|
| - }
|
| - return -1;
|
| -};
|
| -
|
| -/**
|
| - * A volume item.
|
| - * @constructor
|
| - * @extends {HTMLLIElement}
|
| - */
|
| -var VolumeItem = cr.ui.define('li');
|
| -
|
| -VolumeItem.prototype = {
|
| - __proto__: HTMLLIElement.prototype,
|
| -};
|
| -
|
| -/**
|
| - * Decorate the item.
|
| - */
|
| -VolumeItem.prototype.decorate = function() {
|
| - // decorate() may be called twice: from the constructor and from
|
| - // List.createItem(). This check prevents double-decorating.
|
| - if (this.className)
|
| - return;
|
| -
|
| - this.className = 'root-item';
|
| - this.setAttribute('role', 'option');
|
| -
|
| - this.iconDiv_ = cr.doc.createElement('div');
|
| - this.iconDiv_.className = 'volume-icon';
|
| - this.appendChild(this.iconDiv_);
|
| -
|
| - this.label_ = cr.doc.createElement('div');
|
| - this.label_.className = 'root-label';
|
| - this.appendChild(this.label_);
|
| -
|
| - cr.defineProperty(this, 'lead', cr.PropertyKind.BOOL_ATTR);
|
| - cr.defineProperty(this, 'selected', cr.PropertyKind.BOOL_ATTR);
|
| -};
|
| -
|
| -/**
|
| - * Associate a path with this item.
|
| - * @param {string} path Path of this item.
|
| - */
|
| -VolumeItem.prototype.setPath = function(path) {
|
| - if (this.path_)
|
| - console.warn('VolumeItem.setPath should be called only once.');
|
| -
|
| - this.path_ = path;
|
| -
|
| - var rootType = PathUtil.getRootType(path);
|
| -
|
| - this.iconDiv_.setAttribute('volume-type-icon', rootType);
|
| - if (rootType === RootType.REMOVABLE) {
|
| - this.iconDiv_.setAttribute('volume-subtype',
|
| - VolumeManager.getInstance().getDeviceType(path));
|
| - }
|
| -
|
| - this.label_.textContent = PathUtil.getFolderLabel(path);
|
| -
|
| - if (rootType === RootType.ARCHIVE || rootType === RootType.REMOVABLE) {
|
| - this.eject_ = cr.doc.createElement('div');
|
| - // Block other mouse handlers.
|
| - this.eject_.addEventListener(
|
| - 'mouseup', function(e) { e.stopPropagation() });
|
| - this.eject_.addEventListener(
|
| - 'mousedown', function(e) { e.stopPropagation() });
|
| -
|
| - this.eject_.className = 'root-eject';
|
| - this.eject_.addEventListener('click', function(event) {
|
| - event.stopPropagation();
|
| - cr.dispatchSimpleEvent(this, 'eject');
|
| - }.bind(this));
|
| -
|
| - this.appendChild(this.eject_);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Associate a context menu with this item.
|
| - * @param {cr.ui.Menu} menu Menu this item.
|
| - */
|
| -VolumeItem.prototype.maybeSetContextMenu = function(menu) {
|
| - if (!this.path_) {
|
| - console.error(
|
| - 'VolumeItem.maybeSetContextMenu must be called after setPath().');
|
| - return;
|
| - }
|
| -
|
| - var isRoot = PathUtil.isRootPath(this.path_);
|
| - var rootType = PathUtil.getRootType(this.path_);
|
| - // The context menu is shown on the following items:
|
| - // - Removable and Archive volumes
|
| - // - Folder shortcuts
|
| - if (!isRoot ||
|
| - (rootType != RootType.DRIVE && rootType != RootType.DOWNLOADS))
|
| - cr.ui.contextMenuHandler.setContextMenu(this, menu);
|
| -};
|
| -
|
| -/**
|
| - * A volume list.
|
| - * @constructor
|
| - * @extends {cr.ui.List}
|
| - */
|
| -function VolumeList() {
|
| -}
|
| -
|
| -/**
|
| - * VolumeList inherits cr.ui.List.
|
| - */
|
| -VolumeList.prototype.__proto__ = cr.ui.List.prototype;
|
| -
|
| -/**
|
| - * @param {HTMLElement} el Element to be DirectoryItem.
|
| - * @param {DirectoryModel} directoryModel Current DirectoryModel.
|
| - * @param {cr.ui.ArrayDataModel} pinnedFolderModel Current model of the pinned
|
| - * folders.
|
| - */
|
| -VolumeList.decorate = function(el, directoryModel, pinnedFolderModel) {
|
| - el.__proto__ = VolumeList.prototype;
|
| - el.decorate(directoryModel, pinnedFolderModel);
|
| -};
|
| -
|
| -/**
|
| - * @param {DirectoryModel} directoryModel Current DirectoryModel.
|
| - * @param {cr.ui.ArrayDataModel} pinnedFolderModel Current model of the pinned
|
| - * folders.
|
| - */
|
| -VolumeList.prototype.decorate = function(directoryModel, pinnedFolderModel) {
|
| - cr.ui.List.decorate(this);
|
| - this.__proto__ = VolumeList.prototype;
|
| -
|
| - this.directoryModel_ = directoryModel;
|
| - this.volumeManager_ = VolumeManager.getInstance();
|
| - this.selectionModel = new cr.ui.ListSingleSelectionModel();
|
| -
|
| - this.directoryModel_.addEventListener('directory-changed',
|
| - this.onCurrentDirectoryChanged_.bind(this));
|
| - this.selectionModel.addEventListener(
|
| - 'change', this.onSelectionChange_.bind(this));
|
| - this.selectionModel.addEventListener(
|
| - 'beforeChange', this.onBeforeSelectionChange_.bind(this));
|
| -
|
| - this.scrollBar_ = new ScrollBar();
|
| - this.scrollBar_.initialize(this.parentNode, this);
|
| -
|
| - // Overriding default role 'list' set by cr.ui.List.decorate() to 'listbox'
|
| - // role for better accessibility on ChromeOS.
|
| - this.setAttribute('role', 'listbox');
|
| -
|
| - var self = this;
|
| - this.itemConstructor = function(path) {
|
| - return self.renderRoot_(path);
|
| - };
|
| -
|
| - this.pinnedItemList_ = pinnedFolderModel;
|
| -
|
| - this.dataModel =
|
| - new VolumeListModel(this.directoryModel_.getRootsList(),
|
| - this.pinnedItemList_);
|
| -};
|
| -
|
| -/**
|
| - * Creates an element of a volume. This method is called from cr.ui.List
|
| - * internally.
|
| - * @param {string} path Path of the directory to be rendered.
|
| - * @return {VolumeItem} Rendered element.
|
| - * @private
|
| - */
|
| -VolumeList.prototype.renderRoot_ = function(path) {
|
| - var item = new VolumeItem();
|
| - item.setPath(path);
|
| -
|
| - var handleClick = function() {
|
| - if (item.selected && path !== this.directoryModel_.getCurrentDirPath()) {
|
| - this.directoryModel_.changeDirectory(path);
|
| - }
|
| - }.bind(this);
|
| - item.addEventListener('click', handleClick);
|
| -
|
| - var handleEject = function() {
|
| - var unmountCommand = cr.doc.querySelector('command#unmount');
|
| - // Let's make sure 'canExecute' state of the command is properly set for
|
| - // the root before executing it.
|
| - unmountCommand.canExecuteChange(item);
|
| - unmountCommand.execute(item);
|
| - };
|
| - item.addEventListener('eject', handleEject);
|
| - // TODO(yoshiki): Check if the following touch handler is necessary or not.
|
| - // If unnecessary, remove it.
|
| - item.addEventListener(cr.ui.TouchHandler.EventType.TOUCH_START, handleClick);
|
| -
|
| - if (this.contextMenu_)
|
| - item.maybeSetContextMenu(this.contextMenu_);
|
| -
|
| - // If the current directory is already set.
|
| - if (this.currentVolume_ == path) {
|
| - setTimeout(function() {
|
| - this.selectedItem = path;
|
| - }.bind(this), 0);
|
| - }
|
| - return item;
|
| -};
|
| -
|
| -/**
|
| - * Sets a context menu. Context menu is enabled only on archive and removable
|
| - * volumes as of now.
|
| - *
|
| - * @param {cr.ui.Menu} menu Context menu.
|
| - */
|
| -VolumeList.prototype.setContextMenu = function(menu) {
|
| - this.contextMenu_ = menu;
|
| -
|
| - for (var i = 0; i < this.dataModel.length; i++) {
|
| - this.getListItemByIndex(i).maybeSetContextMenu(this.contextMenu_);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Selects the n-th volume from the list.
|
| - * @param {number} index Volume index.
|
| - * @return {boolean} True for success, otherwise false.
|
| - */
|
| -VolumeList.prototype.selectByIndex = function(index) {
|
| - if (index < 0 || index > this.dataModel.length - 1)
|
| - return false;
|
| -
|
| - var newPath = this.dataModel.item(index);
|
| - if (!newPath)
|
| - return false;
|
| -
|
| - // Prevents double-moving to the current directory.
|
| - if (this.directoryModel_.getCurrentDirEntry().fullPath == newPath)
|
| - return false;
|
| -
|
| - this.directoryModel_.changeDirectory(newPath);
|
| - return true;
|
| -};
|
| -
|
| -/**
|
| - * Handler before root item change.
|
| - * @param {Event} event The event.
|
| - * @private
|
| - */
|
| -VolumeList.prototype.onBeforeSelectionChange_ = function(event) {
|
| - if (event.changes.length == 1 && !event.changes[0].selected)
|
| - event.preventDefault();
|
| -};
|
| -
|
| -/**
|
| - * Handler for root item being clicked.
|
| - * @param {Event} event The event.
|
| - * @private
|
| - */
|
| -VolumeList.prototype.onSelectionChange_ = function(event) {
|
| - // This handler is invoked even when the volume list itself changes the
|
| - // selection. In such case, we shouldn't handle the event.
|
| - if (this.dontHandleSelectionEvent_)
|
| - return;
|
| -
|
| - this.selectByIndex(this.selectionModel.selectedIndex);
|
| -};
|
| -
|
| -/**
|
| - * Invoked when the current directory is changed.
|
| - * @param {Event} event The event.
|
| - * @private
|
| - */
|
| -VolumeList.prototype.onCurrentDirectoryChanged_ = function(event) {
|
| - var path = event.newDirEntry.fullPath || this.dataModel.getCurrentDirPath();
|
| - var newRootPath = PathUtil.getRootPath(path);
|
| -
|
| - // Synchronizes the volume list selection with the current directory, after
|
| - // it is changed outside of the volume list.
|
| -
|
| - // (1) Select the nearest parent directory (including the pinned directories).
|
| - var bestMatchIndex = -1;
|
| - var bestMatchSubStringLen = 0;
|
| - for (var i = 0; i < this.dataModel.length; i++) {
|
| - var itemPath = this.dataModel.item(i);
|
| - if (path.indexOf(itemPath) == 0) {
|
| - if (bestMatchSubStringLen < itemPath.length) {
|
| - bestMatchIndex = i;
|
| - bestMatchSubStringLen = itemPath.length;
|
| - }
|
| - }
|
| - }
|
| - if (bestMatchIndex != -1) {
|
| - // Not to invoke the handler of this instance, sets the guard.
|
| - this.dontHandleSelectionEvent_ = true;
|
| - this.selectionModel.selectedIndex = bestMatchIndex;
|
| - this.dontHandleSelectionEvent_ = false;
|
| - return;
|
| - }
|
| -
|
| - // (2) Selects the volume of the current directory.
|
| - for (var i = 0; i < this.dataModel.length; i++) {
|
| - var itemPath = this.dataModel.item(i);
|
| - if (PathUtil.getRootPath(itemPath) == newRootPath) {
|
| - // Not to invoke the handler of this instance, sets the guard.
|
| - this.dontHandleSelectionEvent_ = true;
|
| - this.selectionModel.selectedIndex = i;
|
| - this.dontHandleSelectionEvent_ = false;
|
| - return;
|
| - }
|
| - }
|
| -};
|
|
|