Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / ContentProviderBasedProjectDelegate.js
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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
13  * distribution.
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.
17  *
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.
29  */
30
31  /**
32  * @constructor
33  * @implements {WebInspector.ProjectDelegate}
34  * @extends {WebInspector.Object}
35  * @param {string} type
36  */
37 WebInspector.ContentProviderBasedProjectDelegate = function(type)
38 {
39     this._type = type;
40     /** @type {!Object.<string, !WebInspector.ContentProvider>} */
41     this._contentProviders = {};
42     /** @type {!Object.<string, boolean>} */
43     this._isContentScriptMap = {};
44 }
45
46 WebInspector.ContentProviderBasedProjectDelegate.prototype = {
47     /**
48      * @return {string}
49      */
50     id: function()
51     {
52         // Overriddden by subclasses
53         return "";
54     },
55
56     /**
57      * @return {string}
58      */
59     type: function()
60     {
61         return this._type;
62     },
63
64     /**
65      * @return {string}
66      */
67     displayName: function()
68     {
69         // Overriddden by subclasses
70         return "";
71     },
72
73     /**
74      * @param {string} path
75      * @param {function(?Date, ?number)} callback
76      */
77     requestMetadata: function(path, callback)
78     {
79         callback(null, null);
80     },
81
82     /**
83      * @param {string} path
84      * @param {function(?string)} callback
85      */
86     requestFileContent: function(path, callback)
87     {
88         var contentProvider = this._contentProviders[path];
89         contentProvider.requestContent(callback);
90
91         /**
92          * @param {?string} content
93          * @param {boolean} encoded
94          * @param {string} mimeType
95          */
96         function innerCallback(content, encoded, mimeType)
97         {
98             callback(content);
99         }
100     },
101
102     /**
103      * @return {boolean}
104      */
105     canSetFileContent: function()
106     {
107         return false;
108     },
109
110     /**
111      * @param {string} path
112      * @param {string} newContent
113      * @param {function(?string)} callback
114      */
115     setFileContent: function(path, newContent, callback)
116     {
117         callback(null);
118     },
119
120     /**
121      * @return {boolean}
122      */
123     canRename: function()
124     {
125         return false;
126     },
127
128     /**
129      * @param {string} path
130      * @param {string} newName
131      * @param {function(boolean, string=, string=, string=, !WebInspector.ResourceType=)} callback
132      */
133     rename: function(path, newName, callback)
134     {
135         this.performRename(path, newName, innerCallback.bind(this));
136
137         /**
138          * @param {boolean} success
139          * @param {string=} newName
140          * @this {WebInspector.ContentProviderBasedProjectDelegate}
141          */
142         function innerCallback(success, newName)
143         {
144             if (success)
145                 this._updateName(path, /** @type {string} */ (newName));
146             callback(success, newName);
147         }
148     },
149
150     /**
151      * @param {string} path
152      */
153     refresh: function(path)
154     {
155     },
156
157     /**
158      * @param {string} path
159      */
160     excludeFolder: function(path)
161     {
162     },
163
164     /**
165      * @param {string} path
166      * @param {?string} name
167      * @param {string} content
168      * @param {function(?string)} callback
169      */
170     createFile: function(path, name, content, callback)
171     {
172     },
173
174     /**
175      * @param {string} path
176      */
177     deleteFile: function(path)
178     {
179     },
180
181     remove: function()
182     {
183     },
184
185     /**
186      * @param {string} path
187      * @param {string} newName
188      * @param {function(boolean, string=)} callback
189      */
190     performRename: function(path, newName, callback)
191     {
192         callback(false);
193     },
194
195     /**
196      * @param {string} path
197      * @param {string} newName
198      */
199     _updateName: function(path, newName)
200     {
201         var oldPath = path;
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];
207     },
208
209     /**
210      * @param {string} path
211      * @param {string} query
212      * @param {boolean} caseSensitive
213      * @param {boolean} isRegex
214      * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
215      */
216     searchInFileContent: function(path, query, caseSensitive, isRegex, callback)
217     {
218         var contentProvider = this._contentProviders[path];
219         contentProvider.searchInContent(query, caseSensitive, isRegex, callback);
220     },
221
222     /**
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
229      */
230     findFilesMatchingSearchRequest: function(queries, fileQueries, caseSensitive, isRegex, progress, callback)
231     {
232         var result = [];
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);
238             return;
239         }
240
241         /**
242          * @param {string} path
243          * @this {WebInspector.ContentProviderBasedProjectDelegate}
244          */
245         function filterOutContentScripts(path)
246         {
247             return !this._isContentScriptMap[path];
248         }
249
250         if (!WebInspector.settings.searchInContentScripts.get())
251             paths = paths.filter(filterOutContentScripts.bind(this));
252
253         var fileRegexes = [];
254         for (var i = 0; i < fileQueries.length; ++i)
255             fileRegexes.push(new RegExp(fileQueries[i], caseSensitive ? "" : "i"));
256
257         /**
258          * @param {!string} file
259          */
260         function filterOutNonMatchingFiles(file)
261         {
262             for (var i = 0; i < fileRegexes.length; ++i) {
263                 if (!file.match(fileRegexes[i]))
264                     return false;
265             }
266             return true;
267         }
268
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);
275
276         /**
277          * @param {string} path
278          * @param {function(boolean)} callback
279          * @this {WebInspector.ContentProviderBasedProjectDelegate}
280          */
281         function searchInContent(path, callback)
282         {
283             var queriesToRun = queries.slice();
284             searchNextQuery.call(this);
285
286             /**
287              * @this {WebInspector.ContentProviderBasedProjectDelegate}
288              */
289             function searchNextQuery()
290             {
291                 if (!queriesToRun.length) {
292                     callback(true);
293                     return;
294                 }
295                 var query = queriesToRun.shift();
296                 this._contentProviders[path].searchInContent(query, caseSensitive, isRegex, contentCallback.bind(this));
297             }
298
299             /**
300              * @param {!Array.<!WebInspector.ContentProvider.SearchMatch>} searchMatches
301              * @this {WebInspector.ContentProviderBasedProjectDelegate}
302              */
303             function contentCallback(searchMatches)
304             {
305                 if (!searchMatches.length) {
306                     callback(false);
307                     return;
308                 }
309                 searchNextQuery.call(this);
310             }
311         }
312
313         /**
314          * @param {string} path
315          * @param {boolean} matches
316          */
317         function searchInContentCallback(path, matches)
318         {
319             if (matches)
320                 result.push(path);
321             progress.worked(1);
322         }
323
324         function doneCallback()
325         {
326             callback(result);
327             progress.done();
328         }
329     },
330
331     /**
332      * @param {!WebInspector.Progress} progress
333      * @param {function()} callback
334      */
335     indexContent: function(progress, callback)
336     {
337         setTimeout(innerCallback, 0);
338
339         function innerCallback()
340         {
341             progress.done();
342             callback();
343         }
344     },
345
346     /**
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
353      * @return {string}
354      */
355     addContentProvider: function(parentPath, name, url, contentProvider, isEditable, isContentScript)
356     {
357         var path = parentPath ? parentPath + "/" + name : name;
358         if (this._contentProviders[path])
359             return 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);
364         return path;
365     },
366
367     /**
368      * @param {string} path
369      */
370     removeFile: function(path)
371     {
372         delete this._contentProviders[path];
373         delete this._isContentScriptMap[path];
374         this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path);
375     },
376
377     /**
378      * @return {!Object.<string, !WebInspector.ContentProvider>}
379      */
380     contentProviders: function()
381     {
382         return this._contentProviders;
383     },
384
385     reset: function()
386     {
387         this._contentProviders = {};
388         this._isContentScriptMap = {};
389         this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.Reset, null);
390     },
391     
392     __proto__: WebInspector.Object.prototype
393 }