| 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();
|
|
|