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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/persistence/Automapping.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4
5 /** 4 /**
6 * @constructor 5 * @unrestricted
7 * @param {!WebInspector.Workspace} workspace
8 * @param {function(!WebInspector.PersistenceBinding)} onBindingCreated
9 * @param {function(!WebInspector.PersistenceBinding)} onBindingRemoved
10 */ 6 */
11 WebInspector.Automapping = function(workspace, onBindingCreated, onBindingRemove d) 7 WebInspector.Automapping = class {
12 { 8 /**
9 * @param {!WebInspector.Workspace} workspace
10 * @param {function(!WebInspector.PersistenceBinding)} onBindingCreated
11 * @param {function(!WebInspector.PersistenceBinding)} onBindingRemoved
12 */
13 constructor(workspace, onBindingCreated, onBindingRemoved) {
13 this._workspace = workspace; 14 this._workspace = workspace;
14 15
15 this._onBindingCreated = onBindingCreated; 16 this._onBindingCreated = onBindingCreated;
16 this._onBindingRemoved = onBindingRemoved; 17 this._onBindingRemoved = onBindingRemoved;
17 /** @type {!Set<!WebInspector.PersistenceBinding>} */ 18 /** @type {!Set<!WebInspector.PersistenceBinding>} */
18 this._bindings = new Set(); 19 this._bindings = new Set();
19 20
20 /** @type {!Map<string, !WebInspector.UISourceCode>} */ 21 /** @type {!Map<string, !WebInspector.UISourceCode>} */
21 this._fileSystemUISourceCodes = new Map(); 22 this._fileSystemUISourceCodes = new Map();
22 this._sweepThrottler = new WebInspector.Throttler(100); 23 this._sweepThrottler = new WebInspector.Throttler(100);
23 24
24 var pathEncoder = new WebInspector.Automapping.PathEncoder(); 25 var pathEncoder = new WebInspector.Automapping.PathEncoder();
25 this._filesIndex = new WebInspector.Automapping.FilePathIndex(pathEncoder); 26 this._filesIndex = new WebInspector.Automapping.FilePathIndex(pathEncoder);
26 this._projectFoldersIndex = new WebInspector.Automapping.FolderIndex(pathEnc oder); 27 this._projectFoldersIndex = new WebInspector.Automapping.FolderIndex(pathEnc oder);
27 this._activeFoldersIndex = new WebInspector.Automapping.FolderIndex(pathEnco der); 28 this._activeFoldersIndex = new WebInspector.Automapping.FolderIndex(pathEnco der);
28 29
29 this._eventListeners = [ 30 this._eventListeners = [
30 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceC odeAdded, event => this._onUISourceCodeAdded(/** @type {!WebInspector.UISourceCo de} */(event.data))), 31 this._workspace.addEventListener(
31 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceC odeRemoved, event => this._onUISourceCodeRemoved(/** @type {!WebInspector.UISour ceCode} */(event.data))), 32 WebInspector.Workspace.Events.UISourceCodeAdded,
32 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectAd ded, event => this._onProjectAdded(/** @type {!WebInspector.Project} */(event.da ta)), this), 33 event => this._onUISourceCodeAdded(/** @type {!WebInspector.UISourceCo de} */ (event.data))),
33 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRe moved, event => this._onProjectRemoved(/** @type {!WebInspector.Project} */(even t.data)), this), 34 this._workspace.addEventListener(
35 WebInspector.Workspace.Events.UISourceCodeRemoved,
36 event => this._onUISourceCodeRemoved(/** @type {!WebInspector.UISource Code} */ (event.data))),
37 this._workspace.addEventListener(
38 WebInspector.Workspace.Events.ProjectAdded,
39 event => this._onProjectAdded(/** @type {!WebInspector.Project} */ (ev ent.data)), this),
40 this._workspace.addEventListener(
41 WebInspector.Workspace.Events.ProjectRemoved,
42 event => this._onProjectRemoved(/** @type {!WebInspector.Project} */ ( event.data)), this),
34 ]; 43 ];
35 44
36 for (var fileSystem of workspace.projects()) 45 for (var fileSystem of workspace.projects())
37 this._onProjectAdded(fileSystem); 46 this._onProjectAdded(fileSystem);
38 for (var uiSourceCode of workspace.uiSourceCodes()) 47 for (var uiSourceCode of workspace.uiSourceCodes())
39 this._onUISourceCodeAdded(uiSourceCode); 48 this._onUISourceCodeAdded(uiSourceCode);
40 }; 49 }
41 50
42 WebInspector.Automapping._binding = Symbol("Automapping.Binding"); 51 _scheduleRemap() {
43 WebInspector.Automapping._processingPromise = Symbol("Automapping.ProcessingProm ise"); 52 for (var binding of this._bindings.valuesArray())
44 WebInspector.Automapping._metadata = Symbol("Automapping.Metadata"); 53 this._unbindNetwork(binding.network);
45 54 this._scheduleSweep();
46 WebInspector.Automapping.prototype = { 55 }
47 _scheduleRemap: function() 56
48 { 57 _scheduleSweep() {
49 for (var binding of this._bindings.valuesArray()) 58 this._sweepThrottler.schedule(sweepUnmapped.bind(this));
50 this._unbindNetwork(binding.network);
51 this._scheduleSweep();
52 },
53
54 _scheduleSweep: function()
55 {
56 this._sweepThrottler.schedule(sweepUnmapped.bind(this));
57
58 /**
59 * @this {WebInspector.Automapping}
60 * @return {!Promise}
61 */
62 function sweepUnmapped()
63 {
64 var networkProjects = this._workspace.projectsForType(WebInspector.p rojectTypes.Network);
65 for (var networkProject of networkProjects) {
66 for (var uiSourceCode of networkProject.uiSourceCodes())
67 this._bindNetwork(uiSourceCode);
68 }
69 this._onSweepHappenedForTest();
70 return Promise.resolve();
71 }
72 },
73
74 _onSweepHappenedForTest: function() { },
75 59
76 /** 60 /**
77 * @param {!WebInspector.Project} project 61 * @this {WebInspector.Automapping}
78 */
79 _onProjectRemoved: function(project)
80 {
81 for (var uiSourceCode of project.uiSourceCodes())
82 this._onUISourceCodeRemoved(uiSourceCode);
83 if (project.type() !== WebInspector.projectTypes.FileSystem)
84 return;
85 var fileSystem = /** @type {!WebInspector.FileSystemWorkspaceBinding.Fil eSystem} */(project);
86 for (var gitFolder of fileSystem.gitFolders())
87 this._projectFoldersIndex.removeFolder(gitFolder);
88 this._projectFoldersIndex.removeFolder(fileSystem.fileSystemPath());
89 this._scheduleRemap();
90 },
91
92 /**
93 * @param {!WebInspector.Project} project
94 */
95 _onProjectAdded: function(project)
96 {
97 if (project.type() !== WebInspector.projectTypes.FileSystem)
98 return;
99 var fileSystem = /** @type {!WebInspector.FileSystemWorkspaceBinding.Fil eSystem} */(project);
100 for (var gitFolder of fileSystem.gitFolders())
101 this._projectFoldersIndex.addFolder(gitFolder);
102 this._projectFoldersIndex.addFolder(fileSystem.fileSystemPath());
103 this._scheduleRemap();
104 },
105
106 /**
107 * @param {!WebInspector.UISourceCode} uiSourceCode
108 */
109 _onUISourceCodeAdded: function(uiSourceCode)
110 {
111 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSyst em) {
112 this._filesIndex.addPath(uiSourceCode.url());
113 this._fileSystemUISourceCodes.set(uiSourceCode.url(), uiSourceCode);
114 this._scheduleSweep();
115 } else if (uiSourceCode.project().type() === WebInspector.projectTypes.N etwork) {
116 this._bindNetwork(uiSourceCode);
117 }
118 },
119
120 /**
121 * @param {!WebInspector.UISourceCode} uiSourceCode
122 */
123 _onUISourceCodeRemoved: function(uiSourceCode)
124 {
125 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSyst em) {
126 this._filesIndex.removePath(uiSourceCode.url());
127 this._fileSystemUISourceCodes.delete(uiSourceCode.url());
128 var binding = uiSourceCode[WebInspector.Automapping._binding];
129 if (binding)
130 this._unbindNetwork(binding.network);
131 } else if (uiSourceCode.project().type() === WebInspector.projectTypes.N etwork) {
132 this._unbindNetwork(uiSourceCode);
133 }
134 },
135
136 /**
137 * @param {!WebInspector.UISourceCode} networkSourceCode
138 */
139 _bindNetwork: function(networkSourceCode)
140 {
141 if (networkSourceCode[WebInspector.Automapping._processingPromise] || ne tworkSourceCode[WebInspector.Automapping._binding])
142 return;
143 var createBindingPromise = this._createBinding(networkSourceCode).then(o nBinding.bind(this));
144 networkSourceCode[WebInspector.Automapping._processingPromise] = createB indingPromise;
145
146 /**
147 * @param {?WebInspector.PersistenceBinding} binding
148 * @this {WebInspector.Automapping}
149 */
150 function onBinding(binding)
151 {
152 if (networkSourceCode[WebInspector.Automapping._processingPromise] ! == createBindingPromise)
153 return;
154 networkSourceCode[WebInspector.Automapping._processingPromise] = nul l;
155 if (!binding) {
156 this._onBindingFailedForTest();
157 return;
158 }
159
160 this._bindings.add(binding);
161 binding.network[WebInspector.Automapping._binding] = binding;
162 binding.fileSystem[WebInspector.Automapping._binding] = binding;
163 if (binding.exactMatch) {
164 var projectFolder = this._projectFoldersIndex.closestParentFolde r(binding.fileSystem.url());
165 var newFolderAdded = projectFolder ? this._activeFoldersIndex.ad dFolder(projectFolder) : false;
166 if (newFolderAdded)
167 this._scheduleSweep();
168 }
169 this._onBindingCreated.call(null, binding);
170 }
171 },
172
173 _onBindingFailedForTest: function() { },
174
175 /**
176 * @param {!WebInspector.UISourceCode} networkSourceCode
177 */
178 _unbindNetwork: function(networkSourceCode)
179 {
180 if (networkSourceCode[WebInspector.Automapping._processingPromise]) {
181 networkSourceCode[WebInspector.Automapping._processingPromise] = nul l;
182 return;
183 }
184 var binding = networkSourceCode[WebInspector.Automapping._binding];
185 if (!binding)
186 return;
187
188 this._bindings.delete(binding);
189 binding.network[WebInspector.Automapping._binding] = null;
190 binding.fileSystem[WebInspector.Automapping._binding] = null;
191 if (binding.exactMatch) {
192 var projectFolder = this._projectFoldersIndex.closestParentFolder(bi nding.fileSystem.url());
193 if (projectFolder)
194 this._activeFoldersIndex.removeFolder(projectFolder);
195 }
196 this._onBindingRemoved.call(null, binding);
197 },
198
199 /**
200 * @param {!WebInspector.UISourceCode} networkSourceCode
201 * @return {!Promise<?WebInspector.PersistenceBinding>}
202 */
203 _createBinding: function(networkSourceCode)
204 {
205 var networkPath = WebInspector.ParsedURL.extractPath(networkSourceCode.u rl());
206 if (networkPath === null)
207 return Promise.resolve(/** @type {?WebInspector.PersistenceBinding} */(null));
208
209 if (networkPath.endsWith("/"))
210 networkPath += "index.html";
211 var similarFiles = this._filesIndex.similarFiles(networkPath).map(path = > this._fileSystemUISourceCodes.get(path));
212 if (!similarFiles.length)
213 return Promise.resolve(/** @type {?WebInspector.PersistenceBinding} */(null));
214
215 return this._pullMetadatas(similarFiles.concat(networkSourceCode)).then( onMetadatas.bind(this));
216
217 /**
218 * @this {WebInspector.Automapping}
219 */
220 function onMetadatas()
221 {
222 var activeFiles = similarFiles.filter(file => !!this._activeFoldersI ndex.closestParentFolder(file.url()));
223 var networkMetadata = networkSourceCode[WebInspector.Automapping._me tadata];
224 if (!networkMetadata || (!networkMetadata.modificationTime && typeof networkMetadata.contentSize !== "number")) {
225 // If networkSourceCode does not have metadata, try to match aga inst active folders.
226 if (activeFiles.length !== 1)
227 return null;
228 return new WebInspector.PersistenceBinding(networkSourceCode, ac tiveFiles[0], false);
229 }
230
231 // Try to find exact matches, prioritizing active folders.
232 var exactMatches = this._filterWithMetadata(activeFiles, networkMeta data);
233 if (!exactMatches.length)
234 exactMatches = this._filterWithMetadata(similarFiles, networkMet adata);
235 if (exactMatches.length !== 1)
236 return null;
237 return new WebInspector.PersistenceBinding(networkSourceCode, exactM atches[0], true);
238 }
239 },
240
241 /**
242 * @param {!Array<!WebInspector.UISourceCode>} uiSourceCodes
243 * @return {!Promise} 62 * @return {!Promise}
244 */ 63 */
245 _pullMetadatas: function(uiSourceCodes) 64 function sweepUnmapped() {
246 { 65 var networkProjects = this._workspace.projectsForType(WebInspector.project Types.Network);
247 var promises = uiSourceCodes.map(file => fetchMetadata(file)); 66 for (var networkProject of networkProjects) {
248 return Promise.all(promises); 67 for (var uiSourceCode of networkProject.uiSourceCodes())
249 68 this._bindNetwork(uiSourceCode);
250 /** 69 }
251 * @param {!WebInspector.UISourceCode} file 70 this._onSweepHappenedForTest();
252 * @return {!Promise} 71 return Promise.resolve();
253 */ 72 }
254 function fetchMetadata(file) 73 }
255 { 74
256 return file.requestMetadata().then(metadata => file[WebInspector.Aut omapping._metadata] = metadata); 75 _onSweepHappenedForTest() {
257 } 76 }
258 }, 77
78 /**
79 * @param {!WebInspector.Project} project
80 */
81 _onProjectRemoved(project) {
82 for (var uiSourceCode of project.uiSourceCodes())
83 this._onUISourceCodeRemoved(uiSourceCode);
84 if (project.type() !== WebInspector.projectTypes.FileSystem)
85 return;
86 var fileSystem = /** @type {!WebInspector.FileSystemWorkspaceBinding.FileSys tem} */ (project);
87 for (var gitFolder of fileSystem.gitFolders())
88 this._projectFoldersIndex.removeFolder(gitFolder);
89 this._projectFoldersIndex.removeFolder(fileSystem.fileSystemPath());
90 this._scheduleRemap();
91 }
92
93 /**
94 * @param {!WebInspector.Project} project
95 */
96 _onProjectAdded(project) {
97 if (project.type() !== WebInspector.projectTypes.FileSystem)
98 return;
99 var fileSystem = /** @type {!WebInspector.FileSystemWorkspaceBinding.FileSys tem} */ (project);
100 for (var gitFolder of fileSystem.gitFolders())
101 this._projectFoldersIndex.addFolder(gitFolder);
102 this._projectFoldersIndex.addFolder(fileSystem.fileSystemPath());
103 this._scheduleRemap();
104 }
105
106 /**
107 * @param {!WebInspector.UISourceCode} uiSourceCode
108 */
109 _onUISourceCodeAdded(uiSourceCode) {
110 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
111 this._filesIndex.addPath(uiSourceCode.url());
112 this._fileSystemUISourceCodes.set(uiSourceCode.url(), uiSourceCode);
113 this._scheduleSweep();
114 } else if (uiSourceCode.project().type() === WebInspector.projectTypes.Netwo rk) {
115 this._bindNetwork(uiSourceCode);
116 }
117 }
118
119 /**
120 * @param {!WebInspector.UISourceCode} uiSourceCode
121 */
122 _onUISourceCodeRemoved(uiSourceCode) {
123 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
124 this._filesIndex.removePath(uiSourceCode.url());
125 this._fileSystemUISourceCodes.delete(uiSourceCode.url());
126 var binding = uiSourceCode[WebInspector.Automapping._binding];
127 if (binding)
128 this._unbindNetwork(binding.network);
129 } else if (uiSourceCode.project().type() === WebInspector.projectTypes.Netwo rk) {
130 this._unbindNetwork(uiSourceCode);
131 }
132 }
133
134 /**
135 * @param {!WebInspector.UISourceCode} networkSourceCode
136 */
137 _bindNetwork(networkSourceCode) {
138 if (networkSourceCode[WebInspector.Automapping._processingPromise] ||
139 networkSourceCode[WebInspector.Automapping._binding])
140 return;
141 var createBindingPromise = this._createBinding(networkSourceCode).then(onBin ding.bind(this));
142 networkSourceCode[WebInspector.Automapping._processingPromise] = createBindi ngPromise;
259 143
260 /** 144 /**
261 * @param {!Array<!WebInspector.UISourceCode>} files 145 * @param {?WebInspector.PersistenceBinding} binding
262 * @param {!WebInspector.UISourceCodeMetadata} networkMetadata 146 * @this {WebInspector.Automapping}
263 * @return {!Array<!WebInspector.UISourceCode>}
264 */ 147 */
265 _filterWithMetadata: function(files, networkMetadata) 148 function onBinding(binding) {
266 { 149 if (networkSourceCode[WebInspector.Automapping._processingPromise] !== cre ateBindingPromise)
267 return files.filter(file => { 150 return;
268 var fileMetadata = file[WebInspector.Automapping._metadata]; 151 networkSourceCode[WebInspector.Automapping._processingPromise] = null;
269 if (!fileMetadata) 152 if (!binding) {
270 return false; 153 this._onBindingFailedForTest();
271 // Allow a second of difference due to network timestamps lack of pr ecision. 154 return;
272 var timeMatches = !networkMetadata.modificationTime || Math.abs(netw orkMetadata.modificationTime - fileMetadata.modificationTime) < 1000; 155 }
273 var contentMatches = !networkMetadata.contentSize || fileMetadata.co ntentSize === networkMetadata.contentSize; 156
274 return timeMatches && contentMatches; 157 this._bindings.add(binding);
275 }); 158 binding.network[WebInspector.Automapping._binding] = binding;
276 } 159 binding.fileSystem[WebInspector.Automapping._binding] = binding;
160 if (binding.exactMatch) {
161 var projectFolder = this._projectFoldersIndex.closestParentFolder(bindin g.fileSystem.url());
162 var newFolderAdded = projectFolder ? this._activeFoldersIndex.addFolder( projectFolder) : false;
163 if (newFolderAdded)
164 this._scheduleSweep();
165 }
166 this._onBindingCreated.call(null, binding);
167 }
168 }
169
170 _onBindingFailedForTest() {
171 }
172
173 /**
174 * @param {!WebInspector.UISourceCode} networkSourceCode
175 */
176 _unbindNetwork(networkSourceCode) {
177 if (networkSourceCode[WebInspector.Automapping._processingPromise]) {
178 networkSourceCode[WebInspector.Automapping._processingPromise] = null;
179 return;
180 }
181 var binding = networkSourceCode[WebInspector.Automapping._binding];
182 if (!binding)
183 return;
184
185 this._bindings.delete(binding);
186 binding.network[WebInspector.Automapping._binding] = null;
187 binding.fileSystem[WebInspector.Automapping._binding] = null;
188 if (binding.exactMatch) {
189 var projectFolder = this._projectFoldersIndex.closestParentFolder(binding. fileSystem.url());
190 if (projectFolder)
191 this._activeFoldersIndex.removeFolder(projectFolder);
192 }
193 this._onBindingRemoved.call(null, binding);
194 }
195
196 /**
197 * @param {!WebInspector.UISourceCode} networkSourceCode
198 * @return {!Promise<?WebInspector.PersistenceBinding>}
199 */
200 _createBinding(networkSourceCode) {
201 var networkPath = WebInspector.ParsedURL.extractPath(networkSourceCode.url() );
202 if (networkPath === null)
203 return Promise.resolve(/** @type {?WebInspector.PersistenceBinding} */ (nu ll));
204
205 if (networkPath.endsWith('/'))
206 networkPath += 'index.html';
207 var similarFiles = this._filesIndex.similarFiles(networkPath).map(path => th is._fileSystemUISourceCodes.get(path));
208 if (!similarFiles.length)
209 return Promise.resolve(/** @type {?WebInspector.PersistenceBinding} */ (nu ll));
210
211 return this._pullMetadatas(similarFiles.concat(networkSourceCode)).then(onMe tadatas.bind(this));
212
213 /**
214 * @this {WebInspector.Automapping}
215 */
216 function onMetadatas() {
217 var activeFiles = similarFiles.filter(file => !!this._activeFoldersIndex.c losestParentFolder(file.url()));
218 var networkMetadata = networkSourceCode[WebInspector.Automapping._metadata ];
219 if (!networkMetadata || (!networkMetadata.modificationTime && typeof netwo rkMetadata.contentSize !== 'number')) {
220 // If networkSourceCode does not have metadata, try to match against act ive folders.
221 if (activeFiles.length !== 1)
222 return null;
223 return new WebInspector.PersistenceBinding(networkSourceCode, activeFile s[0], false);
224 }
225
226 // Try to find exact matches, prioritizing active folders.
227 var exactMatches = this._filterWithMetadata(activeFiles, networkMetadata);
228 if (!exactMatches.length)
229 exactMatches = this._filterWithMetadata(similarFiles, networkMetadata);
230 if (exactMatches.length !== 1)
231 return null;
232 return new WebInspector.PersistenceBinding(networkSourceCode, exactMatches [0], true);
233 }
234 }
235
236 /**
237 * @param {!Array<!WebInspector.UISourceCode>} uiSourceCodes
238 * @return {!Promise}
239 */
240 _pullMetadatas(uiSourceCodes) {
241 var promises = uiSourceCodes.map(file => fetchMetadata(file));
242 return Promise.all(promises);
243
244 /**
245 * @param {!WebInspector.UISourceCode} file
246 * @return {!Promise}
247 */
248 function fetchMetadata(file) {
249 return file.requestMetadata().then(metadata => file[WebInspector.Automappi ng._metadata] = metadata);
250 }
251 }
252
253 /**
254 * @param {!Array<!WebInspector.UISourceCode>} files
255 * @param {!WebInspector.UISourceCodeMetadata} networkMetadata
256 * @return {!Array<!WebInspector.UISourceCode>}
257 */
258 _filterWithMetadata(files, networkMetadata) {
259 return files.filter(file => {
260 var fileMetadata = file[WebInspector.Automapping._metadata];
261 if (!fileMetadata)
262 return false;
263 // Allow a second of difference due to network timestamps lack of precisio n.
264 var timeMatches = !networkMetadata.modificationTime ||
265 Math.abs(networkMetadata.modificationTime - fileMetadata.modificationT ime) < 1000;
266 var contentMatches = !networkMetadata.contentSize || fileMetadata.contentS ize === networkMetadata.contentSize;
267 return timeMatches && contentMatches;
268 });
269 }
277 }; 270 };
278 271
272 WebInspector.Automapping._binding = Symbol('Automapping.Binding');
273 WebInspector.Automapping._processingPromise = Symbol('Automapping.ProcessingProm ise');
274 WebInspector.Automapping._metadata = Symbol('Automapping.Metadata');
275
279 /** 276 /**
280 * @constructor 277 * @unrestricted
281 */ 278 */
282 WebInspector.Automapping.PathEncoder = function() 279 WebInspector.Automapping.PathEncoder = class {
283 { 280 constructor() {
284 /** @type {!WebInspector.CharacterIdMap<string>} */ 281 /** @type {!WebInspector.CharacterIdMap<string>} */
285 this._encoder = new WebInspector.CharacterIdMap(); 282 this._encoder = new WebInspector.CharacterIdMap();
283 }
284
285 /**
286 * @param {string} path
287 * @return {string}
288 */
289 encode(path) {
290 return path.split('/').map(token => this._encoder.toChar(token)).join('');
291 }
292
293 /**
294 * @param {string} path
295 * @return {string}
296 */
297 decode(path) {
298 return path.split('').map(token => this._encoder.fromChar(token)).join('/');
299 }
286 }; 300 };
287 301
288 WebInspector.Automapping.PathEncoder.prototype = {
289 /**
290 * @param {string} path
291 * @return {string}
292 */
293 encode: function(path)
294 {
295 return path.split("/").map(token => this._encoder.toChar(token)).join("" );
296 },
297
298 /**
299 * @param {string} path
300 * @return {string}
301 */
302 decode: function(path)
303 {
304 return path.split("").map(token => this._encoder.fromChar(token)).join(" /");
305 }
306 };
307
308 /** 302 /**
309 * @constructor 303 * @unrestricted
310 * @param {!WebInspector.Automapping.PathEncoder} encoder
311 */ 304 */
312 WebInspector.Automapping.FilePathIndex = function(encoder) 305 WebInspector.Automapping.FilePathIndex = class {
313 { 306 /**
307 * @param {!WebInspector.Automapping.PathEncoder} encoder
308 */
309 constructor(encoder) {
314 this._encoder = encoder; 310 this._encoder = encoder;
315 this._reversedIndex = new WebInspector.Trie(); 311 this._reversedIndex = new WebInspector.Trie();
312 }
313
314 /**
315 * @param {string} path
316 */
317 addPath(path) {
318 var encodedPath = this._encoder.encode(path);
319 this._reversedIndex.add(encodedPath.reverse());
320 }
321
322 /**
323 * @param {string} path
324 */
325 removePath(path) {
326 var encodedPath = this._encoder.encode(path);
327 this._reversedIndex.remove(encodedPath.reverse());
328 }
329
330 /**
331 * @param {string} networkPath
332 * @return {!Array<string>}
333 */
334 similarFiles(networkPath) {
335 var encodedPath = this._encoder.encode(networkPath);
336 var longestCommonPrefix = this._reversedIndex.longestPrefix(encodedPath.reve rse(), false);
337 if (!longestCommonPrefix)
338 return [];
339 return this._reversedIndex.words(longestCommonPrefix)
340 .map(encodedPath => this._encoder.decode(encodedPath.reverse()));
341 }
316 }; 342 };
317 343
318 WebInspector.Automapping.FilePathIndex.prototype = {
319 /**
320 * @param {string} path
321 */
322 addPath: function(path)
323 {
324 var encodedPath = this._encoder.encode(path);
325 this._reversedIndex.add(encodedPath.reverse());
326 },
327
328 /**
329 * @param {string} path
330 */
331 removePath: function(path)
332 {
333 var encodedPath = this._encoder.encode(path);
334 this._reversedIndex.remove(encodedPath.reverse());
335 },
336
337 /**
338 * @param {string} networkPath
339 * @return {!Array<string>}
340 */
341 similarFiles: function(networkPath)
342 {
343 var encodedPath = this._encoder.encode(networkPath);
344 var longestCommonPrefix = this._reversedIndex.longestPrefix(encodedPath. reverse(), false);
345 if (!longestCommonPrefix)
346 return [];
347 return this._reversedIndex.words(longestCommonPrefix).map(encodedPath => this._encoder.decode(encodedPath.reverse()));
348 },
349 };
350
351 /** 344 /**
352 * @constructor 345 * @unrestricted
353 * @param {!WebInspector.Automapping.PathEncoder} encoder
354 */ 346 */
355 WebInspector.Automapping.FolderIndex = function(encoder) 347 WebInspector.Automapping.FolderIndex = class {
356 { 348 /**
349 * @param {!WebInspector.Automapping.PathEncoder} encoder
350 */
351 constructor(encoder) {
357 this._encoder = encoder; 352 this._encoder = encoder;
358 this._index = new WebInspector.Trie(); 353 this._index = new WebInspector.Trie();
359 /** @type {!Map<string, number>} */ 354 /** @type {!Map<string, number>} */
360 this._folderCount = new Map(); 355 this._folderCount = new Map();
356 }
357
358 /**
359 * @param {string} path
360 * @return {boolean}
361 */
362 addFolder(path) {
363 if (path.endsWith('/'))
364 path = path.substring(0, path.length - 1);
365 var encodedPath = this._encoder.encode(path);
366 this._index.add(encodedPath);
367 var count = this._folderCount.get(encodedPath) || 0;
368 this._folderCount.set(encodedPath, count + 1);
369 return count === 0;
370 }
371
372 /**
373 * @param {string} path
374 * @return {boolean}
375 */
376 removeFolder(path) {
377 if (path.endsWith('/'))
378 path = path.substring(0, path.length - 1);
379 var encodedPath = this._encoder.encode(path);
380 var count = this._folderCount.get(encodedPath) || 0;
381 if (!count)
382 return false;
383 if (count > 1) {
384 this._folderCount.set(encodedPath, count - 1);
385 return false;
386 }
387 this._index.remove(encodedPath);
388 this._folderCount.delete(encodedPath);
389 return true;
390 }
391
392 /**
393 * @param {string} path
394 * @return {string}
395 */
396 closestParentFolder(path) {
397 var encodedPath = this._encoder.encode(path);
398 var commonPrefix = this._index.longestPrefix(encodedPath, true);
399 return this._encoder.decode(commonPrefix);
400 }
361 }; 401 };
362
363 WebInspector.Automapping.FolderIndex.prototype = {
364 /**
365 * @param {string} path
366 * @return {boolean}
367 */
368 addFolder: function(path)
369 {
370 if (path.endsWith("/"))
371 path = path.substring(0, path.length - 1);
372 var encodedPath = this._encoder.encode(path);
373 this._index.add(encodedPath);
374 var count = this._folderCount.get(encodedPath) || 0;
375 this._folderCount.set(encodedPath, count + 1);
376 return count === 0;
377 },
378
379 /**
380 * @param {string} path
381 * @return {boolean}
382 */
383 removeFolder: function(path)
384 {
385 if (path.endsWith("/"))
386 path = path.substring(0, path.length - 1);
387 var encodedPath = this._encoder.encode(path);
388 var count = this._folderCount.get(encodedPath) || 0;
389 if (!count)
390 return false;
391 if (count > 1) {
392 this._folderCount.set(encodedPath, count - 1);
393 return false;
394 }
395 this._index.remove(encodedPath);
396 this._folderCount.delete(encodedPath);
397 return true;
398 },
399
400 /**
401 * @param {string} path
402 * @return {string}
403 */
404 closestParentFolder: function(path)
405 {
406 var encodedPath = this._encoder.encode(path);
407 var commonPrefix = this._index.longestPrefix(encodedPath, true);
408 return this._encoder.decode(commonPrefix);
409 }
410 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698