Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / file_manager / gallery / js / background.js
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.
4
5 /**
6  * @param {Object.<string, string>} stringData String data.
7  * @param {VolumeManager} volumeManager Volume manager.
8  */
9 function BackgroundComponents(stringData, volumeManager) {
10   /**
11    * String data.
12    * @type {Object.<string, string>}
13    */
14   this.stringData = stringData;
15
16   /**
17    * Volume manager.
18    * @type {VolumeManager}
19    */
20   this.volumeManager = volumeManager;
21
22   Object.freeze(this);
23 }
24
25 /**
26  * Loads background component.
27  * @return {Promise} Promise fulfilled with BackgroundComponents.
28  */
29 BackgroundComponents.load = function() {
30   var stringDataPromise = new Promise(function(fulfill) {
31     chrome.fileManagerPrivate.getStrings(function(stringData) {
32       loadTimeData.data = stringData;
33       fulfill(stringData);
34     });
35   });
36
37   // VolumeManager should be obtained after stringData initialized.
38   var volumeManagerPromise = stringDataPromise.then(function() {
39     return new Promise(function(fulfill) {
40       VolumeManager.getInstance(fulfill);
41     });
42   });
43
44   return Promise.all([stringDataPromise, volumeManagerPromise]).then(
45       function(args) {
46         return new BackgroundComponents(args[0], args[1]);
47       });
48 };
49
50 /**
51  * Promise to be fulfilled with singleton instance of background components.
52  * @type {Promise}
53  */
54 var backgroundComponentsPromise = BackgroundComponents.load();
55
56 /**
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.
60  */
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);
67           else
68             reject(chrome.runtime.lastError);
69         });
70   });
71 }
72
73 /**
74  * Obtains child entries.
75  * @param {DirectoryEntry} entry Directory entry.
76  * @return {Promise} Promise to be fulfilled with child entries.
77  */
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)
83         return [];
84       return readEntries().then(function(nextEntries) {
85         return entries.concat(nextEntries);
86       });
87     });
88   };
89   return readEntries().then(function(entries) {
90     return entries.sort(function(a, b) {
91       return a.name.localeCompare(b.name);
92     });
93   });
94 }
95
96 /**
97  * Promise to be fulfilled with single application window.
98  * This can be null when the window is not opened.
99  * @type {Promise}
100  */
101 var appWindowPromise = null;
102
103 /**
104  * Promise to be fulfilled with entries that are used for reopening the
105  * application window.
106  * @type {Promise}
107  */
108 var reopenEntriesPromsie = null;
109
110 /**
111  * Launches the application with entries.
112  *
113  * @param {Promise} selectedEntriesPromise Promise to be fulfilled with the
114  *     entries that are stored in the external file system (not in the isolated
115  *     file system).
116  * @return {Promise} Promise to be fulfilled after the application is launched.
117  */
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) {
123       appWindow.close();
124     });
125     return Promise.reject('The window has already opened.');
126   }
127   reopenEntriesPromsie = null;
128
129   // Create a new window.
130   appWindowPromise = new Promise(function(fulfill) {
131     chrome.app.window.create(
132         'gallery.html',
133         {
134           id: 'gallery',
135           innerBounds: {
136             minWidth: 820,
137             minHeight: 544
138           },
139           frame: 'none'
140         },
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);
148           });
149         });
150   });
151
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);
159       });
160     } else {
161       return entries;
162     }
163   });
164
165   // Initialize the window document.
166   return Promise.all([
167     appWindowPromise,
168     backgroundComponentsPromise,
169   ]).then(function(args) {
170     args[0].contentWindow.initialize(args[1]);
171     return Promise.all([
172       allEntriesPromise,
173       selectedEntriesPromise
174     ]).then(function(entries) {
175       args[0].contentWindow.loadEntries(entries[0], entries[1]);
176     });
177   });
178 }
179
180 chrome.app.runtime.onLaunched.addListener(function(launchData) {
181   // Skip if files are not selected.
182   if (!launchData || !launchData.items || launchData.items.length === 0)
183     return;
184
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
188   // parent directory.
189   var isolatedEntries = launchData.items.map(function(item) {
190     return item.entry;
191   });
192   var selectedEntriesPromise = backgroundComponentsPromise.then(function() {
193     return resolveEntries(isolatedEntries);
194   });
195
196   launch(selectedEntriesPromise).catch(function(error) {
197     console.error(error.stack || error);
198   });
199 });
200
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.
203 if (chrome.test) {
204   /** @type {string} */
205   window.testExtensionId = 'ejhcmmdhhpdhhgmifplfmjobgegbibkn';
206   chrome.runtime.onMessageExternal.addListener(function(message) {
207     if (message.name !== 'testResourceLoaded')
208       return;
209     var script = document.createElement('script');
210     script.src =
211         'chrome-extension://' + window.testExtensionId +
212         '/common/test_loader.js';
213     document.documentElement.appendChild(script);
214   });
215 }