Index: ui/file_manager/file_manager/foreground/js/ui/navigation_list.js |
diff --git a/ui/file_manager/file_manager/foreground/js/ui/navigation_list.js b/ui/file_manager/file_manager/foreground/js/ui/navigation_list.js |
deleted file mode 100644 |
index 8de253d986f145da2aa66a468ec4f5eb2aea0e65..0000000000000000000000000000000000000000 |
--- a/ui/file_manager/file_manager/foreground/js/ui/navigation_list.js |
+++ /dev/null |
@@ -1,444 +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 navigation list item. |
- * @constructor |
- * @extends {HTMLLIElement} |
- */ |
-var NavigationListItem = cr.ui.define('li'); |
- |
-NavigationListItem.prototype = { |
- __proto__: HTMLLIElement.prototype, |
- get modelItem() { return this.modelItem_; } |
-}; |
- |
-/** |
- * Decorate the item. |
- */ |
-NavigationListItem.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 entry-name'; |
- this.appendChild(this.label_); |
- |
- cr.defineProperty(this, 'lead', cr.PropertyKind.BOOL_ATTR); |
- cr.defineProperty(this, 'selected', cr.PropertyKind.BOOL_ATTR); |
-}; |
- |
-/** |
- * Associate a model with this item. |
- * @param {NavigationModelItem} modelItem NavigationModelItem of this item. |
- */ |
-NavigationListItem.prototype.setModelItem = function(modelItem) { |
- if (this.modelItem_) |
- console.warn('NavigationListItem.setModelItem should be called only once.'); |
- |
- this.modelItem_ = modelItem; |
- |
- var typeIcon; |
- if (modelItem.isVolume) { |
- if (modelItem.volumeInfo.volumeType == 'provided') { |
- var backgroundImage = '-webkit-image-set(' + |
- 'url(chrome://extension-icon/' + modelItem.volumeInfo.extensionId + |
- '/24/1) 1x, ' + |
- 'url(chrome://extension-icon/' + modelItem.volumeInfo.extensionId + |
- '/48/1) 2x);'; |
- // The icon div is not yet added to DOM, therefore it is impossible to |
- // use style.backgroundImage. |
- this.iconDiv_.setAttribute( |
- 'style', 'background-image: ' + backgroundImage); |
- } |
- typeIcon = modelItem.volumeInfo.volumeType; |
- } else if (modelItem.isShortcut) { |
- // Shortcuts are available for Drive only. |
- typeIcon = VolumeManagerCommon.VolumeType.DRIVE; |
- } |
- |
- this.iconDiv_.setAttribute('volume-type-icon', typeIcon); |
- |
- if (modelItem.isVolume) { |
- this.iconDiv_.setAttribute( |
- 'volume-subtype', modelItem.volumeInfo.deviceType); |
- } |
- |
- this.label_.textContent = modelItem.label; |
- |
- if (modelItem.isVolume && |
- (modelItem.volumeInfo.volumeType === |
- VolumeManagerCommon.VolumeType.ARCHIVE || |
- modelItem.volumeInfo.volumeType === |
- VolumeManagerCommon.VolumeType.REMOVABLE || |
- modelItem.volumeInfo.volumeType === |
- VolumeManagerCommon.VolumeType.PROVIDED)) { |
- this.eject_ = cr.doc.createElement('div'); |
- // Block other mouse handlers. |
- this.eject_.addEventListener( |
- 'mouseup', function(event) { event.stopPropagation() }); |
- this.eject_.addEventListener( |
- 'mousedown', function(event) { event.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. |
- */ |
-NavigationListItem.prototype.maybeSetContextMenu = function(menu) { |
- if (!this.modelItem_) { |
- console.error('NavigationListItem.maybeSetContextMenu must be called ' + |
- 'after setModelItem().'); |
- return; |
- } |
- |
- // The context menu is shown on the following items: |
- // - Removable and Archive volumes |
- // - Folder shortcuts |
- if (this.modelItem_.isVolume && (this.modelItem_.volumeInfo.volumeType === |
- VolumeManagerCommon.VolumeType.REMOVABLE || |
- this.modelItem_.volumeInfo.volumeType === |
- VolumeManagerCommon.VolumeType.ARCHIVE || |
- this.modelItem_.volumeInfo.volumeType === |
- VolumeManagerCommon.VolumeType.PROVIDED) || |
- this.modelItem_.isShortcut) { |
- cr.ui.contextMenuHandler.setContextMenu(this, menu); |
- } |
-}; |
- |
-/** |
- * A navigation list. |
- * @constructor |
- * @extends {cr.ui.List} |
- */ |
-function NavigationList() { |
-} |
- |
-/** |
- * NavigationList inherits cr.ui.List. |
- */ |
-NavigationList.prototype = { |
- __proto__: cr.ui.List.prototype, |
- |
- set dataModel(dataModel) { |
- if (!this.onListContentChangedBound_) |
- this.onListContentChangedBound_ = this.onListContentChanged_.bind(this); |
- |
- if (this.dataModel_) { |
- this.dataModel_.removeEventListener( |
- 'change', this.onListContentChangedBound_); |
- this.dataModel_.removeEventListener( |
- 'permuted', this.onListContentChangedBound_); |
- } |
- |
- var parentSetter = cr.ui.List.prototype.__lookupSetter__('dataModel'); |
- parentSetter.call(this, dataModel); |
- |
- // This must be placed after the parent method is called, in order to make |
- // it sure that the list was changed. |
- dataModel.addEventListener('change', this.onListContentChangedBound_); |
- dataModel.addEventListener('permuted', this.onListContentChangedBound_); |
- }, |
- |
- get dataModel() { |
- return this.dataModel_; |
- }, |
- |
- // TODO(yoshiki): Add a setter of 'directoryModel'. |
-}; |
- |
-/** |
- * @param {HTMLElement} el Element to be DirectoryItem. |
- * @param {VolumeManagerWrapper} volumeManager The VolumeManager of the system. |
- * @param {DirectoryModel} directoryModel Current DirectoryModel. |
- * folders. |
- */ |
-NavigationList.decorate = function(el, volumeManager, directoryModel) { |
- el.__proto__ = NavigationList.prototype; |
- el.decorate(volumeManager, directoryModel); |
-}; |
- |
-/** |
- * @param {VolumeManagerWrapper} volumeManager The VolumeManager of the system. |
- * @param {DirectoryModel} directoryModel Current DirectoryModel. |
- */ |
-NavigationList.prototype.decorate = function(volumeManager, directoryModel) { |
- cr.ui.List.decorate(this); |
- this.__proto__ = NavigationList.prototype; |
- |
- this.directoryModel_ = directoryModel; |
- this.volumeManager_ = volumeManager; |
- 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); |
- |
- // Keeps track of selected model item to detect if it is changed actually. |
- this.currentModelItem_ = null; |
- |
- // 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(modelItem) { |
- return self.renderRoot_(modelItem); |
- }; |
-}; |
- |
-/** |
- * This overrides cr.ui.List.measureItem(). |
- * In the method, a temporary element is added/removed from the list, and we |
- * need to omit animations for such temporary items. |
- * |
- * @param {ListItem=} opt_item The list item to be measured. |
- * @return {{height: number, marginTop: number, marginBottom:number, |
- * width: number, marginLeft: number, marginRight:number}} Size. |
- * @override |
- */ |
-NavigationList.prototype.measureItem = function(opt_item) { |
- this.measuringTemporaryItemNow_ = true; |
- var result = cr.ui.List.prototype.measureItem.call(this, opt_item); |
- this.measuringTemporaryItemNow_ = false; |
- return result; |
-}; |
- |
-/** |
- * Creates an element of a navigation list. This method is called from |
- * cr.ui.List internally. |
- * |
- * @param {NavigationModelItem} modelItem NavigationModelItem to be rendered. |
- * @return {NavigationListItem} Rendered element. |
- * @private |
- */ |
-NavigationList.prototype.renderRoot_ = function(modelItem) { |
- var item = new NavigationListItem(); |
- item.setModelItem(modelItem); |
- |
- var handleClick = function() { |
- if (!item.selected) |
- return; |
- this.activateModelItem_(item.modelItem); |
- // On clicking the root item, clears the selection. |
- this.directoryModel_.clearSelection(); |
- }.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); |
- |
- if (this.contextMenu_) |
- item.maybeSetContextMenu(this.contextMenu_); |
- |
- 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. |
- */ |
-NavigationList.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 item from the list. |
- * @param {number} index Item index. |
- * @return {boolean} True for success, otherwise false. |
- */ |
-NavigationList.prototype.selectByIndex = function(index) { |
- if (index < 0 || index > this.dataModel.length - 1) |
- return false; |
- |
- this.selectionModel.selectedIndex = index; |
- this.activateModelItem_(this.dataModel.item(index)); |
- return true; |
-}; |
- |
- |
-/** |
- * Selects the passed item of the model. |
- * @param {NavigationModelItem} modelItem Model item to be activated. |
- * @private |
- */ |
-NavigationList.prototype.activateModelItem_ = function(modelItem) { |
- var onEntryResolved = function(entry) { |
- // Changes directory to the model item's root directory if needed. |
- if (!util.isSameEntry(this.directoryModel_.getCurrentDirEntry(), entry)) { |
- metrics.recordUserAction('FolderShortcut.Navigate'); |
- this.directoryModel_.changeDirectoryEntry(entry); |
- } |
- }.bind(this); |
- |
- if (modelItem.isVolume) { |
- modelItem.volumeInfo.resolveDisplayRoot( |
- onEntryResolved, |
- function() { |
- // Error, the display root is not available. It may happen on Drive. |
- this.dataModel.onItemNotFoundError(modelItem); |
- }.bind(this)); |
- } else if (modelItem.isShortcut) { |
- // For shortcuts we already have an Entry, but it has to be resolved again |
- // in case, it points to a non-existing directory. |
- var url = modelItem.entry.toURL(); |
- webkitResolveLocalFileSystemURL( |
- url, |
- onEntryResolved, |
- function() { |
- // Error, the entry can't be re-resolved. It may happen for shortcuts |
- // which targets got removed after resolving the Entry during |
- // initialization. |
- this.dataModel.onItemNotFoundError(modelItem); |
- }.bind(this)); |
- } |
-}; |
- |
-/** |
- * Handler before root item change. |
- * @param {Event} event The event. |
- * @private |
- */ |
-NavigationList.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 |
- */ |
-NavigationList.prototype.onSelectionChange_ = function(event) { |
- var index = this.selectionModel.selectedIndex; |
- if (index < 0 || index > this.dataModel.length - 1) |
- return; |
- |
- // If the selected model item is not changed actually, we don't change the |
- // current directory even if the selected index is changed. |
- var modelItem = this.dataModel.item(index); |
- if (modelItem === this.currentModelItem_) |
- return; |
- |
- // Remembers the selected model item. |
- this.currentModelItem_ = modelItem; |
- |
- // This handler is invoked even when the navigation list itself changes the |
- // selection. In such case, we shouldn't handle the event. |
- if (this.dontHandleSelectionEvent_) |
- return; |
- |
- this.activateModelItem_(modelItem); |
-}; |
- |
-/** |
- * Invoked when the current directory is changed. |
- * @param {Event} event The event. |
- * @private |
- */ |
-NavigationList.prototype.onCurrentDirectoryChanged_ = function(event) { |
- this.selectBestMatchItem_(); |
-}; |
- |
-/** |
- * Invoked when the content in the data model is changed. |
- * @param {Event} event The event. |
- * @private |
- */ |
-NavigationList.prototype.onListContentChanged_ = function(event) { |
- this.selectBestMatchItem_(); |
-}; |
- |
-/** |
- * Synchronizes the volume list selection with the current directory, after |
- * it is changed outside of the volume list. |
- * @private |
- */ |
-NavigationList.prototype.selectBestMatchItem_ = function() { |
- var entry = this.directoryModel_.getCurrentDirEntry(); |
- // It may happen that the current directory is not set yet, for update events. |
- if (!entry) |
- return; |
- |
- // (1) Select the nearest shortcut directory. |
- var entryURL = entry.toURL(); |
- var bestMatchIndex = -1; |
- var bestMatchSubStringLen = 0; |
- for (var i = 0; i < this.dataModel.length; i++) { |
- var modelItem = this.dataModel.item(i); |
- if (!modelItem.isShortcut) |
- continue; |
- var modelItemURL = modelItem.entry.toURL(); |
- // Relying on URL's format is risky and should be avoided. However, there is |
- // no other way to quickly check if an entry is an ancestor of another one. |
- if (entryURL.indexOf(modelItemURL) === 0) { |
- if (bestMatchSubStringLen < modelItemURL.length) { |
- bestMatchIndex = i; |
- bestMatchSubStringLen = modelItemURL.length; |
- } |
- } |
- } |
- if (bestMatchIndex != -1) { |
- // Don't 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. |
- var volumeInfo = this.volumeManager_.getVolumeInfo(entry); |
- if (!volumeInfo) |
- return; |
- for (var i = 0; i < this.dataModel.length; i++) { |
- var modelItem = this.dataModel.item(i); |
- if (!modelItem.isVolume) |
- continue; |
- if (modelItem.volumeInfo === volumeInfo) { |
- // Don't to invoke the handler of this instance, sets the guard. |
- this.dontHandleSelectionEvent_ = true; |
- this.selectionModel.selectedIndex = i; |
- this.dontHandleSelectionEvent_ = false; |
- return; |
- } |
- } |
-}; |