1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * @param {Object.<string, string>} stringData String data.
7 * @param {VolumeManager} volumeManager Volume manager.
9 function BackgroundComponents(stringData, volumeManager) {
12 * @type {Object.<string, string>}
14 this.stringData = stringData;
18 * @type {VolumeManager}
20 this.volumeManager = volumeManager;
26 * Loads background component.
27 * @return {Promise} Promise fulfilled with BackgroundComponents.
29 BackgroundComponents.load = function() {
30 var stringDataPromise = new Promise(function(fulfill) {
31 chrome.fileManagerPrivate.getStrings(function(stringData) {
32 loadTimeData.data = stringData;
37 // VolumeManager should be obtained after stringData initialized.
38 var volumeManagerPromise = stringDataPromise.then(function() {
39 return new Promise(function(fulfill) {
40 VolumeManager.getInstance(fulfill);
44 return Promise.all([stringDataPromise, volumeManagerPromise]).then(
46 return new BackgroundComponents(args[0], args[1]);
51 * Promise to be fulfilled with singleton instance of background components.
54 var backgroundComponentsPromise = BackgroundComponents.load();
57 * Resolves file system names and obtains entries.
58 * @param {Array.<FileEntry>} entries Names of isolated file system.
59 * @return {Promise} Promise to be fulfilled with an entry array.
61 function resolveEntries(entries) {
62 return new Promise(function(fulfill, reject) {
63 chrome.fileManagerPrivate.resolveIsolatedEntries(
64 entries, function(externalEntries) {
65 if (!chrome.runtime.lastError)
66 fulfill(externalEntries);
68 reject(chrome.runtime.lastError);
74 * Obtains child entries.
75 * @param {DirectoryEntry} entry Directory entry.
76 * @return {Promise} Promise to be fulfilled with child entries.
78 function getChildren(entry) {
79 var reader = entry.createReader();
80 var readEntries = function() {
81 return new Promise(reader.readEntries.bind(reader)).then(function(entries) {
82 if (entries.length === 0)
84 return readEntries().then(function(nextEntries) {
85 return entries.concat(nextEntries);
89 return readEntries().then(function(entries) {
90 return entries.sort(function(a, b) {
91 return a.name.localeCompare(b.name);
97 * Promise to be fulfilled with single application window.
98 * This can be null when the window is not opened.
101 var appWindowPromise = null;
104 * Promise to be fulfilled with entries that are used for reopening the
105 * application window.
108 var reopenEntriesPromsie = null;
111 * Launches the application with entries.
113 * @param {Promise} selectedEntriesPromise Promise to be fulfilled with the
114 * entries that are stored in the external file system (not in the isolated
116 * @return {Promise} Promise to be fulfilled after the application is launched.
118 function launch(selectedEntriesPromise) {
119 // If there is the previous window, close the window.
120 if (appWindowPromise) {
121 reopenEntriesPromsie = selectedEntriesPromise;
122 appWindowPromise.then(function(appWindow) {
125 return Promise.reject('The window has already opened.');
127 reopenEntriesPromsie = null;
129 // Create a new window.
130 appWindowPromise = new Promise(function(fulfill) {
131 chrome.app.window.create(
141 function(appWindow) {
142 appWindow.contentWindow.addEventListener(
143 'load', fulfill.bind(null, appWindow));
144 appWindow.onClosed.addListener(function() {
145 appWindowPromise = null;
146 if (reopenEntriesPromsie)
147 launch(reopenEntriesPromsie);
152 // If only 1 entry is selected, retrieve entries in the same directory.
153 // Otherwise, just use the selectedEntries as an entry set.
154 var allEntriesPromise = selectedEntriesPromise.then(function(entries) {
155 if (entries.length === 1) {
156 var parentPromise = new Promise(entries[0].getParent.bind(entries[0]));
157 return parentPromise.then(getChildren).then(function(entries) {
158 return entries.filter(FileType.isImage);
165 // Initialize the window document.
168 backgroundComponentsPromise,
169 ]).then(function(args) {
170 args[0].contentWindow.initialize(args[1]);
173 selectedEntriesPromise
174 ]).then(function(entries) {
175 args[0].contentWindow.loadEntries(entries[0], entries[1]);
180 chrome.app.runtime.onLaunched.addListener(function(launchData) {
181 // Skip if files are not selected.
182 if (!launchData || !launchData.items || launchData.items.length === 0)
185 // Obtains entries in non-isolated file systems.
186 // The entries in launchData are stored in the isolated file system.
187 // We need to map the isolated entries to the normal entries to retrieve their
189 var isolatedEntries = launchData.items.map(function(item) {
192 var selectedEntriesPromise = backgroundComponentsPromise.then(function() {
193 return resolveEntries(isolatedEntries);
196 launch(selectedEntriesPromise).catch(function(error) {
197 console.error(error.stack || error);
201 // If is is run in the browser test, wait for the test resources are installed
202 // as a component extension, and then load the test resources.
204 /** @type {string} */
205 window.testExtensionId = 'ejhcmmdhhpdhhgmifplfmjobgegbibkn';
206 chrome.runtime.onMessageExternal.addListener(function(message) {
207 if (message.name !== 'testResourceLoaded')
209 var script = document.createElement('script');
211 'chrome-extension://' + window.testExtensionId +
212 '/common/test_loader.js';
213 document.documentElement.appendChild(script);