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.
5 var fileSystemNatives
= requireNative('file_system_natives');
6 var GetIsolatedFileSystem
= fileSystemNatives
.GetIsolatedFileSystem
;
7 var sendRequest
= require('sendRequest');
8 var lastError
= require('lastError');
9 var GetModuleSystem
= requireNative('v8_context').GetModuleSystem
;
10 // TODO(sammc): Don't require extension. See http://crbug.com/235689.
11 var GetExtensionViews
= requireNative('runtime').GetExtensionViews
;
13 // For a given |apiName|, generates object with two elements that are used
14 // in file system relayed APIs:
15 // * 'bindFileEntryCallback' function that provides mapping between JS objects
16 // into actual FileEntry|DirectoryEntry objects.
17 // * 'entryIdManager' object that implements methods for keeping the tracks of
18 // previously saved file entries.
19 function getFileBindingsForApi(apiName
) {
20 // Fallback to using the current window if no background page is running.
21 var backgroundPage
= GetExtensionViews(-1, 'BACKGROUND')[0] || window
;
22 var backgroundPageModuleSystem
= GetModuleSystem(backgroundPage
);
24 // All windows use the bindFileEntryCallback from the background page so their
25 // FileEntry objects have the background page's context as their own. This
26 // allows them to be used from other windows (including the background page)
27 // after the original window is closed.
28 if (window
== backgroundPage
) {
29 var bindFileEntryCallback = function(functionName
, apiFunctions
) {
30 apiFunctions
.setCustomCallback(functionName
,
31 function(name
, request
, callback
, response
) {
41 var getEntryError = function(fileError
) {
45 apiName
+ '.' + functionName
,
46 'Error getting fileEntry, code: ' + fileError
.code
,
52 // Loop through the response entries and asynchronously get the
53 // FileEntry for each. We use hasError to ensure that only the first
54 // error is reported. Note that an error can occur either during the
55 // loop or in the asynchronous error callback to getFile.
56 $Array
.forEach(response
.entries
, function(entry
) {
59 var fileSystemId
= entry
.fileSystemId
;
60 var baseName
= entry
.baseName
;
62 var fs
= GetIsolatedFileSystem(fileSystemId
);
65 var getEntryCallback = function(fileEntry
) {
68 entryIdManager
.registerEntry(id
, fileEntry
);
69 entries
.push(fileEntry
);
70 // Once all entries are ready, pass them to the callback. In the
71 // event of an error, this condition will never be satisfied so
72 // the callback will not be called with any entries.
73 if (entries
.length
== response
.entries
.length
) {
74 if (response
.multiple
) {
75 sendRequest
.safeCallbackApply(
76 apiName
+ '.' + functionName
, request
, callback
,
79 sendRequest
.safeCallbackApply(
80 apiName
+ '.' + functionName
, request
, callback
,
85 // TODO(koz): fs.root.getFile() makes a trip to the browser
86 // process, but it might be possible avoid that by calling
87 // WebDOMFileSystem::createV8Entry().
88 if (entry
.isDirectory
) {
89 fs
.root
.getDirectory(baseName
, {}, getEntryCallback
,
92 fs
.root
.getFile(baseName
, {}, getEntryCallback
, getEntryError
);
97 lastError
.run(apiName
+ '.' + functionName
,
98 'Error getting fileEntry: ' + e
.stack
,
107 var entryIdManager
= require('entryIdManager');
109 // Force the fileSystem API to be loaded in the background page. Using
110 // backgroundPageModuleSystem.require('fileSystem') is insufficient as
111 // requireNative is only allowed while lazily loading an API.
112 backgroundPage
.chrome
.fileSystem
;
113 var bindFileEntryCallback
= backgroundPageModuleSystem
.require(
114 apiName
).bindFileEntryCallback
;
115 var entryIdManager
= backgroundPageModuleSystem
.require('entryIdManager');
117 return {bindFileEntryCallback
: bindFileEntryCallback
,
118 entryIdManager
: entryIdManager
};
121 exports
.getFileBindingsForApi
= getFileBindingsForApi
;