Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/workspace/FileSystemMapping.js

Issue 2529303003: DevTools: move FileSystemMapping from Workspace to Persistence (Closed)
Patch Set: fix tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 * @unrestricted
33 */
34 Workspace.FileSystemMapping = class extends Common.Object {
35 /**
36 * @param {!Workspace.IsolatedFileSystemManager} fileSystemManager
37 */
38 constructor(fileSystemManager) {
39 super();
40 this._fileSystemMappingSetting = Common.settings.createLocalSetting('fileSys temMapping', {});
41 /** @type {!Object.<string, !Array.<!Workspace.FileSystemMapping.Entry>>} */
42 this._fileSystemMappings = {};
43 this._loadFromSettings();
44
45 this._eventListeners = [
46 fileSystemManager.addEventListener(
47 Workspace.IsolatedFileSystemManager.Events.FileSystemAdded, this._file SystemAdded, this),
48 fileSystemManager.addEventListener(
49 Workspace.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fi leSystemRemoved, this),
50 ];
51 fileSystemManager.waitForFileSystems().then(this._fileSystemsLoaded.bind(thi s));
52 }
53
54 /**
55 * @param {!Array<!Workspace.IsolatedFileSystem>} fileSystems
56 */
57 _fileSystemsLoaded(fileSystems) {
58 for (var fileSystem of fileSystems)
59 this._addMappingsForFilesystem(fileSystem);
60 }
61
62 /**
63 * @param {!Common.Event} event
64 */
65 _fileSystemAdded(event) {
66 var fileSystem = /** @type {!Workspace.IsolatedFileSystem} */ (event.data);
67 this._addMappingsForFilesystem(fileSystem);
68 }
69
70 /**
71 * @param {!Workspace.IsolatedFileSystem} fileSystem
72 */
73 _addMappingsForFilesystem(fileSystem) {
74 this.addFileSystem(fileSystem.path());
75
76 var mappings = fileSystem.projectProperty('mappings');
77 for (var i = 0; Array.isArray(mappings) && i < mappings.length; ++i) {
78 var mapping = mappings[i];
79 if (!mapping || typeof mapping !== 'object')
80 continue;
81 var folder = mapping['folder'];
82 var url = mapping['url'];
83 if (typeof folder !== 'string' || typeof url !== 'string')
84 continue;
85 this.addNonConfigurableFileMapping(fileSystem.path(), url, folder);
86 }
87 }
88
89 /**
90 * @param {!Common.Event} event
91 */
92 _fileSystemRemoved(event) {
93 var fileSystem = /** @type {!Workspace.IsolatedFileSystem} */ (event.data);
94 this.removeFileSystem(fileSystem.path());
95 }
96
97 _loadFromSettings() {
98 var savedMapping = this._fileSystemMappingSetting.get();
99 this._fileSystemMappings = {};
100 for (var fileSystemPath in savedMapping) {
101 var savedFileSystemMappings = savedMapping[fileSystemPath];
102 fileSystemPath = Common.ParsedURL.platformPathToURL(fileSystemPath);
103 this._fileSystemMappings[fileSystemPath] = [];
104 var fileSystemMappings = this._fileSystemMappings[fileSystemPath];
105
106 for (var i = 0; i < savedFileSystemMappings.length; ++i) {
107 var savedEntry = savedFileSystemMappings[i];
108 var entry =
109 new Workspace.FileSystemMapping.Entry(fileSystemPath, savedEntry.url Prefix, savedEntry.pathPrefix, true);
110 fileSystemMappings.push(entry);
111 }
112 }
113
114 this._rebuildIndexes();
115 }
116
117 _saveToSettings() {
118 var setting = {};
119 for (var fileSystemPath in this._fileSystemMappings) {
120 setting[fileSystemPath] = [];
121 var entries = this._fileSystemMappings[fileSystemPath];
122 for (var entry of entries) {
123 if (entry.configurable)
124 setting[fileSystemPath].push(entry);
125 }
126 }
127 this._fileSystemMappingSetting.set(setting);
128 }
129
130 _rebuildIndexes() {
131 // We are building an index here to search for the longest url prefix match faster.
132 this._mappingForURLPrefix = {};
133 this._urlPrefixes = [];
134 for (var fileSystemPath in this._fileSystemMappings) {
135 var fileSystemMapping = this._fileSystemMappings[fileSystemPath];
136 for (var i = 0; i < fileSystemMapping.length; ++i) {
137 var entry = fileSystemMapping[i];
138 // Resolve conflict in favor of configurable mapping.
139 if (this._mappingForURLPrefix[entry.urlPrefix] && !entry.configurable)
140 continue;
141 this._mappingForURLPrefix[entry.urlPrefix] = entry;
142 if (this._urlPrefixes.indexOf(entry.urlPrefix) === -1)
143 this._urlPrefixes.push(entry.urlPrefix);
144 }
145 }
146 this._urlPrefixes.sort();
147 }
148
149 /**
150 * @param {string} fileSystemPath
151 */
152 addFileSystem(fileSystemPath) {
153 if (this._fileSystemMappings[fileSystemPath])
154 return;
155
156 this._fileSystemMappings[fileSystemPath] = [];
157 this._saveToSettings();
158 }
159
160 /**
161 * @param {string} fileSystemPath
162 */
163 removeFileSystem(fileSystemPath) {
164 if (!this._fileSystemMappings[fileSystemPath])
165 return;
166 delete this._fileSystemMappings[fileSystemPath];
167 this._rebuildIndexes();
168 this._saveToSettings();
169 }
170
171 /**
172 * @param {string} fileSystemPath
173 * @param {string} urlPrefix
174 * @param {string} pathPrefix
175 */
176 addFileMapping(fileSystemPath, urlPrefix, pathPrefix) {
177 if (!urlPrefix.endsWith('/'))
178 urlPrefix += '/';
179 if (!pathPrefix.endsWith('/'))
180 pathPrefix += '/';
181 if (!pathPrefix.startsWith('/'))
182 pathPrefix = '/' + pathPrefix;
183 this._innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, true);
184 this._saveToSettings();
185 }
186
187 /**
188 * @param {string} fileSystemPath
189 * @param {string} urlPrefix
190 * @param {string} pathPrefix
191 */
192 addNonConfigurableFileMapping(fileSystemPath, urlPrefix, pathPrefix) {
193 this._innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, false);
194 }
195
196 /**
197 * @param {string} fileSystemPath
198 * @param {string} urlPrefix
199 * @param {string} pathPrefix
200 * @param {boolean} configurable
201 */
202 _innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, configurable) {
203 var entry = new Workspace.FileSystemMapping.Entry(fileSystemPath, urlPrefix, pathPrefix, configurable);
204 this._fileSystemMappings[fileSystemPath].push(entry);
205 this._rebuildIndexes();
206 this.dispatchEventToListeners(Workspace.FileSystemMapping.Events.FileMapping Added, entry);
207 }
208
209 /**
210 * @param {string} fileSystemPath
211 * @param {string} urlPrefix
212 * @param {string} pathPrefix
213 */
214 removeFileMapping(fileSystemPath, urlPrefix, pathPrefix) {
215 var entry = this._configurableMappingEntryForPathPrefix(fileSystemPath, path Prefix);
216 if (!entry)
217 return;
218 this._fileSystemMappings[fileSystemPath].remove(entry);
219 this._rebuildIndexes();
220 this._saveToSettings();
221 this.dispatchEventToListeners(Workspace.FileSystemMapping.Events.FileMapping Removed, entry);
222 }
223
224 /**
225 * @param {string} url
226 * @return {?Workspace.FileSystemMapping.Entry}
227 */
228 _mappingEntryForURL(url) {
229 for (var i = this._urlPrefixes.length - 1; i >= 0; --i) {
230 var urlPrefix = this._urlPrefixes[i];
231 if (url.startsWith(urlPrefix))
232 return this._mappingForURLPrefix[urlPrefix];
233 }
234 return null;
235 }
236
237 /**
238 * @param {string} fileSystemPath
239 * @param {string} filePath
240 * @return {?Workspace.FileSystemMapping.Entry}
241 */
242 _mappingEntryForPath(fileSystemPath, filePath) {
243 var entries = this._fileSystemMappings[fileSystemPath];
244 if (!entries)
245 return null;
246
247 var entry = null;
248 for (var i = 0; i < entries.length; ++i) {
249 var pathPrefix = entries[i].pathPrefix;
250 if (entry && entry.configurable && !entries[i].configurable)
251 continue;
252 // We are looking for the longest pathPrefix match.
253 if (entry && entry.pathPrefix.length > pathPrefix.length)
254 continue;
255 if (filePath.startsWith(pathPrefix))
256 entry = entries[i];
257 }
258 return entry;
259 }
260
261 /**
262 * @param {string} fileSystemPath
263 * @param {string} pathPrefix
264 * @return {?Workspace.FileSystemMapping.Entry}
265 */
266 _configurableMappingEntryForPathPrefix(fileSystemPath, pathPrefix) {
267 var entries = this._fileSystemMappings[fileSystemPath];
268 for (var i = 0; i < entries.length; ++i) {
269 if (entries[i].configurable && pathPrefix === entries[i].pathPrefix)
270 return entries[i];
271 }
272 return null;
273 }
274
275 /**
276 * @param {string} fileSystemPath
277 * @return {!Array.<!Workspace.FileSystemMapping.Entry>}
278 */
279 mappingEntries(fileSystemPath) {
280 return this._fileSystemMappings[fileSystemPath].slice();
281 }
282
283 /**
284 * @param {string} url
285 * @return {boolean}
286 */
287 hasMappingForNetworkURL(url) {
288 return !!this._mappingEntryForURL(url);
289 }
290
291 /**
292 * @param {string} url
293 * @return {?{fileSystemPath: string, fileURL: string}}
294 */
295 fileForURL(url) {
296 var entry = this._mappingEntryForURL(url);
297 if (!entry)
298 return null;
299 var file = {};
300 file.fileSystemPath = entry.fileSystemPath;
301 file.fileURL = entry.fileSystemPath + entry.pathPrefix + url.substr(entry.ur lPrefix.length);
302 return file;
303 }
304
305 /**
306 * @param {string} fileSystemPath
307 * @param {string} filePath
308 * @return {string}
309 */
310 networkURLForFileSystemURL(fileSystemPath, filePath) {
311 var relativePath = filePath.substring(fileSystemPath.length);
312 var entry = this._mappingEntryForPath(fileSystemPath, relativePath);
313 if (!entry)
314 return '';
315 return entry.urlPrefix + relativePath.substring(entry.pathPrefix.length);
316 }
317
318 /**
319 * @param {string} url
320 */
321 removeMappingForURL(url) {
322 var entry = this._mappingEntryForURL(url);
323 if (!entry || !entry.configurable)
324 return;
325 this._fileSystemMappings[entry.fileSystemPath].remove(entry);
326 this._saveToSettings();
327 }
328
329 /**
330 * @param {string} url
331 * @param {string} fileSystemPath
332 * @param {string} filePath
333 */
334 addMappingForResource(url, fileSystemPath, filePath) {
335 var commonPathSuffixLength = 0;
336 for (var i = 0; i < filePath.length; ++i) {
337 var filePathCharacter = filePath[filePath.length - 1 - i];
338 var urlCharacter = url[url.length - 1 - i];
339 if (filePathCharacter !== urlCharacter)
340 break;
341 if (filePathCharacter === '/')
342 commonPathSuffixLength = i;
343 }
344 var from = fileSystemPath.length;
345 var to = filePath.length - commonPathSuffixLength;
346 var pathPrefix = filePath.substring(from, to);
347 var urlPrefix = url.substr(0, url.length - commonPathSuffixLength);
348 if (to >= from)
349 this.addFileMapping(fileSystemPath, urlPrefix, pathPrefix);
350 else
351 this.addFileMapping(fileSystemPath, urlPrefix + pathPrefix, '/');
352 }
353
354 resetForTesting() {
355 this._fileSystemMappings = {};
356 }
357
358 dispose() {
359 Common.EventTarget.removeEventListeners(this._eventListeners);
360 }
361 };
362
363 /** @enum {symbol} */
364 Workspace.FileSystemMapping.Events = {
365 FileMappingAdded: Symbol('FileMappingAdded'),
366 FileMappingRemoved: Symbol('FileMappingRemoved')
367 };
368
369 /**
370 * @unrestricted
371 */
372 Workspace.FileSystemMapping.Entry = class {
373 /**
374 * @param {string} fileSystemPath
375 * @param {string} urlPrefix
376 * @param {string} pathPrefix
377 * @param {boolean} configurable
378 */
379 constructor(fileSystemPath, urlPrefix, pathPrefix, configurable) {
380 this.fileSystemPath = fileSystemPath;
381 this.urlPrefix = urlPrefix;
382 this.pathPrefix = pathPrefix;
383 this.configurable = configurable;
384 }
385 };
386
387 /**
388 * @type {!Workspace.FileSystemMapping}
389 */
390 Workspace.fileSystemMapping;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698