2 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * @implements {WebInspector.ProjectDelegate}
34 * @extends {WebInspector.Object}
35 * @param {string} type
37 WebInspector.ContentProviderBasedProjectDelegate = function(type)
40 /** @type {!Object.<string, !WebInspector.ContentProvider>} */
41 this._contentProviders = {};
42 /** @type {!Object.<string, boolean>} */
43 this._isContentScriptMap = {};
46 WebInspector.ContentProviderBasedProjectDelegate.prototype = {
52 // Overriddden by subclasses
67 displayName: function()
69 // Overriddden by subclasses
74 * @param {string} path
75 * @param {function(?Date, ?number)} callback
77 requestMetadata: function(path, callback)
83 * @param {string} path
84 * @param {function(?string)} callback
86 requestFileContent: function(path, callback)
88 var contentProvider = this._contentProviders[path];
89 contentProvider.requestContent(callback);
92 * @param {?string} content
93 * @param {boolean} encoded
94 * @param {string} mimeType
96 function innerCallback(content, encoded, mimeType)
105 canSetFileContent: function()
111 * @param {string} path
112 * @param {string} newContent
113 * @param {function(?string)} callback
115 setFileContent: function(path, newContent, callback)
123 canRename: function()
129 * @param {string} path
130 * @param {string} newName
131 * @param {function(boolean, string=, string=, string=, !WebInspector.ResourceType=)} callback
133 rename: function(path, newName, callback)
135 this.performRename(path, newName, innerCallback.bind(this));
138 * @param {boolean} success
139 * @param {string=} newName
140 * @this {WebInspector.ContentProviderBasedProjectDelegate}
142 function innerCallback(success, newName)
145 this._updateName(path, /** @type {string} */ (newName));
146 callback(success, newName);
151 * @param {string} path
153 refresh: function(path)
158 * @param {string} path
160 excludeFolder: function(path)
165 * @param {string} path
166 * @param {?string} name
167 * @param {string} content
168 * @param {function(?string)} callback
170 createFile: function(path, name, content, callback)
175 * @param {string} path
177 deleteFile: function(path)
186 * @param {string} path
187 * @param {string} newName
188 * @param {function(boolean, string=)} callback
190 performRename: function(path, newName, callback)
196 * @param {string} path
197 * @param {string} newName
199 _updateName: function(path, newName)
202 var copyOfPath = path.split("/");
203 copyOfPath[copyOfPath.length - 1] = newName;
204 var newPath = copyOfPath.join("/");
205 this._contentProviders[newPath] = this._contentProviders[oldPath];
206 delete this._contentProviders[oldPath];
210 * @param {string} path
211 * @param {string} query
212 * @param {boolean} caseSensitive
213 * @param {boolean} isRegex
214 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
216 searchInFileContent: function(path, query, caseSensitive, isRegex, callback)
218 var contentProvider = this._contentProviders[path];
219 contentProvider.searchInContent(query, caseSensitive, isRegex, callback);
223 * @param {!Array.<string>} queries
224 * @param {!Array.<string>} fileQueries
225 * @param {boolean} caseSensitive
226 * @param {boolean} isRegex
227 * @param {!WebInspector.Progress} progress
228 * @param {function(!Array.<string>)} callback
230 findFilesMatchingSearchRequest: function(queries, fileQueries, caseSensitive, isRegex, progress, callback)
233 var paths = Object.keys(this._contentProviders);
234 var totalCount = paths.length;
235 if (totalCount === 0) {
236 // searchInContent should call back later.
237 setTimeout(doneCallback, 0);
242 * @param {string} path
243 * @this {WebInspector.ContentProviderBasedProjectDelegate}
245 function filterOutContentScripts(path)
247 return !this._isContentScriptMap[path];
250 if (!WebInspector.settings.searchInContentScripts.get())
251 paths = paths.filter(filterOutContentScripts.bind(this));
253 var fileRegexes = [];
254 for (var i = 0; i < fileQueries.length; ++i)
255 fileRegexes.push(new RegExp(fileQueries[i], caseSensitive ? "" : "i"));
258 * @param {!string} file
260 function filterOutNonMatchingFiles(file)
262 for (var i = 0; i < fileRegexes.length; ++i) {
263 if (!file.match(fileRegexes[i]))
269 paths = paths.filter(filterOutNonMatchingFiles);
270 var barrier = new CallbackBarrier();
271 progress.setTotalWork(paths.length);
272 for (var i = 0; i < paths.length; ++i)
273 searchInContent.call(this, paths[i], barrier.createCallback(searchInContentCallback.bind(null, paths[i])));
274 barrier.callWhenDone(doneCallback);
277 * @param {string} path
278 * @param {function(boolean)} callback
279 * @this {WebInspector.ContentProviderBasedProjectDelegate}
281 function searchInContent(path, callback)
283 var queriesToRun = queries.slice();
284 searchNextQuery.call(this);
287 * @this {WebInspector.ContentProviderBasedProjectDelegate}
289 function searchNextQuery()
291 if (!queriesToRun.length) {
295 var query = queriesToRun.shift();
296 this._contentProviders[path].searchInContent(query, caseSensitive, isRegex, contentCallback.bind(this));
300 * @param {!Array.<!WebInspector.ContentProvider.SearchMatch>} searchMatches
301 * @this {WebInspector.ContentProviderBasedProjectDelegate}
303 function contentCallback(searchMatches)
305 if (!searchMatches.length) {
309 searchNextQuery.call(this);
314 * @param {string} path
315 * @param {boolean} matches
317 function searchInContentCallback(path, matches)
324 function doneCallback()
332 * @param {!WebInspector.Progress} progress
333 * @param {function()} callback
335 indexContent: function(progress, callback)
337 setTimeout(innerCallback, 0);
339 function innerCallback()
347 * @param {string} parentPath
348 * @param {string} name
349 * @param {string} url
350 * @param {!WebInspector.ContentProvider} contentProvider
351 * @param {boolean} isEditable
352 * @param {boolean=} isContentScript
355 addContentProvider: function(parentPath, name, url, contentProvider, isEditable, isContentScript)
357 var path = parentPath ? parentPath + "/" + name : name;
358 if (this._contentProviders[path])
360 var fileDescriptor = new WebInspector.FileDescriptor(parentPath, name, url, url, contentProvider.contentType(), isEditable, isContentScript);
361 this._contentProviders[path] = contentProvider;
362 this._isContentScriptMap[path] = isContentScript || false;
363 this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileAdded, fileDescriptor);
368 * @param {string} path
370 removeFile: function(path)
372 delete this._contentProviders[path];
373 delete this._isContentScriptMap[path];
374 this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path);
378 * @return {!Object.<string, !WebInspector.ContentProvider>}
380 contentProviders: function()
382 return this._contentProviders;
387 this._contentProviders = {};
388 this._isContentScriptMap = {};
389 this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.Reset, null);
392 __proto__: WebInspector.Object.prototype