OLD | NEW |
| (Empty) |
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("fileSy
stemMapping", {}); | |
39 this._excludedFoldersSetting = WebInspector.settings.createSetting("workspac
eExcludedFolders", {}); | |
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(defaultWinExclude
dFolders); | |
70 else if (WebInspector.isMac()) | |
71 defaultExcludedFolders = defaultExcludedFolders.concat(defaultMacExclude
dFolders); | |
72 else | |
73 defaultExcludedFolders = defaultExcludedFolders.concat(defaultLinuxExclu
dedFolders); | |
74 var defaultExcludedFoldersPattern = defaultExcludedFolders.join("|"); | |
75 WebInspector.settings.workspaceFolderExcludePattern = WebInspector.settings.
createRegExpSetting("workspaceFolderExcludePattern", defaultExcludedFoldersPatte
rn, WebInspector.isWin() ? "i" : ""); | |
76 /** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.Entry>>}
*/ | |
77 this._fileSystemMappings = {}; | |
78 /** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.Excluded
FolderEntry>>} */ | |
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[fileSystemPat
h]; | |
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.ExcludedFolderEnt
ry(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 ma
tch 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, url
Prefix, pathPrefix); | |
186 this._fileSystemMappings[fileSystemPath].push(entry); | |
187 this._saveToSettings(); | |
188 this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.File
MappingAdded, 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.File
MappingRemoved, 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(fileS
ystemPath, excludedFolderPath); | |
215 this._excludedFolders[fileSystemPath].push(entry); | |
216 this._saveToSettings(); | |
217 this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.Excl
udedFolderAdded, 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.Excl
udedFolderRemoved, 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, pathP
refix) | |
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, pa
th) | |
441 { | |
442 this.fileSystemPath = fileSystemPath; | |
443 this.path = path; | |
444 } | |
OLD | NEW |