blob: 591d466885c2c6a91b8b575088ae332e8b687086 [file] [log] [blame]
// Copyright 2014 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.
/**
* @param {Object.<string, string>} stringData String data.
* @param {VolumeManager} volumeManager Volume manager.
*/
function BackgroundComponents(stringData, volumeManager) {
/**
* String data.
* @type {Object.<string, string>}
*/
this.stringData = stringData;
/**
* Volume manager.
* @type {VolumeManager}
*/
this.volumeManager = volumeManager;
Object.freeze(this);
}
/**
* Loads background component.
* @return {Promise} Promise fulfilled with BackgroundComponents.
*/
BackgroundComponents.load = function() {
var stringDataPromise = new Promise(function(fulfill) {
chrome.fileManagerPrivate.getStrings(function(stringData) {
loadTimeData.data = stringData;
fulfill(stringData);
});
});
// VolumeManager should be obtained after stringData initialized.
var volumeManagerPromise = stringDataPromise.then(function() {
return new Promise(function(fulfill) {
VolumeManager.getInstance(fulfill);
});
});
return Promise.all([stringDataPromise, volumeManagerPromise]).then(
function(args) {
return new BackgroundComponents(args[0], args[1]);
});
};
/**
* Promise to be fulfilled with singleton instance of background components.
* @type {Promise}
*/
var backgroundComponentsPromise = BackgroundComponents.load();
/**
* Resolves file system names and obtains entries.
* @param {Array.<FileEntry>} entries Names of isolated file system.
* @return {Promise} Promise to be fulfilled with an entry array.
*/
function resolveEntries(entries) {
return new Promise(function(fulfill, reject) {
chrome.fileManagerPrivate.resolveIsolatedEntries(
entries, function(externalEntries) {
if (!chrome.runtime.lastError)
fulfill(externalEntries);
else
reject(chrome.runtime.lastError);
});
});
}
/**
* Obtains child entries.
* @param {DirectoryEntry} entry Directory entry.
* @return {Promise} Promise to be fulfilled with child entries.
*/
function getChildren(entry) {
var reader = entry.createReader();
var readEntries = function() {
return new Promise(reader.readEntries.bind(reader)).then(function(entries) {
if (entries.length === 0)
return [];
return readEntries().then(function(nextEntries) {
return entries.concat(nextEntries);
});
});
};
return readEntries().then(function(entries) {
return entries.sort(function(a, b) {
return a.name.localeCompare(b.name);
});
});
}
/**
* Promise to be fulfilled with single application window.
* This can be null when the window is not opened.
* @type {Promise}
*/
var appWindowPromise = null;
/**
* Promise to be fulfilled with entries that are used for reopening the
* application window.
* @type {Promise}
*/
var reopenEntriesPromsie = null;
/**
* Launches the application with entries.
*
* @param {Promise} selectedEntriesPromise Promise to be fulfilled with the
* entries that are stored in the external file system (not in the isolated
* file system).
* @return {Promise} Promise to be fulfilled after the application is launched.
*/
function launch(selectedEntriesPromise) {
// If there is the previous window, close the window.
if (appWindowPromise) {
reopenEntriesPromsie = selectedEntriesPromise;
appWindowPromise.then(function(appWindow) {
appWindow.close();
});
return Promise.reject('The window has already opened.');
}
reopenEntriesPromsie = null;
// Create a new window.
appWindowPromise = new Promise(function(fulfill) {
chrome.app.window.create(
'gallery.html',
{
id: 'gallery',
innerBounds: {
minWidth: 820,
minHeight: 544
},
frame: 'none'
},
function(appWindow) {
appWindow.contentWindow.addEventListener(
'load', fulfill.bind(null, appWindow));
appWindow.onClosed.addListener(function() {
appWindowPromise = null;
if (reopenEntriesPromsie)
launch(reopenEntriesPromsie);
});
});
});
// If only 1 entry is selected, retrieve entries in the same directory.
// Otherwise, just use the selectedEntries as an entry set.
var allEntriesPromise = selectedEntriesPromise.then(function(entries) {
if (entries.length === 1) {
var parentPromise = new Promise(entries[0].getParent.bind(entries[0]));
return parentPromise.then(getChildren).then(function(entries) {
return entries.filter(FileType.isImage);
});
} else {
return entries;
}
});
// Initialize the window document.
return Promise.all([
appWindowPromise,
backgroundComponentsPromise,
]).then(function(args) {
args[0].contentWindow.initialize(args[1]);
return Promise.all([
allEntriesPromise,
selectedEntriesPromise
]).then(function(entries) {
args[0].contentWindow.loadEntries(entries[0], entries[1]);
});
});
}
chrome.app.runtime.onLaunched.addListener(function(launchData) {
// Skip if files are not selected.
if (!launchData || !launchData.items || launchData.items.length === 0)
return;
// Obtains entries in non-isolated file systems.
// The entries in launchData are stored in the isolated file system.
// We need to map the isolated entries to the normal entries to retrieve their
// parent directory.
var isolatedEntries = launchData.items.map(function(item) {
return item.entry;
});
var selectedEntriesPromise = backgroundComponentsPromise.then(function() {
return resolveEntries(isolatedEntries);
});
launch(selectedEntriesPromise).catch(function(error) {
console.error(error.stack || error);
});
});
// If is is run in the browser test, wait for the test resources are installed
// as a component extension, and then load the test resources.
if (chrome.test) {
/** @type {string} */
window.testExtensionId = 'ejhcmmdhhpdhhgmifplfmjobgegbibkn';
chrome.runtime.onMessageExternal.addListener(function(message) {
if (message.name !== 'testResourceLoaded')
return;
var script = document.createElement('script');
script.src =
'chrome-extension://' + window.testExtensionId +
'/common/test_loader.js';
document.documentElement.appendChild(script);
});
}