Index: ui/file_manager/file_manager/background/js/background.js |
diff --git a/ui/file_manager/file_manager/background/js/background.js b/ui/file_manager/file_manager/background/js/background.js |
deleted file mode 100644 |
index e21cf5101b2782ef7c9665931f7947d42c9c79a2..0000000000000000000000000000000000000000 |
--- a/ui/file_manager/file_manager/background/js/background.js |
+++ /dev/null |
@@ -1,530 +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'; |
- |
-/** |
- * Type of a Files.app's instance launch. |
- * @enum {number} |
- */ |
-var LaunchType = { |
- ALWAYS_CREATE: 0, |
- FOCUS_ANY_OR_CREATE: 1, |
- FOCUS_SAME_OR_CREATE: 2 |
-}; |
-Object.freeze(LaunchType); |
- |
-/** |
- * Root class of the background page. |
- * @constructor |
- * @extends {BackgroundBase} |
- */ |
-function FileBrowserBackground() { |
- BackgroundBase.call(this); |
- |
- /** |
- * Map of all currently open file dialogs. The key is an app ID. |
- * @type {Object.<string, Window>} |
- */ |
- this.dialogs = {}; |
- |
- /** |
- * Synchronous queue for asynchronous calls. |
- * @type {AsyncUtil.Queue} |
- */ |
- this.queue = new AsyncUtil.Queue(); |
- |
- /** |
- * Progress center of the background page. |
- * @type {ProgressCenter} |
- */ |
- this.progressCenter = new ProgressCenter(); |
- |
- /** |
- * File operation manager. |
- * @type {FileOperationManager} |
- */ |
- this.fileOperationManager = new FileOperationManager(); |
- |
- /** |
- * Event handler for progress center. |
- * @type {FileOperationHandler} |
- * @private |
- */ |
- this.fileOperationHandler_ = new FileOperationHandler(this); |
- |
- /** |
- * Event handler for C++ sides notifications. |
- * @type {DeviceHandler} |
- * @private |
- */ |
- this.deviceHandler_ = new DeviceHandler(); |
- this.deviceHandler_.addEventListener( |
- DeviceHandler.VOLUME_NAVIGATION_REQUESTED, |
- function(event) { |
- this.navigateToVolume_(event.devicePath); |
- }.bind(this)); |
- |
- /** |
- * Drive sync handler. |
- * @type {DriveSyncHandler} |
- * @private |
- */ |
- this.driveSyncHandler_ = new DriveSyncHandler(this.progressCenter); |
- this.driveSyncHandler_.addEventListener( |
- DriveSyncHandler.COMPLETED_EVENT, |
- function() { this.tryClose(); }.bind(this)); |
- |
- /** |
- * Promise of string data. |
- * @type {Promise} |
- */ |
- this.stringDataPromise = new Promise(function(fulfill) { |
- chrome.fileManagerPrivate.getStrings(fulfill); |
- }); |
- |
- /** |
- * String assets. |
- * @type {Object.<string, string>} |
- */ |
- this.stringData = null; |
- |
- /** |
- * Callback list to be invoked after initialization. |
- * It turns to null after initialization. |
- * |
- * @type {Array.<function()>} |
- * @private |
- */ |
- this.initializeCallbacks_ = []; |
- |
- /** |
- * Last time when the background page can close. |
- * |
- * @type {?number} |
- * @private |
- */ |
- this.lastTimeCanClose_ = null; |
- |
- // Seal self. |
- Object.seal(this); |
- |
- // Initialize handlers. |
- chrome.fileBrowserHandler.onExecute.addListener(this.onExecute_.bind(this)); |
- chrome.app.runtime.onLaunched.addListener(this.onLaunched_.bind(this)); |
- chrome.app.runtime.onRestarted.addListener(this.onRestarted_.bind(this)); |
- chrome.contextMenus.onClicked.addListener( |
- this.onContextMenuClicked_.bind(this)); |
- |
- this.queue.run(function(callback) { |
- this.stringDataPromise.then(function(strings) { |
- // Init string data. |
- this.stringData = strings; |
- loadTimeData.data = strings; |
- |
- // Init context menu. |
- this.initContextMenu_(); |
- |
- callback(); |
- }.bind(this)).catch(function(error) { |
- console.error(error.stack || error); |
- callback(); |
- }); |
- }.bind(this)); |
-} |
- |
-/** |
- * A number of delay milliseconds from the first call of tryClose to the actual |
- * close action. |
- * @type {number} |
- * @const |
- * @private |
- */ |
-FileBrowserBackground.CLOSE_DELAY_MS_ = 5000; |
- |
-FileBrowserBackground.prototype = { |
- __proto__: BackgroundBase.prototype |
-}; |
- |
-/** |
- * Register callback to be invoked after initialization. |
- * If the initialization is already done, the callback is invoked immediately. |
- * |
- * @param {function()} callback Initialize callback to be registered. |
- */ |
-FileBrowserBackground.prototype.ready = function(callback) { |
- this.stringDataPromise.then(callback); |
-}; |
- |
-/** |
- * Checks the current condition of background page. |
- * @return {boolean} True if the background page is closable, false if not. |
- */ |
-FileBrowserBackground.prototype.canClose = function() { |
- // If the file operation is going, the background page cannot close. |
- if (this.fileOperationManager.hasQueuedTasks() || |
- this.driveSyncHandler_.syncing) { |
- this.lastTimeCanClose_ = null; |
- return false; |
- } |
- |
- var views = chrome.extension.getViews(); |
- var closing = false; |
- for (var i = 0; i < views.length; i++) { |
- // If the window that is not the background page itself and it is not |
- // closing, the background page cannot close. |
- if (views[i] !== window && !views[i].closing) { |
- this.lastTimeCanClose_ = null; |
- return false; |
- } |
- closing = closing || views[i].closing; |
- } |
- |
- // If some windows are closing, or the background page can close but could not |
- // 5 seconds ago, We need more time for sure. |
- if (closing || |
- this.lastTimeCanClose_ === null || |
- (Date.now() - this.lastTimeCanClose_ < |
- FileBrowserBackground.CLOSE_DELAY_MS_)) { |
- if (this.lastTimeCanClose_ === null) |
- this.lastTimeCanClose_ = Date.now(); |
- setTimeout(this.tryClose.bind(this), FileBrowserBackground.CLOSE_DELAY_MS_); |
- return false; |
- } |
- |
- // Otherwise we can close the background page. |
- return true; |
-}; |
- |
-/** |
- * Opens the root directory of the volume in Files.app. |
- * @param {string} devicePath Device path to a volume to be opened. |
- * @private |
- */ |
-FileBrowserBackground.prototype.navigateToVolume_ = function(devicePath) { |
- VolumeManager.getInstance().then(function(volumeManager) { |
- var volumeInfoList = volumeManager.volumeInfoList; |
- for (var i = 0; i < volumeInfoList.length; i++) { |
- if (volumeInfoList.item(i).devicePath == devicePath) |
- return volumeInfoList.item(i).resolveDisplayRoot(); |
- } |
- return Promise.reject( |
- 'Volume having the device path: ' + devicePath + ' is not found.'); |
- }).then(function(entry) { |
- launchFileManager( |
- {currentDirectoryURL: entry.toURL()}, |
- /* App ID */ undefined, |
- LaunchType.FOCUS_SAME_OR_CREATE); |
- }).catch(function(error) { |
- console.error(error.stack || error); |
- }); |
-}; |
- |
-/** |
- * Prefix for the file manager window ID. |
- * @type {string} |
- * @const |
- */ |
-var FILES_ID_PREFIX = 'files#'; |
- |
-/** |
- * Regexp matching a file manager window ID. |
- * @type {RegExp} |
- * @const |
- */ |
-var FILES_ID_PATTERN = new RegExp('^' + FILES_ID_PREFIX + '(\\d*)$'); |
- |
-/** |
- * Prefix for the dialog ID. |
- * @type {string} |
- * @const |
- */ |
-var DIALOG_ID_PREFIX = 'dialog#'; |
- |
-/** |
- * Value of the next file manager window ID. |
- * @type {number} |
- */ |
-var nextFileManagerWindowID = 0; |
- |
-/** |
- * Value of the next file manager dialog ID. |
- * @type {number} |
- */ |
-var nextFileManagerDialogID = 0; |
- |
-/** |
- * File manager window create options. |
- * @type {Object} |
- * @const |
- */ |
-var FILE_MANAGER_WINDOW_CREATE_OPTIONS = Object.freeze({ |
- bounds: Object.freeze({ |
- left: Math.round(window.screen.availWidth * 0.1), |
- top: Math.round(window.screen.availHeight * 0.1), |
- width: Math.round(window.screen.availWidth * 0.8), |
- height: Math.round(window.screen.availHeight * 0.8) |
- }), |
- minWidth: 480, |
- minHeight: 300, |
- hidden: true |
-}); |
- |
-/** |
- * @param {Object=} opt_appState App state. |
- * @param {number=} opt_id Window id. |
- * @param {LaunchType=} opt_type Launch type. Default: ALWAYS_CREATE. |
- * @param {function(string)=} opt_callback Completion callback with the App ID. |
- */ |
-function launchFileManager(opt_appState, opt_id, opt_type, opt_callback) { |
- var type = opt_type || LaunchType.ALWAYS_CREATE; |
- |
- // Wait until all windows are created. |
- background.queue.run(function(onTaskCompleted) { |
- // Check if there is already a window with the same URL. If so, then |
- // reuse it instead of opening a new one. |
- if (type == LaunchType.FOCUS_SAME_OR_CREATE || |
- type == LaunchType.FOCUS_ANY_OR_CREATE) { |
- if (opt_appState) { |
- for (var key in background.appWindows) { |
- if (!key.match(FILES_ID_PATTERN)) |
- continue; |
- |
- var contentWindow = background.appWindows[key].contentWindow; |
- if (!contentWindow.appState) |
- continue; |
- |
- // Different current directories. |
- if (opt_appState.currentDirectoryURL !== |
- contentWindow.appState.currentDirectoryURL) { |
- continue; |
- } |
- |
- // Selection URL specified, and it is different. |
- if (opt_appState.selectionURL && |
- opt_appState.selectionURL !== |
- contentWindow.appState.selectionURL) { |
- continue; |
- } |
- |
- AppWindowWrapper.focusOnDesktop( |
- background.appWindows[key], opt_appState.displayedId); |
- if (opt_callback) |
- opt_callback(key); |
- onTaskCompleted(); |
- return; |
- } |
- } |
- } |
- |
- // Focus any window if none is focused. Try restored first. |
- if (type == LaunchType.FOCUS_ANY_OR_CREATE) { |
- // If there is already a focused window, then finish. |
- for (var key in background.appWindows) { |
- if (!key.match(FILES_ID_PATTERN)) |
- continue; |
- |
- // The isFocused() method should always be available, but in case |
- // Files.app's failed on some error, wrap it with try catch. |
- try { |
- if (background.appWindows[key].contentWindow.isFocused()) { |
- if (opt_callback) |
- opt_callback(key); |
- onTaskCompleted(); |
- return; |
- } |
- } catch (e) { |
- console.error(e.message); |
- } |
- } |
- // Try to focus the first non-minimized window. |
- for (var key in background.appWindows) { |
- if (!key.match(FILES_ID_PATTERN)) |
- continue; |
- |
- if (!background.appWindows[key].isMinimized()) { |
- AppWindowWrapper.focusOnDesktop( |
- background.appWindows[key], (opt_appState || {}).displayedId); |
- if (opt_callback) |
- opt_callback(key); |
- onTaskCompleted(); |
- return; |
- } |
- } |
- // Restore and focus any window. |
- for (var key in background.appWindows) { |
- if (!key.match(FILES_ID_PATTERN)) |
- continue; |
- |
- AppWindowWrapper.focusOnDesktop( |
- background.appWindows[key], (opt_appState || {}).displayedId); |
- if (opt_callback) |
- opt_callback(key); |
- onTaskCompleted(); |
- return; |
- } |
- } |
- |
- // Create a new instance in case of ALWAYS_CREATE type, or as a fallback |
- // for other types. |
- |
- var id = opt_id || nextFileManagerWindowID; |
- nextFileManagerWindowID = Math.max(nextFileManagerWindowID, id + 1); |
- var appId = FILES_ID_PREFIX + id; |
- |
- var appWindow = new AppWindowWrapper( |
- 'main.html', |
- appId, |
- FILE_MANAGER_WINDOW_CREATE_OPTIONS); |
- appWindow.launch(opt_appState || {}, false, function() { |
- AppWindowWrapper.focusOnDesktop( |
- appWindow.rawAppWindow, (opt_appState || {}).displayedId); |
- if (opt_callback) |
- opt_callback(appId); |
- onTaskCompleted(); |
- }); |
- }); |
-} |
- |
-/** |
- * Registers dialog window to the background page. |
- * |
- * @param {Window} dialogWindow Window of the dialog. |
- */ |
-function registerDialog(dialogWindow) { |
- var id = DIALOG_ID_PREFIX + (nextFileManagerDialogID++); |
- background.dialogs[id] = dialogWindow; |
- dialogWindow.addEventListener('pagehide', function() { |
- delete background.dialogs[id]; |
- }); |
-} |
- |
-/** |
- * Executes a file browser task. |
- * |
- * @param {string} action Task id. |
- * @param {Object} details Details object. |
- * @private |
- */ |
-FileBrowserBackground.prototype.onExecute_ = function(action, details) { |
- var appState = { |
- params: {action: action}, |
- // It is not allowed to call getParent() here, since there may be |
- // no permissions to access it at this stage. Therefore we are passing |
- // the selectionURL only, and the currentDirectory will be resolved |
- // later. |
- selectionURL: details.entries[0].toURL() |
- }; |
- |
- // Every other action opens a Files app window. |
- // For mounted devices just focus any Files.app window. The mounted |
- // volume will appear on the navigation list. |
- launchFileManager( |
- appState, |
- /* App ID */ undefined, |
- LaunchType.FOCUS_SAME_OR_CREATE); |
-}; |
- |
-/** |
- * Launches the app. |
- * @private |
- */ |
-FileBrowserBackground.prototype.onLaunched_ = function() { |
- if (nextFileManagerWindowID == 0) { |
- // The app just launched. Remove window state records that are not needed |
- // any more. |
- chrome.storage.local.get(function(items) { |
- for (var key in items) { |
- if (items.hasOwnProperty(key)) { |
- if (key.match(FILES_ID_PATTERN)) |
- chrome.storage.local.remove(key); |
- } |
- } |
- }); |
- } |
- launchFileManager(null, undefined, LaunchType.FOCUS_ANY_OR_CREATE); |
-}; |
- |
-/** |
- * Restarted the app, restore windows. |
- * @private |
- */ |
-FileBrowserBackground.prototype.onRestarted_ = function() { |
- // Reopen file manager windows. |
- chrome.storage.local.get(function(items) { |
- for (var key in items) { |
- if (items.hasOwnProperty(key)) { |
- var match = key.match(FILES_ID_PATTERN); |
- if (match) { |
- var id = Number(match[1]); |
- try { |
- var appState = /** @type {Object} */ (JSON.parse(items[key])); |
- launchFileManager(appState, id); |
- } catch (e) { |
- console.error('Corrupt launch data for ' + id); |
- } |
- } |
- } |
- } |
- }); |
-}; |
- |
-/** |
- * Handles clicks on a custom item on the launcher context menu. |
- * @param {OnClickData} info Event details. |
- * @private |
- */ |
-FileBrowserBackground.prototype.onContextMenuClicked_ = function(info) { |
- if (info.menuItemId == 'new-window') { |
- // Find the focused window (if any) and use it's current url for the |
- // new window. If not found, then launch with the default url. |
- for (var key in background.appWindows) { |
- try { |
- if (background.appWindows[key].contentWindow.isFocused()) { |
- var appState = { |
- // Do not clone the selection url, only the current directory. |
- currentDirectoryURL: background.appWindows[key].contentWindow. |
- appState.currentDirectoryURL |
- }; |
- launchFileManager(appState); |
- return; |
- } |
- } catch (ignore) { |
- // The isFocused method may not be defined during initialization. |
- // Therefore, wrapped with a try-catch block. |
- } |
- } |
- |
- // Launch with the default URL. |
- launchFileManager(); |
- } |
-}; |
- |
-/** |
- * Initializes the context menu. Recreates if already exists. |
- * @private |
- */ |
-FileBrowserBackground.prototype.initContextMenu_ = function() { |
- try { |
- // According to the spec [1], the callback is optional. But no callback |
- // causes an error for some reason, so we call it with null-callback to |
- // prevent the error. http://crbug.com/353877 |
- // - [1] https://developer.chrome.com/extensions/contextMenus#method-remove |
- chrome.contextMenus.remove('new-window', function() {}); |
- } catch (ignore) { |
- // There is no way to detect if the context menu is already added, therefore |
- // try to recreate it every time. |
- } |
- chrome.contextMenus.create({ |
- id: 'new-window', |
- contexts: ['launcher'], |
- title: str('NEW_WINDOW_BUTTON_LABEL') |
- }); |
-}; |
- |
-/** |
- * Singleton instance of Background. |
- * @type {FileBrowserBackground} |
- */ |
-window.background = new FileBrowserBackground(); |