Commit 12618036 authored by yoshiki's avatar yoshiki Committed by Commit bot

[Gallery app] Make the background page use BackgroundBase class

This is a cleanup and should change no functionality. See the issue for detail.

BUG=442214
TEST=browser_test passes
R=fukino@chromium.org

Review URL: https://codereview.chromium.org/921043004

Cr-Commit-Position: refs/heads/master@{#317031}
parent ebf70947
......@@ -11,14 +11,9 @@
function GalleryWindow() {}
/**
* @param {!BackgroundComponents} backgroundComponents Background components.
* @type {Promise}
*/
window.initialize = function(backgroundComponents) {};
/**
* @param {!Array.<!Entry>} entries Array of entries.
*/
window.loadEntries = function(entries) {};
window.initializePromise;
/**
* This definition is required by
......
......@@ -775,7 +775,7 @@ util.entriesToURLs = function(entries) {
* Converts array of URLs to an array of corresponding Entries.
*
* @param {Array.<string>} urls Input array of URLs.
* @param {function(Array.<Entry>, Array.<URL>)=} opt_callback Completion
* @param {function(!Array.<!Entry>, !Array.<!URL>)=} opt_callback Completion
* callback with array of success Entries and failure URLs.
* @return {Promise} Promise fulfilled with the object that has entries property
* and failureUrls property. The promise is never rejected.
......
......@@ -3,172 +3,132 @@
// found in the LICENSE file.
/**
* @param {!Object.<string, string>} stringData String data.
* @param {!VolumeManager} volumeManager Volume manager.
* @constructor
* @struct
* Configuration of the Gallery window.
* @const
* @type {Object}
*/
function BackgroundComponents(stringData, volumeManager) {
/**
* String data.
* @type {!Object.<string, string>}
*/
this.stringData = stringData;
/**
* Volume manager.
* @type {!VolumeManager}
*/
this.volumeManager = volumeManager;
}
var windowCreateOptions = {
id: 'gallery',
innerBounds: {
minWidth: 820,
minHeight: 554
},
frame: 'none'
};
/**
* Loads background component.
* @return {!Promise} Promise fulfilled with BackgroundComponents.
* Backgound object. This is necessary for AppWindowWrapper.
* @type {!BackgroundBase}
*/
BackgroundComponents.load = function() {
var stringDataPromise = new Promise(function(fulfill) {
chrome.fileManagerPrivate.getStrings(function(stringData) {
loadTimeData.data = stringData;
fulfill(stringData);
});
});
var background = new BackgroundBase();
// 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]);
});
};
/**
* 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);
});
// Initializes the strings. This needs for the volume manager.
var loadTimeDataPromise = new Promise(function(fulfill, reject) {
chrome.fileManagerPrivate.getStrings(function(stringData) {
loadTimeData.data = stringData;
fulfill(true);
});
}
});
/**
* Promise to be fulfilled with singleton instance of background components.
* @type {Promise}
*/
var backgroundComponentsPromise = null;
// Initializes the volume manager. This needs for isolated entries.
var volumeManagerPromise = new Promise(function(fulfill, reject) {
VolumeManager.getInstance(fulfill);
});
/**
* Promise to be fulfilled with single application window.
* This can be null when the window is not opened.
* @type {Promise}
* Queue to serialize initialization.
* @type {!Promise}
*/
var appWindowPromise = null;
window.initializePromise = Promise.all([loadTimeDataPromise,
volumeManagerPromise]);
/**
* Promise to be fulfilled with entries that are used for reopening the
* application window.
* @type {Promise}
*/
var reopenEntriesPromise = null;
// Registers the handlers.
chrome.app.runtime.onLaunched.addListener(onLaunched);
/**
* Launches the application with entries.
* Called when an app is launched.
*
* @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.
* @param {!Object} launchData Launch data. See the manual of chrome.app.runtime
* .onLaunched for detail.
*/
function launch(selectedEntriesPromise) {
// If there is the previous window, close the window.
if (appWindowPromise) {
reopenEntriesPromise = selectedEntriesPromise;
appWindowPromise.then(function(appWindow) {
appWindow.close();
});
return Promise.reject('The window has already opened.');
}
reopenEntriesPromise = 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 (reopenEntriesPromise) {
// TODO(hirono): This is workaround for crbug.com/442217. Remove
// this after fixing it.
setTimeout(function() {
if (reopenEntriesPromise)
launch(reopenEntriesPromise);
}, 500);
}
});
});
});
function onLaunched(launchData) {
// Skip if files are not selected.
if (!launchData || !launchData.items || launchData.items.length == 0)
return;
// Initialize the window document.
return Promise.all([
appWindowPromise,
backgroundComponentsPromise
]).then(function(args) {
var appWindow = /** @type {!chrome.app.window.AppWindow} */ (args[0]);
var galleryWindow = /** @type {!GalleryWindow} */ (appWindow.contentWindow);
galleryWindow.initialize(args[1]);
return selectedEntriesPromise.then(function(entries) {
galleryWindow.loadEntries(entries);
window.initializePromise.then(function() {
var isolatedEntries = launchData.items.map(function(item) {
return item.entry;
});
});
}
// If the script is loaded from unit test, chrome.app.runtime is not defined.
// In this case, does not run the initialization code for the application.
if (chrome.app.runtime) {
backgroundComponentsPromise = BackgroundComponents.load();
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);
});
chrome.fileManagerPrivate.resolveIsolatedEntries(
isolatedEntries,
function(externalEntries) {
var urls = util.entriesToURLs(externalEntries);
openGalleryWindow(urls, false);
});
});
}
/**
* Returns a function to generate an ID for window.
* @type {function():string} Function which returns an unique id.
*/
var generateWindowId = (function() {
var seq = 0;
return function() {
return 'GALLERY_' + seq++;
};
})();
launch(selectedEntriesPromise).catch(function(error) {
console.error(error.stack || error);
/**
* Opens gallery window.
* @param {!Array.<string>} urls List of URL to show.
* @param {boolean} reopen True if reopen, false otherwise.
* @return {!Promise} Promise to be fulfilled on success, or rejected on error.
*/
function openGalleryWindow(urls, reopen) {
return new Promise(function(fulfill, reject) {
util.URLsToEntries(urls).then(function(result) {
fulfill(util.entriesToURLs(result.entries));
}).catch(reject);
}).then(function(urls) {
if (urls.length === 0)
return Promise.reject('No file to open.');
var windowId = generateWindowId();
// Opens a window.
return new Promise(function(fulfill, reject) {
var gallery = new AppWindowWrapper('gallery.html',
windowId,
windowCreateOptions);
gallery.launch(
{urls: urls},
reopen,
fulfill.bind(null, gallery));
}).then(function(gallery) {
var galleryDocument = gallery.rawAppWindow.contentWindow.document;
if (galleryDocument.readyState == 'complete')
return gallery;
return new Promise(function(fulfill, reject) {
galleryDocument.addEventListener(
'DOMContentLoaded', fulfill.bind(null, gallery));
});
});
}).then(function(gallery) {
gallery.rawAppWindow.focus();
return gallery.rawAppWindow;
}).catch(function(error) {
console.error('Launch failed' + error.stack || error);
return Promise.reject(error);
});
}
......
......@@ -20,6 +20,8 @@
'../../file_manager/common/js/volume_manager_common.js',
'../../file_manager/common/js/error_util.js',
'../../file_manager/common/js/file_type.js',
'../../file_manager/background/js/app_window_wrapper.js',
'../../file_manager/background/js/background_base.js',
'../../file_manager/background/js/volume_manager.js',
],
'externs': [
......@@ -55,6 +57,7 @@
'../../../webui/resources/js/cr/ui/list_selection_controller.js',
'../../../webui/resources/js/cr/ui/list.js',
'../../../webui/resources/js/cr/ui/grid.js',
'../../../webui/resources/js/i18n_template_no_process.js',
'../../file_manager/common/js/volume_manager_common.js',
'../../file_manager/common/js/lru_cache.js',
'../../file_manager/common/js/async_util.js',
......
......@@ -283,7 +283,7 @@ Gallery.prototype.initToolbarButton_ = function(className, title) {
/**
* Loads the content.
*
* @param {!Array.<Entry>} selectedEntries Array of selected entries.
* @param {!Array.<!Entry>} selectedEntries Array of selected entries.
*/
Gallery.prototype.load = function(selectedEntries) {
GalleryUtil.createEntrySet(selectedEntries).then(function(allEntries) {
......@@ -294,8 +294,8 @@ Gallery.prototype.load = function(selectedEntries) {
/**
* Loads the content.
*
* @param {!Array.<Entry>} entries Array of entries.
* @param {!Array.<Entry>} selectedEntries Array of selected entries.
* @param {!Array.<!Entry>} entries Array of entries.
* @param {!Array.<!Entry>} selectedEntries Array of selected entries.
* @private
*/
Gallery.prototype.loadInternal_ = function(entries, selectedEntries) {
......@@ -908,25 +908,56 @@ Gallery.prototype.debugMe = function() {
var gallery = null;
/**
* Initialize the window.
* @param {!BackgroundComponents} backgroundComponents Background components.
* Promise to initialize the load time data.
* @type {!Promise}
*/
window.initialize = function(backgroundComponents) {
window.loadTimeData.data = backgroundComponents.stringData;
gallery = new Gallery(backgroundComponents.volumeManager);
};
var loadTimeDataPromise = new Promise(function(fulfill, reject) {
chrome.fileManagerPrivate.getStrings(function(strings) {
window.loadTimeData.data = strings;
i18nTemplate.process(document, loadTimeData);
fulfill(true);
});
});
/**
* Loads entries.
* @param {!Array.<Entry>} selectedEntries Array of selected entries.
* Promise to initialize volume manager.
* @type {!Promise}
*/
window.loadEntries = function(selectedEntries) {
gallery.load(selectedEntries);
};
var volumeManagerPromise = new Promise(function(fulfill, reject) {
var volumeManager = new VolumeManagerWrapper(
VolumeManagerWrapper.DriveEnabledStatus.DRIVE_ENABLED);
volumeManager.ensureInitialized(fulfill.bind(null, volumeManager));
});
/**
* Promise to initialize both the volume manager and the load time data.
* @type {!Promise}
*/
var initializePromise =
Promise.all([loadTimeDataPromise, volumeManagerPromise]).
then(function(args) {
var volumeManager = args[1];
var gallery = new Gallery(volumeManager);
return gallery;
});
// Loads entries.
initializePromise.then(
/**
* Loads entries.
* @param {!Gallery} gallery The gallery instance.
*/
function(gallery) {
util.URLsToEntries(window.appState.urls, function(entries) {
gallery.load(entries);
});
});
/**
* Enteres the debug mode.
*/
window.debugMe = function() {
gallery.debugMe();
initializePromise.then(function(gallery) {
gallery.debugMe();
});
};
......@@ -19,6 +19,7 @@
//<include src="../../../webui/resources/js/util.js">
//<include src="../../../webui/resources/js/event_tracker.js">
//<include src="../../../webui/resources/js/load_time_data.js">
//<include src="../../../webui/resources/js/i18n_template_no_process.js">
//<include src="../../../webui/resources/js/cr/ui.js">
//<include src="../../../webui/resources/js/cr/event_target.js">
......
......@@ -52,10 +52,12 @@
// util.js and async_util.js should be included before volume_manager.js.
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/util.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/async_util.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/file_type.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/volume_manager_common.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/background/js/app_window_wrapper.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/background/js/background_base.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/background/js/test_util_base.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/background/js/volume_manager.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/error_util.js",
"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/file_type.js",
"js/background.js"
]
},
......
......@@ -119,10 +119,13 @@ function launchWithTestEntries(
selectedEntries.map(function(entry) { return entry.nameText; }));
});
return launch(entriesPromise).then(function() {
var launchedPromise = Promise.all([appWindowPromise, entriesPromise]);
return launchedPromise.then(function(results) {
return {appWindow: results[0], entries: results[1]};
return entriesPromise.then(function(entries) {
return window.initializePromise.then(function() {
var urls = util.entriesToURLs(entries);
var launchedPromise = openGalleryWindow(urls, false);
return launchedPromise.then(function(appWindow) {
return {appWindow: appWindow, entries: entries};
});
});
});
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment