Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / sdk / FileSystemMapping.js
1 /*
2  * Copyright (C) 2012 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  * @extends {WebInspector.Object}
34  */
35 WebInspector.FileSystemMapping = function()
36 {
37     WebInspector.Object.call(this);
38     this._fileSystemMappingSetting = WebInspector.settings.createSetting("fileSystemMapping", {});
39     this._excludedFoldersSetting = WebInspector.settings.createSetting("workspaceExcludedFolders", {});
40     var defaultCommonExcludedFolders = [
41         "/\\.git/",
42         "/\\.sass-cache/",
43         "/\\.hg/",
44         "/\\.idea/",
45         "/\\.svn/",
46         "/\\.cache/",
47         "/\\.project/"
48     ];
49     var defaultWinExcludedFolders = [
50         "/Thumbs.db$",
51         "/ehthumbs.db$",
52         "/Desktop.ini$",
53         "/\\$RECYCLE.BIN/"
54     ];
55     var defaultMacExcludedFolders = [
56         "/\\.DS_Store$",
57         "/\\.Trashes$",
58         "/\\.Spotlight-V100$",
59         "/\\.AppleDouble$",
60         "/\\.LSOverride$",
61         "/Icon$",
62         "/\\._.*$"
63     ];
64     var defaultLinuxExcludedFolders = [
65         "/.*~$"
66     ];
67     var defaultExcludedFolders = defaultCommonExcludedFolders;
68     if (WebInspector.isWin())
69         defaultExcludedFolders = defaultExcludedFolders.concat(defaultWinExcludedFolders);
70     else if (WebInspector.isMac())
71         defaultExcludedFolders = defaultExcludedFolders.concat(defaultMacExcludedFolders);
72     else
73         defaultExcludedFolders = defaultExcludedFolders.concat(defaultLinuxExcludedFolders);
74     var defaultExcludedFoldersPattern = defaultExcludedFolders.join("|");
75     WebInspector.settings.workspaceFolderExcludePattern = WebInspector.settings.createRegExpSetting("workspaceFolderExcludePattern", defaultExcludedFoldersPattern, WebInspector.isWin() ? "i" : "");
76     /** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.Entry>>} */
77     this._fileSystemMappings = {};
78     /** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.ExcludedFolderEntry>>} */
79     this._excludedFolders = {};
80     this._loadFromSettings();
81 }
82
83 WebInspector.FileSystemMapping.Events = {
84     FileMappingAdded: "FileMappingAdded",
85     FileMappingRemoved: "FileMappingRemoved",
86     ExcludedFolderAdded: "ExcludedFolderAdded",
87     ExcludedFolderRemoved: "ExcludedFolderRemoved"
88 }
89
90
91 WebInspector.FileSystemMapping.prototype = {
92     _loadFromSettings: function()
93     {
94         var savedMapping = this._fileSystemMappingSetting.get();
95         this._fileSystemMappings = {};
96         for (var fileSystemPath in savedMapping) {
97             var savedFileSystemMappings = savedMapping[fileSystemPath];
98
99             this._fileSystemMappings[fileSystemPath] = [];
100             var fileSystemMappings = this._fileSystemMappings[fileSystemPath];
101
102             for (var i = 0; i < savedFileSystemMappings.length; ++i) {
103                 var savedEntry = savedFileSystemMappings[i];
104                 var entry = new WebInspector.FileSystemMapping.Entry(savedEntry.fileSystemPath, savedEntry.urlPrefix, savedEntry.pathPrefix);
105                 fileSystemMappings.push(entry);
106             }
107         }
108
109         var savedExcludedFolders = this._excludedFoldersSetting.get();
110         this._excludedFolders = {};
111         for (var fileSystemPath in savedExcludedFolders) {
112             var savedExcludedFoldersForPath = savedExcludedFolders[fileSystemPath];
113
114             this._excludedFolders[fileSystemPath] = [];
115             var excludedFolders = this._excludedFolders[fileSystemPath];
116
117             for (var i = 0; i < savedExcludedFoldersForPath.length; ++i) {
118                 var savedEntry = savedExcludedFoldersForPath[i];
119                 var entry = new WebInspector.FileSystemMapping.ExcludedFolderEntry(savedEntry.fileSystemPath, savedEntry.path);
120                 excludedFolders.push(entry);
121             }
122         }
123
124         this._rebuildIndexes();
125     },
126
127     _saveToSettings: function()
128     {
129         var savedMapping = this._fileSystemMappings;
130         this._fileSystemMappingSetting.set(savedMapping);
131
132         var savedExcludedFolders = this._excludedFolders;
133         this._excludedFoldersSetting.set(savedExcludedFolders);
134
135         this._rebuildIndexes();
136     },
137
138     _rebuildIndexes: function()
139     {
140         // We are building an index here to search for the longest url prefix match faster.
141         this._mappingForURLPrefix = {};
142         this._urlPrefixes = [];
143         for (var fileSystemPath in this._fileSystemMappings) {
144             var fileSystemMapping = this._fileSystemMappings[fileSystemPath];
145             for (var i = 0; i < fileSystemMapping.length; ++i) {
146                 var entry = fileSystemMapping[i];
147                 this._mappingForURLPrefix[entry.urlPrefix] = entry;
148                 this._urlPrefixes.push(entry.urlPrefix);
149             }
150         }
151         this._urlPrefixes.sort();
152     },
153
154     /**
155      * @param {string} fileSystemPath
156      */
157     addFileSystem: function(fileSystemPath)
158     {
159         if (this._fileSystemMappings[fileSystemPath])
160             return;
161
162         this._fileSystemMappings[fileSystemPath] = [];
163         this._saveToSettings();
164     },
165
166     /**
167      * @param {string} fileSystemPath
168      */
169     removeFileSystem: function(fileSystemPath)
170     {
171         if (!this._fileSystemMappings[fileSystemPath])
172             return;
173         delete this._fileSystemMappings[fileSystemPath];
174         delete this._excludedFolders[fileSystemPath];
175         this._saveToSettings();
176     },
177
178     /**
179      * @param {string} fileSystemPath
180      * @param {string} urlPrefix
181      * @param {string} pathPrefix
182      */
183     addFileMapping: function(fileSystemPath, urlPrefix, pathPrefix)
184     {
185         var entry = new WebInspector.FileSystemMapping.Entry(fileSystemPath, urlPrefix, pathPrefix);
186         this._fileSystemMappings[fileSystemPath].push(entry);
187         this._saveToSettings();
188         this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.FileMappingAdded, entry);
189     },
190
191     /**
192      * @param {string} fileSystemPath
193      * @param {string} urlPrefix
194      * @param {string} pathPrefix
195      */
196     removeFileMapping: function(fileSystemPath, urlPrefix, pathPrefix)
197     {
198         var entry = this._mappingEntryForPathPrefix(fileSystemPath, pathPrefix);
199         if (!entry)
200             return;
201         this._fileSystemMappings[fileSystemPath].remove(entry);
202         this._saveToSettings();
203         this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.FileMappingRemoved, entry);
204     },
205
206     /**
207      * @param {string} fileSystemPath
208      * @param {string} excludedFolderPath
209      */
210     addExcludedFolder: function(fileSystemPath, excludedFolderPath)
211     {
212         if (!this._excludedFolders[fileSystemPath])
213             this._excludedFolders[fileSystemPath] = [];
214         var entry = new WebInspector.FileSystemMapping.ExcludedFolderEntry(fileSystemPath, excludedFolderPath);
215         this._excludedFolders[fileSystemPath].push(entry);
216         this._saveToSettings();
217         this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.ExcludedFolderAdded, entry);
218     },
219
220     /**
221      * @param {string} fileSystemPath
222      * @param {string} path
223      */
224     removeExcludedFolder: function(fileSystemPath, path)
225     {
226         var entry = this._excludedFolderEntryForPath(fileSystemPath, path);
227         if (!entry)
228             return;
229         this._excludedFolders[fileSystemPath].remove(entry);
230         this._saveToSettings();
231         this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.ExcludedFolderRemoved, entry);
232     },
233
234     /**
235      * @return {!Array.<string>}
236      */
237     fileSystemPaths: function()
238     {
239         return Object.keys(this._fileSystemMappings);
240     },
241
242     /**
243      * @param {string} url
244      * @return {?WebInspector.FileSystemMapping.Entry}
245      */
246     _mappingEntryForURL: function(url)
247     {
248         for (var i = this._urlPrefixes.length - 1; i >= 0; --i) {
249             var urlPrefix = this._urlPrefixes[i];
250             if (url.startsWith(urlPrefix))
251                 return this._mappingForURLPrefix[urlPrefix];
252         }
253         return null;
254     },
255
256     /**
257      * @param {string} fileSystemPath
258      * @param {string} path
259      * @return {?WebInspector.FileSystemMapping.ExcludedFolderEntry}
260      */
261     _excludedFolderEntryForPath: function(fileSystemPath, path)
262     {
263         var entries = this._excludedFolders[fileSystemPath];
264         if (!entries)
265             return null;
266
267         for (var i = 0; i < entries.length; ++i) {
268             if (entries[i].path === path)
269                 return entries[i];
270         }
271         return null;
272     },
273
274     /**
275      * @param {string} fileSystemPath
276      * @param {string} filePath
277      * @return {?WebInspector.FileSystemMapping.Entry}
278      */
279     _mappingEntryForPath: function(fileSystemPath, filePath)
280     {
281         var entries = this._fileSystemMappings[fileSystemPath];
282         if (!entries)
283             return null;
284
285         var entry = null;
286         for (var i = 0; i < entries.length; ++i) {
287             var pathPrefix = entries[i].pathPrefix;
288             // We are looking for the longest pathPrefix match.
289             if (entry && entry.pathPrefix.length > pathPrefix.length)
290                 continue;
291             if (filePath.startsWith(pathPrefix.substr(1)))
292                 entry = entries[i];
293         }
294         return entry;
295     },
296
297     /**
298      * @param {string} fileSystemPath
299      * @param {string} pathPrefix
300      * @return {?WebInspector.FileSystemMapping.Entry}
301      */
302     _mappingEntryForPathPrefix: function(fileSystemPath, pathPrefix)
303     {
304         var entries = this._fileSystemMappings[fileSystemPath];
305         for (var i = 0; i < entries.length; ++i) {
306             if (pathPrefix === entries[i].pathPrefix)
307                 return entries[i];
308         }
309         return null;
310     },
311
312     /**
313      * @param {string} fileSystemPath
314      * @param {string} folderPath
315      * @return {boolean}
316      */
317     isFileExcluded: function(fileSystemPath, folderPath)
318     {
319         var excludedFolders = this._excludedFolders[fileSystemPath] || [];
320         for (var i = 0; i < excludedFolders.length; ++i) {
321             var entry = excludedFolders[i];
322             if (entry.path === folderPath)
323                 return true;
324         }
325         var regex = WebInspector.settings.workspaceFolderExcludePattern.asRegExp();
326         return regex && regex.test(folderPath);
327     },
328
329     /**
330      * @param {string} fileSystemPath
331      * @return {!Array.<!WebInspector.FileSystemMapping.ExcludedFolderEntry>}
332      */
333     excludedFolders: function(fileSystemPath)
334     {
335         var excludedFolders = this._excludedFolders[fileSystemPath];
336         return excludedFolders ? excludedFolders.slice() : [];
337     },
338
339     /**
340      * @param {string} fileSystemPath
341      * @return {!Array.<!WebInspector.FileSystemMapping.Entry>}
342      */
343     mappingEntries: function(fileSystemPath)
344     {
345         return this._fileSystemMappings[fileSystemPath].slice();
346     },
347
348     /**
349      * @param {string} url
350      * @return {boolean}
351      */
352     hasMappingForURL: function(url)
353     {
354         return !!this._mappingEntryForURL(url);
355     },
356
357     /**
358      * @param {string} url
359      * @return {?{fileSystemPath: string, filePath: string}}
360      */
361     fileForURL: function(url)
362     {
363         var entry = this._mappingEntryForURL(url);
364         if (!entry)
365             return null;
366         var file = {};
367         file.fileSystemPath = entry.fileSystemPath;
368         file.filePath = entry.pathPrefix.substr(1) + url.substr(entry.urlPrefix.length);
369         return file;
370     },
371
372     /**
373      * @param {string} fileSystemPath
374      * @param {string} filePath
375      * @return {string}
376      */
377     urlForPath: function(fileSystemPath, filePath)
378     {
379         var entry = this._mappingEntryForPath(fileSystemPath, filePath);
380         if (!entry)
381             return "";
382         return entry.urlPrefix + filePath.substring(entry.pathPrefix.length - 1);
383     },
384
385     /**
386      * @param {string} url
387      */
388     removeMappingForURL: function(url)
389     {
390         var entry = this._mappingEntryForURL(url);
391         if (!entry)
392             return;
393         this._fileSystemMappings[entry.fileSystemPath].remove(entry);
394         this._saveToSettings();
395     },
396
397     /**
398      * @param {string} url
399      * @param {string} fileSystemPath
400      * @param {string} filePath
401      */
402     addMappingForResource: function(url, fileSystemPath, filePath)
403     {
404         var commonPathSuffixLength = 0;
405         var normalizedFilePath = "/" + filePath;
406         for (var i = 0; i < normalizedFilePath.length; ++i) {
407             var filePathCharacter = normalizedFilePath[normalizedFilePath.length - 1 - i];
408             var urlCharacter = url[url.length - 1 - i];
409             if (filePathCharacter !== urlCharacter)
410                 break;
411             if (filePathCharacter === "/")
412                 commonPathSuffixLength = i;
413         }
414         var pathPrefix = normalizedFilePath.substr(0, normalizedFilePath.length - commonPathSuffixLength);
415         var urlPrefix = url.substr(0, url.length - commonPathSuffixLength);
416         this.addFileMapping(fileSystemPath, urlPrefix, pathPrefix);
417     },
418
419     __proto__: WebInspector.Object.prototype
420 }
421
422 /**
423  * @constructor
424  * @param {string} fileSystemPath
425  * @param {string} urlPrefix
426  * @param {string} pathPrefix
427  */
428 WebInspector.FileSystemMapping.Entry = function(fileSystemPath, urlPrefix, pathPrefix)
429 {
430     this.fileSystemPath = fileSystemPath;
431     this.urlPrefix = urlPrefix;
432     this.pathPrefix = pathPrefix;
433 }
434
435 /**
436  * @constructor
437  * @param {string} fileSystemPath
438  * @param {string} path
439  */
440 WebInspector.FileSystemMapping.ExcludedFolderEntry = function(fileSystemPath, path)
441 {
442     this.fileSystemPath = fileSystemPath;
443     this.path = path;
444 }