Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / renderer / resources / extensions / file_system_custom_bindings.js
blobedd4b335c6931c3e93a84fd3e6afe1061f54a544
1 // Copyright (c) 2012 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 // Custom binding for the fileSystem API.
7 var binding = require('binding').Binding.create('fileSystem');
9 var fileSystemNatives = requireNative('file_system_natives');
10 var GetIsolatedFileSystem = fileSystemNatives.GetIsolatedFileSystem;
11 var lastError = require('lastError');
12 var sendRequest = require('sendRequest').sendRequest;
13 var GetModuleSystem = requireNative('v8_context').GetModuleSystem;
14 // TODO(sammc): Don't require extension. See http://crbug.com/235689.
15 var GetExtensionViews = requireNative('runtime').GetExtensionViews;
17 // Fallback to using the current window if no background page is running.
18 var backgroundPage = GetExtensionViews(-1, 'BACKGROUND')[0] || window;
19 var backgroundPageModuleSystem = GetModuleSystem(backgroundPage);
21 // All windows use the bindFileEntryCallback from the background page so their
22 // FileEntry objects have the background page's context as their own. This
23 // allows them to be used from other windows (including the background page)
24 // after the original window is closed.
25 if (window == backgroundPage) {
26 var bindFileEntryCallback = function(functionName, apiFunctions) {
27 apiFunctions.setCustomCallback(functionName,
28 function(name, request, response) {
29 if (request.callback && response) {
30 var callback = request.callback;
31 request.callback = null;
33 var entries = [];
34 var hasError = false;
36 var getEntryError = function(fileError) {
37 if (!hasError) {
38 hasError = true;
39 lastError.run(
40 'fileSystem.' + functionName,
41 'Error getting fileEntry, code: ' + fileError.code,
42 request.stack,
43 callback);
47 // Loop through the response entries and asynchronously get the
48 // FileEntry for each. We use hasError to ensure that only the first
49 // error is reported. Note that an error can occur either during the
50 // loop or in the asynchronous error callback to getFile.
51 $Array.forEach(response.entries, function(entry) {
52 if (hasError)
53 return;
54 var fileSystemId = entry.fileSystemId;
55 var baseName = entry.baseName;
56 var id = entry.id;
57 var fs = GetIsolatedFileSystem(fileSystemId);
59 try {
60 var getEntryCallback = function(fileEntry) {
61 if (hasError)
62 return;
63 entryIdManager.registerEntry(id, fileEntry);
64 entries.push(fileEntry);
65 // Once all entries are ready, pass them to the callback. In the
66 // event of an error, this condition will never be satisfied so
67 // the callback will not be called with any entries.
68 if (entries.length == response.entries.length) {
69 if (response.multiple) {
70 callback(entries);
71 } else {
72 callback(entries[0]);
76 // TODO(koz): fs.root.getFile() makes a trip to the browser process,
77 // but it might be possible avoid that by calling
78 // WebFrame::createFileEntry().
79 if (entry.isDirectory) {
80 fs.root.getDirectory(baseName, {}, getEntryCallback,
81 getEntryError);
82 } else {
83 fs.root.getFile(baseName, {}, getEntryCallback, getEntryError);
85 } catch (e) {
86 if (!hasError) {
87 hasError = true;
88 lastError.run('fileSystem.' + functionName,
89 'Error getting fileEntry: ' + e.stack,
90 request.stack,
91 callback);
94 });
96 });
98 var entryIdManager = require('entryIdManager');
99 } else {
100 // Force the fileSystem API to be loaded in the background page. Using
101 // backgroundPageModuleSystem.require('fileSystem') is insufficient as
102 // requireNative is only allowed while lazily loading an API.
103 backgroundPage.chrome.fileSystem;
104 var bindFileEntryCallback = backgroundPageModuleSystem.require(
105 'fileSystem').bindFileEntryCallback;
106 var entryIdManager = backgroundPageModuleSystem.require('entryIdManager');
109 binding.registerCustomHook(function(bindingsAPI) {
110 var apiFunctions = bindingsAPI.apiFunctions;
111 var fileSystem = bindingsAPI.compiledApi;
113 function bindFileEntryFunction(functionName) {
114 apiFunctions.setUpdateArgumentsPostValidate(
115 functionName, function(fileEntry, callback) {
116 var fileSystemName = fileEntry.filesystem.name;
117 var relativePath = $String.slice(fileEntry.fullPath, 1);
118 return [fileSystemName, relativePath, callback];
121 $Array.forEach(['getDisplayPath', 'getWritableEntry', 'isWritableEntry'],
122 bindFileEntryFunction);
124 $Array.forEach(['getWritableEntry', 'chooseEntry', 'restoreEntry'],
125 function(functionName) {
126 bindFileEntryCallback(functionName, apiFunctions);
129 apiFunctions.setHandleRequest('retainEntry', function(fileEntry) {
130 var id = entryIdManager.getEntryId(fileEntry);
131 if (!id)
132 return '';
133 var fileSystemName = fileEntry.filesystem.name;
134 var relativePath = $String.slice(fileEntry.fullPath, 1);
136 sendRequest(this.name, [id, fileSystemName, relativePath],
137 this.definition.parameters, {});
138 return id;
141 apiFunctions.setHandleRequest('isRestorable',
142 function(id, callback) {
143 var savedEntry = entryIdManager.getEntryById(id);
144 if (savedEntry) {
145 callback(true);
146 } else {
147 sendRequest(this.name, [id, callback], this.definition.parameters, {});
151 apiFunctions.setUpdateArgumentsPostValidate('restoreEntry',
152 function(id, callback) {
153 var savedEntry = entryIdManager.getEntryById(id);
154 if (savedEntry) {
155 // We already have a file entry for this id so pass it to the callback and
156 // send a request to the browser to move it to the back of the LRU.
157 callback(savedEntry);
158 return [id, false, null];
159 } else {
160 // Ask the browser process for a new file entry for this id, to be passed
161 // to |callback|.
162 return [id, true, callback];
166 // TODO(benwells): Remove these deprecated versions of the functions.
167 fileSystem.getWritableFileEntry = function() {
168 console.log("chrome.fileSystem.getWritableFileEntry is deprecated");
169 console.log("Please use chrome.fileSystem.getWritableEntry instead");
170 $Function.apply(fileSystem.getWritableEntry, this, arguments);
173 fileSystem.isWritableFileEntry = function() {
174 console.log("chrome.fileSystem.isWritableFileEntry is deprecated");
175 console.log("Please use chrome.fileSystem.isWritableEntry instead");
176 $Function.apply(fileSystem.isWritableEntry, this, arguments);
179 fileSystem.chooseFile = function() {
180 console.log("chrome.fileSystem.chooseFile is deprecated");
181 console.log("Please use chrome.fileSystem.chooseEntry instead");
182 $Function.apply(fileSystem.chooseEntry, this, arguments);
186 exports.bindFileEntryCallback = bindFileEntryCallback;
187 exports.binding = binding.generate();