| Index: ui/file_manager/zip_archiver/unpacker/js/app.js
|
| diff --git a/ui/file_manager/zip_archiver/unpacker/js/app.js b/ui/file_manager/zip_archiver/unpacker/js/app.js
|
| deleted file mode 100644
|
| index 21182a1bc977af12fd7c61cbe803d760c049327d..0000000000000000000000000000000000000000
|
| --- a/ui/file_manager/zip_archiver/unpacker/js/app.js
|
| +++ /dev/null
|
| @@ -1,840 +0,0 @@
|
| -// Copyright 2014 The Chromium OS 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';
|
| -
|
| -/**
|
| - * The main namespace for the extension.
|
| - * @namespace
|
| - */
|
| -unpacker.app = {
|
| - /**
|
| - * The key used by chrome.storage.local to save and restore the volumes state.
|
| - * @const {string}
|
| - */
|
| - STORAGE_KEY: 'state',
|
| -
|
| - /**
|
| - * The default id for the NaCl module.
|
| - * @const {string}
|
| - */
|
| - DEFAULT_MODULE_ID: 'nacl_module',
|
| -
|
| - /**
|
| - * Time in milliseconds before the notification about mounting is shown.
|
| - * @const {number}
|
| - */
|
| - MOUNTING_NOTIFICATION_DELAY: 1000,
|
| -
|
| - /**
|
| - * The default filename for .nmf file.
|
| - * This value must not be const because it is overwritten in tests.
|
| - * @type {string}
|
| - */
|
| - DEFAULT_MODULE_NMF: 'module.nmf',
|
| -
|
| - /**
|
| - * The default MIME type for .nmf file.
|
| - * @const {string}
|
| - */
|
| - DEFAULT_MODULE_TYPE: 'application/x-pnacl',
|
| -
|
| - /**
|
| - * Multiple volumes can be opened at the same time.
|
| - * @type {!Object<!unpacker.types.FileSystemId, !unpacker.Volume>}
|
| - */
|
| - volumes: {},
|
| -
|
| - /**
|
| - * Each "Pack with" request from Files app creates a new compressor.
|
| - * Thus, multiple compressors can exist at the same time.
|
| - * @type {!Object<!unpacker.types.CompressorId, !unpacker.Compressor>}
|
| - */
|
| - compressors: {},
|
| -
|
| - /**
|
| - * A map with promises of loading a volume's metadata from NaCl.
|
| - * Any call from fileSystemProvider API should work only on valid metadata.
|
| - * These promises ensure that the fileSystemProvider API calls wait for the
|
| - * metatada load.
|
| - * @type {!Object<!unpacker.types.FileSystemId, !Promise>}
|
| - */
|
| - volumeLoadedPromises: {},
|
| -
|
| - /**
|
| - * A Promise used to postpone all calls to fileSystemProvider API after
|
| - * the NaCl module loads.
|
| - * @type {?Promise}
|
| - */
|
| - moduleLoadedPromise: null,
|
| -
|
| - /**
|
| - * The NaCl module containing the logic for decompressing archives.
|
| - * @type {?Object}
|
| - */
|
| - naclModule: null,
|
| -
|
| - /**
|
| - * The number of mount process in progress. NaCL module is unloaded if
|
| - * app.unpacker.volumes is empty and this counter is 0. This is incremented
|
| - * when a mounting process starts and decremented when it ends.
|
| - * @type {number}
|
| - */
|
| - mountProcessCounter: 0,
|
| -
|
| - /**
|
| - * Function called on receiving a message from NaCl module. Registered by
|
| - * common.js.
|
| - * Process pack message by getting compressor and passing the message to it.
|
| - * @param {!Object} message The message received from NaCl module.
|
| - * @param {!unpacker.request.Operation} operation
|
| - * @private
|
| - */
|
| - handlePackMessage_: function(message, operation) {
|
| - var compressorId = message.data[unpacker.request.Key.COMPRESSOR_ID];
|
| - console.assert(compressorId, 'No NaCl compressor id.');
|
| -
|
| - var compressor = unpacker.app.compressors[compressorId];
|
| - if (!compressor) {
|
| - console.error('No compressor for compressor id: ' + compressorId + '.');
|
| - return;
|
| - }
|
| - compressor.processMessage(message.data, operation);
|
| - },
|
| -
|
| - /**
|
| - * Process unpack message by getting volume and passing the message to it.
|
| - * @param {!Object} message The message received from NaCl module.
|
| - * @param {!unpacker.request.Operation} operation
|
| - * @private
|
| - */
|
| - handleUnpackMessage_: function(message, operation) {
|
| - var fileSystemId = message.data[unpacker.request.Key.FILE_SYSTEM_ID];
|
| - console.assert(fileSystemId, 'No NaCl file system id.');
|
| -
|
| - var requestId = message.data[unpacker.request.Key.REQUEST_ID];
|
| - console.assert(!!requestId, 'No NaCl request id.');
|
| -
|
| - var volume = unpacker.app.volumes[fileSystemId];
|
| - if (!volume) {
|
| - // The volume is gone, which can happen.
|
| - console.info('No volume for: ' + fileSystemId + '.');
|
| - return;
|
| - }
|
| -
|
| - volume.decompressor.processMessage(message.data, operation,
|
| - Number(requestId));
|
| - },
|
| -
|
| - /**
|
| - * Function called on receiving a message from NaCl module. Registered by
|
| - * common.js.
|
| - * @param {!Object} message The message received from NaCl module.
|
| - * @private
|
| - */
|
| - handleMessage_: function(message) {
|
| - // Get mandatory fields in a message.
|
| - var operation = message.data[unpacker.request.Key.OPERATION];
|
| - console.assert(operation != undefined, // Operation can be 0.
|
| - 'No NaCl operation: ' + operation + '.');
|
| -
|
| - // Assign the message to either module.
|
| - if (unpacker.request.isPackRequest(operation))
|
| - unpacker.app.handlePackMessage_(message, operation);
|
| - else
|
| - unpacker.app.handleUnpackMessage_(message, operation);
|
| - },
|
| -
|
| - /**
|
| - * Saves state in case of restarts, event page suspend, crashes, etc.
|
| - * @param {!Array<!unpacker.types.FileSystemId>} fileSystemIdsArray
|
| - * @private
|
| - */
|
| - saveState_: function(fileSystemIdsArray) {
|
| - chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
|
| - if (!result[unpacker.app.STORAGE_KEY]) // First save state call.
|
| - result[unpacker.app.STORAGE_KEY] = {};
|
| -
|
| - // Overwrite state only for the volumes that have their file system id
|
| - // present in the input array. Leave the rest of the volumes state
|
| - // untouched.
|
| - fileSystemIdsArray.forEach(function(fileSystemId) {
|
| - var entryId = chrome.fileSystem.retainEntry(
|
| - unpacker.app.volumes[fileSystemId].entry);
|
| - result[unpacker.app.STORAGE_KEY][fileSystemId] = {
|
| - entryId: entryId,
|
| - passphrase: unpacker.app.volumes[fileSystemId]
|
| - .decompressor.passphraseManager.rememberedPassphrase
|
| - };
|
| - });
|
| -
|
| - chrome.storage.local.set(result);
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Removes state from local storage for a single volume.
|
| - * @param {!unpacker.types.FileSystemId} fileSystemId
|
| - */
|
| - removeState_: function(fileSystemId) {
|
| - chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
|
| - console.assert(result[unpacker.app.STORAGE_KEY] &&
|
| - result[unpacker.app.STORAGE_KEY][fileSystemId],
|
| - 'Should call removeState_ only for file systems that ',
|
| - 'have previously called saveState_.');
|
| -
|
| - delete result[unpacker.app.STORAGE_KEY][fileSystemId];
|
| - chrome.storage.local.set(result);
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Restores archive's entry and opened files for the passed file system id.
|
| - * @param {!unpacker.types.FileSystemId} fileSystemId
|
| - * @return {!Promise<!Object>} Promise fulfilled with the entry and list of
|
| - * opened files.
|
| - * @private
|
| - */
|
| - restoreVolumeState_: function(fileSystemId) {
|
| - return new Promise(function(fulfill, reject) {
|
| - chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
|
| - if (!result[unpacker.app.STORAGE_KEY]) {
|
| - reject('FAILED');
|
| - return;
|
| - }
|
| -
|
| - var volumeState = result[unpacker.app.STORAGE_KEY][fileSystemId];
|
| - if (!volumeState) {
|
| - console.error('No state for: ' + fileSystemId + '.');
|
| - reject('FAILED');
|
| - return;
|
| - }
|
| -
|
| - chrome.fileSystem.restoreEntry(volumeState.entryId, function(entry) {
|
| - if (chrome.runtime.lastError) {
|
| - console.error('Restore entry error for <', fileSystemId, '>: ' +
|
| - chrome.runtime.lastError.message);
|
| - reject('FAILED');
|
| - return;
|
| - }
|
| - fulfill({
|
| - entry: entry,
|
| - passphrase: volumeState.passphrase
|
| - });
|
| - });
|
| - });
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Creates a volume and loads its metadata from NaCl.
|
| - * @param {!unpacker.types.FileSystemId} fileSystemId
|
| - * @param {!Entry} entry The volume's archive entry.
|
| - * @param {!Object<!unpacker.types.RequestId,
|
| - * !unpacker.types.OpenFileRequestedOptions>}
|
| - * openedFiles Previously opened files before a suspend.
|
| - * @param {string} passphrase Previously used passphrase before a suspend.
|
| - * @return {!Promise} Promise fulfilled on success and rejected on failure.
|
| - * @private
|
| - */
|
| - loadVolume_: function(fileSystemId, entry, openedFiles, passphrase) {
|
| - return new Promise(function(fulfill, reject) {
|
| - entry.file(function(file) {
|
| - // File is a Blob object, so it's ok to construct the Decompressor
|
| - // directly with it.
|
| - var passphraseManager = new unpacker.PassphraseManager(passphrase);
|
| - console.assert(unpacker.app.naclModule,
|
| - 'The NaCL module should have already been defined.');
|
| - var decompressor = new unpacker.Decompressor(
|
| - /** @type {!Object} */ (unpacker.app.naclModule),
|
| - fileSystemId, file, passphraseManager);
|
| - var volume = new unpacker.Volume(decompressor, entry);
|
| -
|
| - var onLoadVolumeSuccess = function() {
|
| - if (Object.keys(openedFiles).length == 0) {
|
| - fulfill();
|
| - return;
|
| - }
|
| -
|
| - // Restore opened files on NaCl side.
|
| - var openFilePromises = [];
|
| - for (var key in openedFiles) {
|
| - // 'key' is always a number but JS compiler complains that it is
|
| - // a string.
|
| - var openRequestId = Number(key);
|
| - var options =
|
| - /** @type {!unpacker.types.OpenFileRequestedOptions} */
|
| - (openedFiles[openRequestId]);
|
| - openFilePromises.push(new Promise(function(resolve, reject) {
|
| - volume.onOpenFileRequested(options, resolve, reject);
|
| - }));
|
| - }
|
| -
|
| - Promise.all(openFilePromises).then(fulfill, reject);
|
| - };
|
| -
|
| - unpacker.app.volumes[fileSystemId] = volume;
|
| - volume.initialize(onLoadVolumeSuccess, reject);
|
| - }, function(error) {
|
| - reject('FAILED');
|
| - });
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Restores a volume mounted previously to a suspend / restart. In case of
|
| - * failure of the load promise for fileSystemId, the corresponding volume is
|
| - * forcely unmounted.
|
| - * @param {!unpacker.types.FileSystemId} fileSystemId
|
| - * @return {!Promise} A promise that restores state and loads volume.
|
| - * @private
|
| - */
|
| - restoreSingleVolume_: function(fileSystemId) {
|
| - // Load volume after restart / suspend page event.
|
| - return unpacker.app.restoreVolumeState_(fileSystemId)
|
| - .then(function(state) {
|
| - return new Promise(function(fulfill, reject) {
|
| - // Check if the file system is compatible with this version of the
|
| - // ZIP unpacker.
|
| - // TODO(mtomasz): Implement remounting instead of unmounting.
|
| - chrome.fileSystemProvider.get(fileSystemId, function(fileSystem) {
|
| - if (chrome.runtime.lastError) {
|
| - console.error(chrome.runtime.lastError.name);
|
| - reject('FAILED');
|
| - return;
|
| - }
|
| - if (!fileSystem || fileSystem.openedFilesLimit != 1) {
|
| - console.error('No compatible mounted file system found.');
|
| - reject('FAILED');
|
| - return;
|
| - }
|
| - fulfill({state: state, fileSystem: fileSystem});
|
| - });
|
| - });
|
| - })
|
| - .then(function(stateWithFileSystem) {
|
| - var openedFilesOptions = {};
|
| - stateWithFileSystem.fileSystem.openedFiles.forEach(function(
|
| - openedFile) {
|
| - openedFilesOptions[openedFile.openRequestId] = {
|
| - fileSystemId: fileSystemId,
|
| - requestId: openedFile.openRequestId,
|
| - mode: openedFile.mode,
|
| - filePath: openedFile.filePath
|
| - };
|
| - });
|
| - return unpacker.app.loadVolume_(
|
| - fileSystemId, stateWithFileSystem.state.entry, openedFilesOptions,
|
| - stateWithFileSystem.state.passphrase);
|
| - })
|
| - .catch(function(error) {
|
| - console.error(error.stack || error);
|
| - // Force unmount in case restore failed. All resources related to the
|
| - // volume will be cleanup from both memory and local storage.
|
| - // TODO(523195): Show a notification that the source file is gone.
|
| - return unpacker.app.unmountVolume(fileSystemId, true)
|
| - .then(function() { return Promise.reject('FAILED'); });
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Ensures a volume is loaded by returning its corresponding loaded promise
|
| - * from unpacker.app.volumeLoadedPromises. In case there is no such promise,
|
| - * then this is a call after suspend / restart and a new volume loaded promise
|
| - * that restores state is returned.
|
| - * @param {!unpacker.types.FileSystemId} fileSystemId
|
| - * @return {!Promise} The loading volume promise.
|
| - * @private
|
| - */
|
| - ensureVolumeLoaded_: function(fileSystemId) {
|
| - // Increment the counter so that the NaCl module won't be unloaded until
|
| - // the mounting process ends.
|
| - unpacker.app.mountProcessCounter++;
|
| - // Create a promise to load the NaCL module.
|
| - if (!unpacker.app.moduleLoadedPromise)
|
| - unpacker.app.loadNaclModule(unpacker.app.DEFAULT_MODULE_NMF,
|
| - unpacker.app.DEFAULT_MODULE_TYPE);
|
| -
|
| - return unpacker.app.moduleLoadedPromise.then(function() {
|
| - // In case there is no volume promise for fileSystemId then we
|
| - // received a call after restart / suspend as load promises are
|
| - // created on launched. In this case we will restore volume state
|
| - // from local storage and create a new load promise.
|
| - if (!unpacker.app.volumeLoadedPromises[fileSystemId]) {
|
| - unpacker.app.volumeLoadedPromises[fileSystemId] =
|
| - unpacker.app.restoreSingleVolume_(fileSystemId);
|
| - }
|
| -
|
| - // Decrement the counter when the mounting process ends.
|
| - unpacker.app.volumeLoadedPromises[fileSystemId].then(function() {
|
| - unpacker.app.mountProcessCounter--;
|
| - }).catch(function(error) {
|
| - unpacker.app.mountProcessCounter--;
|
| - });
|
| -
|
| - return unpacker.app.volumeLoadedPromises[fileSystemId];
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean} True if NaCl module is loaded.
|
| - */
|
| - naclModuleIsLoaded: function() { return !!unpacker.app.naclModule; },
|
| -
|
| - /**
|
| - * Loads the NaCl module.
|
| - * @param {string} pathToConfigureFile Path to the module's configuration
|
| - * file, which should be a .nmf file.
|
| - * @param {string} mimeType The mime type for the NaCl executable.
|
| - * @param {string=} opt_moduleId The NaCl module id. Necessary for testing
|
| - * purposes.
|
| - */
|
| - loadNaclModule: function(pathToConfigureFile, mimeType, opt_moduleId) {
|
| - unpacker.app.moduleLoadedPromise = new Promise(function(fulfill) {
|
| - var moduleId =
|
| - opt_moduleId ? opt_moduleId : unpacker.app.DEFAULT_MODULE_ID;
|
| - var elementDiv = document.createElement('div');
|
| -
|
| - // Promise fulfills only after NaCl module has been loaded.
|
| - elementDiv.addEventListener('load', function() {
|
| - // Since the first load of the NaCL module is slow, the module is loaded
|
| - // once in background.js in advance. If there is no mounted volume and
|
| - // ongoing mounting process, the module is just unloaded. This is the
|
| - // workaround for crbug.com/699930.
|
| - if (Object.keys(unpacker.app.volumes).length === 0 &&
|
| - unpacker.app.mountProcessCounter === 0) {
|
| - elementDiv.parentNode.removeChild(elementDiv);
|
| - // This is necessary for tests.
|
| - fulfill();
|
| - unpacker.app.moduleLoadedPromise = null;
|
| - return;
|
| - }
|
| - unpacker.app.naclModule = document.getElementById(moduleId);
|
| - fulfill();
|
| - }, true);
|
| -
|
| - elementDiv.addEventListener('message', unpacker.app.handleMessage_, true);
|
| -
|
| - var elementEmbed = document.createElement('embed');
|
| - elementEmbed.id = moduleId;
|
| - elementEmbed.style.width = 0;
|
| - elementEmbed.style.height = 0;
|
| - elementEmbed.src = pathToConfigureFile;
|
| - elementEmbed.type = mimeType;
|
| - elementDiv.appendChild(elementEmbed);
|
| -
|
| - document.body.appendChild(elementDiv);
|
| - // Request the offsetTop property to force a relayout. As of Apr 10, 2014
|
| - // this is needed if the module is being loaded on a Chrome App's
|
| - // background page (see crbug.com/350445).
|
| - /** @suppress {suspiciousCode} */ elementEmbed.offsetTop;
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Unloads the NaCl module.
|
| - */
|
| - unloadNaclModule: function() {
|
| - var naclModuleParentNode = unpacker.app.naclModule.parentNode;
|
| - naclModuleParentNode.parentNode.removeChild(naclModuleParentNode);
|
| - unpacker.app.naclModule = null;
|
| - unpacker.app.moduleLoadedPromise = null;
|
| - },
|
| -
|
| - /**
|
| - * Cleans up the resources for a volume, except for the local storage. If
|
| - * necessary that can be done using unpacker.app.removeState_.
|
| - * @param {!unpacker.types.FileSystemId} fileSystemId
|
| - */
|
| - cleanupVolume: function(fileSystemId) {
|
| - delete unpacker.app.volumes[fileSystemId];
|
| - // Allow mount after clean.
|
| - delete unpacker.app.volumeLoadedPromises[fileSystemId];
|
| -
|
| - if (Object.keys(unpacker.app.volumes).length === 0 &&
|
| - unpacker.app.mountProcessCounter === 0) {
|
| - unpacker.app.unloadNaclModule();
|
| - } else {
|
| - unpacker.app.naclModule.postMessage(
|
| - unpacker.request.createCloseVolumeRequest(fileSystemId));
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Cleans up the resources for a compressor.
|
| - * @param {!unpacker.types.CompressorId} compressorId
|
| - * @param {boolean} hasError
|
| - */
|
| - cleanupCompressor: function(compressorId, hasError) {
|
| - var compressor = unpacker.app.compressors[compressorId];
|
| - if (!compressor) {
|
| - console.error('No compressor for: compressor id' + compressorId + '.');
|
| - return;
|
| - }
|
| -
|
| - unpacker.app.mountProcessCounter--;
|
| - if (Object.keys(unpacker.app.volumes).length === 0 &&
|
| - unpacker.app.mountProcessCounter === 0) {
|
| - unpacker.app.unloadNaclModule();
|
| - } else {
|
| - // Request libarchive to abort any ongoing process and release resources.
|
| - // The argument indicates whether an error occurred or not.
|
| - if (hasError)
|
| - compressor.sendCloseArchiveRequest(hasError);
|
| - }
|
| -
|
| - // Delete the archive file if it exists.
|
| - if (compressor.archiveFileEntry)
|
| - compressor.archiveFileEntry.remove();
|
| -
|
| - delete unpacker.app.compressors[compressorId];
|
| - },
|
| -
|
| - /**
|
| - * Unmounts a volume and removes any resources related to the volume from both
|
| - * the extension and the local storage state.
|
| - * @param {!unpacker.types.FileSystemId} fileSystemId
|
| - * @param {boolean=} opt_forceUnmount True if unmount should be forced even if
|
| - * volume might be in use, or is not restored yet.
|
| - * @return {!Promise} A promise that fulfills if volume is unmounted or
|
| - * rejects with ProviderError in case of any errors.
|
| - */
|
| - unmountVolume: function(fileSystemId, opt_forceUnmount) {
|
| - return new Promise(function(fulfill, reject) {
|
| - var volume = unpacker.app.volumes[fileSystemId];
|
| - console.assert(volume || opt_forceUnmount,
|
| - 'Unmount that is not forced must not be called for ',
|
| - 'volumes that are not restored.');
|
| -
|
| - if (!opt_forceUnmount && volume.inUse()) {
|
| - reject('IN_USE');
|
| - return;
|
| - }
|
| -
|
| - var options = {
|
| - fileSystemId: fileSystemId
|
| - };
|
| - chrome.fileSystemProvider.unmount(options, function() {
|
| - if (chrome.runtime.lastError) {
|
| - console.error('Unmount error: ' + chrome.runtime.lastError.message +
|
| - '.');
|
| - reject('FAILED');
|
| - return;
|
| - }
|
| -
|
| - // In case of forced unmount volume can be undefined due to not being
|
| - // restored. An unmount that is not forced will be called only after
|
| - // restoring state. In the case of forced unmount when volume is not
|
| - // restored, we will not do a normal cleanup, but just remove the load
|
| - // volume promise to allow further mounts.
|
| - if (opt_forceUnmount)
|
| - delete unpacker.app.volumeLoadedPromises[fileSystemId];
|
| - else
|
| - unpacker.app.cleanupVolume(fileSystemId);
|
| -
|
| - // Remove volume from local storage.
|
| - unpacker.app.removeState_(fileSystemId);
|
| - fulfill();
|
| - });
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Handles an unmount request received from File System Provider API.
|
| - * @param {!unpacker.types.UnmountRequestedOptions} options
|
| - * @param {function()} onSuccess Callback to execute on success.
|
| - * @param {function(!ProviderError)} onError Callback to execute on error.
|
| - */
|
| - onUnmountRequested: function(options, onSuccess, onError) {
|
| - unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
|
| - .then(function() {
|
| - return unpacker.app.unmountVolume(options.fileSystemId);
|
| - })
|
| - .then(onSuccess)
|
| - .catch(/** @type {function(*)} */ (onError));
|
| - },
|
| -
|
| - /**
|
| - * Obtains metadata about a file system entry.
|
| - * @param {!unpacker.types.GetMetadataRequestedOptions} options
|
| - * @param {function(!EntryMetadata)} onSuccess Callback to execute on success.
|
| - * The parameter is the EntryMetadata obtained by this function.
|
| - * @param {function(!ProviderError)} onError Callback to execute on error.
|
| - */
|
| - onGetMetadataRequested: function(options, onSuccess, onError) {
|
| - unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
|
| - .then(function() {
|
| - unpacker.app.volumes[options.fileSystemId].onGetMetadataRequested(
|
| - options, onSuccess, onError);
|
| - })
|
| - .catch(/** @type {function(*)} */ (onError));
|
| - },
|
| -
|
| - /**
|
| - * Reads a directory entries.
|
| - * @param {!unpacker.types.ReadDirectoryRequestedOptions} options
|
| - * @param {function(!Array<!EntryMetadata>, boolean)} onSuccess Callback to
|
| - * execute on success. The first parameter is an array with directory
|
| - * entries. The second parameter is 'hasMore', and if it's set to true,
|
| - * then onSuccess must be called again with the next directory entries.
|
| - * @param {function(!ProviderError)} onError Callback to execute on error.
|
| - */
|
| - onReadDirectoryRequested: function(options, onSuccess, onError) {
|
| - unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
|
| - .then(function() {
|
| - unpacker.app.volumes[options.fileSystemId].onReadDirectoryRequested(
|
| - options, onSuccess, onError);
|
| - })
|
| - .catch(/** @type {function(*)} */ (onError));
|
| - },
|
| -
|
| - /**
|
| - * Opens a file for read or write.
|
| - * @param {!unpacker.types.OpenFileRequestedOptions} options
|
| - * @param {function()} onSuccess Callback to execute on success.
|
| - * @param {function(!ProviderError)} onError Callback to execute on error.
|
| - */
|
| - onOpenFileRequested: function(options, onSuccess, onError) {
|
| - unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
|
| - .then(function() {
|
| - unpacker.app.volumes[options.fileSystemId].onOpenFileRequested(
|
| - options, onSuccess, onError);
|
| - })
|
| - .catch(/** @type {function(*)} */ (onError));
|
| - },
|
| -
|
| - /**
|
| - * Closes a file identified by options.openRequestId.
|
| - * @param {!unpacker.types.CloseFileRequestedOptions} options
|
| - * @param {function()} onSuccess Callback to execute on success.
|
| - * @param {function(!ProviderError)} onError Callback to execute on error.
|
| - */
|
| - onCloseFileRequested: function(options, onSuccess, onError) {
|
| - unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
|
| - .then(function() {
|
| - unpacker.app.volumes[options.fileSystemId].onCloseFileRequested(
|
| - options, onSuccess, onError);
|
| - })
|
| - .catch(/** @type {function(*)} */ (onError));
|
| - },
|
| -
|
| - /**
|
| - * Reads the contents of a file identified by options.openRequestId.
|
| - * @param {!unpacker.types.ReadFileRequestedOptions} options
|
| - * @param {function(!ArrayBuffer, boolean)} onSuccess Callback to execute on
|
| - * success. The first parameter is the read data and the second parameter
|
| - * is 'hasMore'. If it's set to true, then onSuccess must be called again
|
| - * with the next data to read.
|
| - * @param {function(!ProviderError)} onError Callback to execute on error.
|
| - */
|
| - onReadFileRequested: function(options, onSuccess, onError) {
|
| - unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
|
| - .then(function() {
|
| - unpacker.app.volumes[options.fileSystemId].onReadFileRequested(
|
| - options, onSuccess, onError);
|
| - })
|
| - .catch(/** @type {function(*)} */ (onError));
|
| - },
|
| -
|
| - /**
|
| - * Creates a new compressor and compresses entries.
|
| - * @param {!Object} launchData
|
| - */
|
| - onLaunchedWithPack: function(launchData) {
|
| - unpacker.app.mountProcessCounter++;
|
| -
|
| - // Create a promise to load the NaCL module.
|
| - if (!unpacker.app.moduleLoadedPromise) {
|
| - unpacker.app.loadNaclModule(unpacker.app.DEFAULT_MODULE_NMF,
|
| - unpacker.app.DEFAULT_MODULE_TYPE);
|
| - }
|
| -
|
| - unpacker.app.moduleLoadedPromise
|
| - .then(function() {
|
| - var compressor = new unpacker.Compressor(
|
| - /** @type {!Object} */ (unpacker.app.naclModule),
|
| - launchData.items);
|
| -
|
| - var compressorId = compressor.getCompressorId();
|
| -
|
| - unpacker.app.compressors[compressorId] = compressor;
|
| -
|
| - // TODO(takise): Error messages have not been prepared yet for timer
|
| - // and error processing.
|
| -
|
| - // If packing takes significant amount of time, then show a
|
| - // notification about packing in progress.
|
| - // var deferredNotificationTimer = setTimeout(function() {
|
| - // chrome.notifications.create(compressorId.toString(), {
|
| - // type: 'basic',
|
| - // iconUrl: chrome.runtime.getManifest().icons[128],
|
| - // title: entry.name,
|
| - // message: chrome.i18n.getMessage('packingMessage'),
|
| - // }, function() {});
|
| - // }, unpacker.app.PACKING_NOTIFICATION_DELAY);
|
| -
|
| - var onError = function(compressorId) {
|
| - // clearTimeout(deferredNotificationTimer);
|
| - // console.error('Packing error: ' + error.message + '.');
|
| - // chrome.notifications.create(compressorId.toString(), {
|
| - // type: 'basic',
|
| - // iconUrl: chrome.runtime.getManifest().icons[128],
|
| - // title: entry.name,
|
| - // message: chrome.i18n.getMessage('packingErrorMessage')
|
| - // }, function() {});
|
| - unpacker.app.cleanupCompressor(compressorId, true /* hasError */);
|
| - };
|
| -
|
| - var onSuccess = function(compressorId) {
|
| - // clearTimeout(deferredNotificationTimer);
|
| - // chrome.notifications.clear(compressorId.toString(),
|
| - // function() {});
|
| - unpacker.app.cleanupCompressor(compressorId, false /* hasError */);
|
| - };
|
| -
|
| - compressor.compress(onSuccess, onError);
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Creates a volume for every opened file with the extension or mime type
|
| - * declared in the manifest file.
|
| - * @param {!Object} launchData
|
| - * @param {function(string)=} opt_onSuccess Callback to execute in case a
|
| - * volume was loaded successfully. Has one parameter, which is the file
|
| - * system id of the loaded volume. Can be called multiple times, depending
|
| - * on how many volumes must be loaded.
|
| - * @param {function(string)=} opt_onError Callback to execute in case of
|
| - * failure when loading a volume. Has one parameter, which is the file
|
| - * system id of the volume that failed to load. Can be called multiple
|
| - * times, depending on how many volumes must be loaded.
|
| - */
|
| - onLaunchedWithUnpack: function(launchData, opt_onSuccess, opt_onError) {
|
| - // Increment the counter that indicates the number of ongoing mouot process.
|
| - unpacker.app.mountProcessCounter++;
|
| -
|
| - // Create a promise to load the NaCL module.
|
| - if (!unpacker.app.moduleLoadedPromise) {
|
| - unpacker.app.loadNaclModule(unpacker.app.DEFAULT_MODULE_NMF,
|
| - unpacker.app.DEFAULT_MODULE_TYPE);
|
| - }
|
| -
|
| - unpacker.app.moduleLoadedPromise
|
| - .then(function() {
|
| - unpacker.app.mountProcessCounter--;
|
| - launchData.items.forEach(function(item) {
|
| - unpacker.app.mountProcessCounter++;
|
| - chrome.fileSystem.getDisplayPath(item.entry, function(
|
| - entry,
|
| - fileSystemId) {
|
| - // If loading takes significant amount of time, then show a
|
| - // notification about scanning in progress.
|
| - var deferredNotificationTimer = setTimeout(function() {
|
| - chrome.notifications.create(fileSystemId, {
|
| - type: 'basic',
|
| - iconUrl: chrome.runtime.getManifest().icons[128],
|
| - title: entry.name,
|
| - message: chrome.i18n.getMessage('mountingMessage'),
|
| - }, function() {});
|
| - }, unpacker.app.MOUNTING_NOTIFICATION_DELAY);
|
| -
|
| - var onError = function(error, fileSystemId) {
|
| - clearTimeout(deferredNotificationTimer);
|
| - console.error('Mount error: ' + error.message + '.');
|
| - // Decrement the counter that indicates the number of ongoing
|
| - // mount process.
|
| - unpacker.app.mountProcessCounter--;
|
| - if (error.message === 'EXISTS') {
|
| - if (opt_onError)
|
| - opt_onError(fileSystemId);
|
| - return;
|
| - }
|
| - chrome.notifications.create(fileSystemId, {
|
| - type: 'basic',
|
| - iconUrl: chrome.runtime.getManifest().icons[128],
|
| - title: entry.name,
|
| - message: chrome.i18n.getMessage('otherErrorMessage')
|
| - }, function() {});
|
| - if (opt_onError)
|
| - opt_onError(fileSystemId);
|
| - // Cleanup volume resources in order to allow future attempts
|
| - // to mount the volume. The volume can't be cleaned up in
|
| - // case of 'EXIST' because we should not clean the other
|
| - // already mounted volume.
|
| - unpacker.app.cleanupVolume(fileSystemId);
|
| - };
|
| -
|
| - var onSuccess = function(fileSystemId) {
|
| - clearTimeout(deferredNotificationTimer);
|
| - chrome.notifications.clear(fileSystemId, function() {});
|
| - // Decrement the counter that indicates the number of ongoing
|
| - // mount process.
|
| - unpacker.app.mountProcessCounter--;
|
| - if (opt_onSuccess)
|
| - opt_onSuccess(fileSystemId);
|
| - };
|
| -
|
| - var loadPromise = unpacker.app.loadVolume_(
|
| - fileSystemId, entry, {}, '' /* passphrase */);
|
| - loadPromise.then(function() {
|
| - // Mount the volume and save its information in local storage
|
| - // in order to be able to recover the metadata in case of
|
| - // restarts, system crashes, etc.
|
| - chrome.fileSystemProvider.mount({
|
| - fileSystemId: fileSystemId,
|
| - displayName: entry.name,
|
| - openedFilesLimit: 1
|
| - },
|
| - function() {
|
| - if (chrome.runtime.lastError) {
|
| - onError(chrome.runtime.lastError, fileSystemId);
|
| - return;
|
| - }
|
| - // Save state so in case of restarts we are able to correctly
|
| - // get the archive's metadata.
|
| - unpacker.app.saveState_([fileSystemId]);
|
| - onSuccess(fileSystemId);
|
| - });
|
| - }).catch(function(error) {
|
| - onError(error.stack || error, fileSystemId);
|
| - return Promise.reject(error);
|
| - });
|
| -
|
| - unpacker.app.volumeLoadedPromises[fileSystemId] = loadPromise;
|
| - }.bind(null, item.entry));
|
| - });
|
| - })
|
| - .catch(function(error) { console.error(error.stack || error); });
|
| - },
|
| -
|
| - /**
|
| - * Fired when this extension is launched.
|
| - * Calls a module designated by launchData.id.
|
| - * Currently, Verbs API does not support "unpack" option. Thus, any launchData
|
| - * that does not have "pack" as id is regarded as unpack for now.
|
| - * @param {!Object} launchData
|
| - * @param {function(string)=} opt_onSuccess
|
| - * @param {function(string)=} opt_onError
|
| - */
|
| - onLaunched: function(launchData, opt_onSuccess, opt_onError) {
|
| - if (launchData.items == null) {
|
| - // The user tried to launch us directly.
|
| - console.log('Ignoring launch request w/out items field', {launchData});
|
| - return;
|
| - }
|
| -
|
| - if (launchData.id === "pack")
|
| - unpacker.app.onLaunchedWithPack(launchData);
|
| - else
|
| - unpacker.app.onLaunchedWithUnpack(launchData, opt_onSuccess, opt_onError);
|
| - },
|
| -
|
| - /**
|
| - * Saves the state before suspending the event page, so we can resume it
|
| - * once new events arrive.
|
| - */
|
| - onSuspend: function() {
|
| - unpacker.app.saveState_(Object.keys(unpacker.app.volumes));
|
| - }
|
| -};
|
|
|