OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
13 * distribution. | 13 * distribution. |
14 * * Neither the name of Google Inc. nor the names of its | 14 * * Neither the name of Google Inc. nor the names of its |
15 * contributors may be used to endorse or promote products derived from | 15 * contributors may be used to endorse or promote products derived from |
16 * this software without specific prior written permission. | 16 * this software without specific prior written permission. |
17 * | 17 * |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | |
31 /** | 30 /** |
32 * @constructor | 31 * @unrestricted |
33 * @param {!WebInspector.IsolatedFileSystemManager} isolatedFileSystemManager | |
34 * @param {!WebInspector.Workspace} workspace | |
35 */ | 32 */ |
36 WebInspector.FileSystemWorkspaceBinding = function(isolatedFileSystemManager, wo
rkspace) | 33 WebInspector.FileSystemWorkspaceBinding = class { |
37 { | 34 /** |
| 35 * @param {!WebInspector.IsolatedFileSystemManager} isolatedFileSystemManager |
| 36 * @param {!WebInspector.Workspace} workspace |
| 37 */ |
| 38 constructor(isolatedFileSystemManager, workspace) { |
38 this._isolatedFileSystemManager = isolatedFileSystemManager; | 39 this._isolatedFileSystemManager = isolatedFileSystemManager; |
39 this._workspace = workspace; | 40 this._workspace = workspace; |
40 this._eventListeners = [ | 41 this._eventListeners = [ |
41 this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFi
leSystemManager.Events.FileSystemAdded, this._onFileSystemAdded, this), | 42 this._isolatedFileSystemManager.addEventListener( |
42 this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFi
leSystemManager.Events.FileSystemRemoved, this._onFileSystemRemoved, this), | 43 WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._o
nFileSystemAdded, this), |
43 this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFi
leSystemManager.Events.FileSystemFilesChanged, this._fileSystemFilesChanged, thi
s) | 44 this._isolatedFileSystemManager.addEventListener( |
| 45 WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this.
_onFileSystemRemoved, this), |
| 46 this._isolatedFileSystemManager.addEventListener( |
| 47 WebInspector.IsolatedFileSystemManager.Events.FileSystemFilesChanged,
this._fileSystemFilesChanged, this) |
44 ]; | 48 ]; |
45 /** @type {!Map.<string, !WebInspector.FileSystemWorkspaceBinding.FileSystem
>} */ | 49 /** @type {!Map.<string, !WebInspector.FileSystemWorkspaceBinding.FileSystem
>} */ |
46 this._boundFileSystems = new Map(); | 50 this._boundFileSystems = new Map(); |
47 this._isolatedFileSystemManager.waitForFileSystems() | 51 this._isolatedFileSystemManager.waitForFileSystems().then(this._onFileSystem
sLoaded.bind(this)); |
48 .then(this._onFileSystemsLoaded.bind(this)); | 52 } |
| 53 |
| 54 /** |
| 55 * @param {string} fileSystemPath |
| 56 * @return {string} |
| 57 */ |
| 58 static projectId(fileSystemPath) { |
| 59 return fileSystemPath; |
| 60 } |
| 61 |
| 62 /** |
| 63 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 64 * @return {!Array<string>} |
| 65 */ |
| 66 static relativePath(uiSourceCode) { |
| 67 var baseURL = |
| 68 /** @type {!WebInspector.FileSystemWorkspaceBinding.FileSystem}*/ (uiSou
rceCode.project())._fileSystemBaseURL; |
| 69 return uiSourceCode.url().substring(baseURL.length).split('/'); |
| 70 } |
| 71 |
| 72 /** |
| 73 * @param {!WebInspector.Project} project |
| 74 * @param {string} relativePath |
| 75 * @return {string} |
| 76 */ |
| 77 static completeURL(project, relativePath) { |
| 78 var fsProject = /** @type {!WebInspector.FileSystemWorkspaceBinding.FileSyst
em}*/ (project); |
| 79 return fsProject._fileSystemBaseURL + relativePath; |
| 80 } |
| 81 |
| 82 /** |
| 83 * @param {string} extension |
| 84 * @return {!WebInspector.ResourceType} |
| 85 */ |
| 86 static _contentTypeForExtension(extension) { |
| 87 if (WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions.has(extens
ion)) |
| 88 return WebInspector.resourceTypes.Stylesheet; |
| 89 if (WebInspector.FileSystemWorkspaceBinding._documentExtensions.has(extensio
n)) |
| 90 return WebInspector.resourceTypes.Document; |
| 91 if (WebInspector.FileSystemWorkspaceBinding._imageExtensions.has(extension)) |
| 92 return WebInspector.resourceTypes.Image; |
| 93 if (WebInspector.FileSystemWorkspaceBinding._scriptExtensions.has(extension)
) |
| 94 return WebInspector.resourceTypes.Script; |
| 95 return WebInspector.resourceTypes.Other; |
| 96 } |
| 97 |
| 98 /** |
| 99 * @param {string} projectId |
| 100 * @return {string} |
| 101 */ |
| 102 static fileSystemPath(projectId) { |
| 103 return projectId; |
| 104 } |
| 105 |
| 106 /** |
| 107 * @return {!WebInspector.IsolatedFileSystemManager} |
| 108 */ |
| 109 fileSystemManager() { |
| 110 return this._isolatedFileSystemManager; |
| 111 } |
| 112 |
| 113 /** |
| 114 * @param {!Array<!WebInspector.IsolatedFileSystem>} fileSystems |
| 115 */ |
| 116 _onFileSystemsLoaded(fileSystems) { |
| 117 for (var fileSystem of fileSystems) |
| 118 this._addFileSystem(fileSystem); |
| 119 } |
| 120 |
| 121 /** |
| 122 * @param {!WebInspector.Event} event |
| 123 */ |
| 124 _onFileSystemAdded(event) { |
| 125 var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data
); |
| 126 this._addFileSystem(fileSystem); |
| 127 } |
| 128 |
| 129 /** |
| 130 * @param {!WebInspector.IsolatedFileSystem} fileSystem |
| 131 */ |
| 132 _addFileSystem(fileSystem) { |
| 133 var boundFileSystem = new WebInspector.FileSystemWorkspaceBinding.FileSystem
(this, fileSystem, this._workspace); |
| 134 this._boundFileSystems.set(fileSystem.path(), boundFileSystem); |
| 135 } |
| 136 |
| 137 /** |
| 138 * @param {!WebInspector.Event} event |
| 139 */ |
| 140 _onFileSystemRemoved(event) { |
| 141 var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data
); |
| 142 var boundFileSystem = this._boundFileSystems.get(fileSystem.path()); |
| 143 boundFileSystem.dispose(); |
| 144 this._boundFileSystems.remove(fileSystem.path()); |
| 145 } |
| 146 |
| 147 /** |
| 148 * @param {!WebInspector.Event} event |
| 149 */ |
| 150 _fileSystemFilesChanged(event) { |
| 151 var paths = /** @type {!Array<string>} */ (event.data); |
| 152 for (var path of paths) { |
| 153 for (var key of this._boundFileSystems.keys()) { |
| 154 if (!path.startsWith(key)) |
| 155 continue; |
| 156 this._boundFileSystems.get(key)._fileChanged(path); |
| 157 } |
| 158 } |
| 159 } |
| 160 |
| 161 dispose() { |
| 162 WebInspector.EventTarget.removeEventListeners(this._eventListeners); |
| 163 for (var fileSystem of this._boundFileSystems.values()) { |
| 164 fileSystem.dispose(); |
| 165 this._boundFileSystems.remove(fileSystem._fileSystem.path()); |
| 166 } |
| 167 } |
49 }; | 168 }; |
50 | 169 |
51 WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions = new Set(["css",
"scss", "sass", "less"]); | 170 WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions = new Set(['css',
'scss', 'sass', 'less']); |
52 WebInspector.FileSystemWorkspaceBinding._documentExtensions = new Set(["htm", "h
tml", "asp", "aspx", "phtml", "jsp"]); | 171 WebInspector.FileSystemWorkspaceBinding._documentExtensions = new Set(['htm', 'h
tml', 'asp', 'aspx', 'phtml', 'jsp']); |
53 WebInspector.FileSystemWorkspaceBinding._scriptExtensions = new Set(["asp", "asp
x", "c", "cc", "cljs", "coffee", "cpp", "cs", "dart", "java", "js", "jsp", "jsx"
, "h", "m", "mm", "py", "sh", "ts", "tsx", "ls"]); | 172 WebInspector.FileSystemWorkspaceBinding._scriptExtensions = new Set([ |
| 173 'asp', 'aspx', 'c', 'cc', 'cljs', 'coffee', 'cpp', 'cs', 'dart', 'java', 'js', |
| 174 'jsp', 'jsx', 'h', 'm', 'mm', 'py', 'sh', 'ts', 'tsx', 'ls' |
| 175 ]); |
54 | 176 |
55 WebInspector.FileSystemWorkspaceBinding._imageExtensions = WebInspector.Isolated
FileSystem.ImageExtensions; | 177 WebInspector.FileSystemWorkspaceBinding._imageExtensions = WebInspector.Isolated
FileSystem.ImageExtensions; |
56 | 178 |
| 179 |
57 /** | 180 /** |
58 * @param {string} fileSystemPath | 181 * @implements {WebInspector.Project} |
59 * @return {string} | 182 * @unrestricted |
60 */ | 183 */ |
61 WebInspector.FileSystemWorkspaceBinding.projectId = function(fileSystemPath) | 184 WebInspector.FileSystemWorkspaceBinding.FileSystem = class extends WebInspector.
ProjectStore { |
62 { | 185 /** |
63 return fileSystemPath; | 186 * @param {!WebInspector.FileSystemWorkspaceBinding} fileSystemWorkspaceBindin
g |
64 }; | 187 * @param {!WebInspector.IsolatedFileSystem} isolatedFileSystem |
65 | 188 * @param {!WebInspector.Workspace} workspace |
66 /** | 189 */ |
67 * @param {!WebInspector.UISourceCode} uiSourceCode | 190 constructor(fileSystemWorkspaceBinding, isolatedFileSystem, workspace) { |
68 * @return {!Array<string>} | |
69 */ | |
70 WebInspector.FileSystemWorkspaceBinding.relativePath = function(uiSourceCode) | |
71 { | |
72 var baseURL = /** @type {!WebInspector.FileSystemWorkspaceBinding.FileSystem
}*/(uiSourceCode.project())._fileSystemBaseURL; | |
73 return uiSourceCode.url().substring(baseURL.length).split("/"); | |
74 }; | |
75 | |
76 /** | |
77 * @param {!WebInspector.Project} project | |
78 * @param {string} relativePath | |
79 * @return {string} | |
80 */ | |
81 WebInspector.FileSystemWorkspaceBinding.completeURL = function(project, relative
Path) | |
82 { | |
83 var fsProject = /** @type {!WebInspector.FileSystemWorkspaceBinding.FileSyst
em}*/(project); | |
84 return fsProject._fileSystemBaseURL + relativePath; | |
85 }; | |
86 | |
87 /** | |
88 * @param {string} extension | |
89 * @return {!WebInspector.ResourceType} | |
90 */ | |
91 WebInspector.FileSystemWorkspaceBinding._contentTypeForExtension = function(exte
nsion) | |
92 { | |
93 if (WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions.has(extens
ion)) | |
94 return WebInspector.resourceTypes.Stylesheet; | |
95 if (WebInspector.FileSystemWorkspaceBinding._documentExtensions.has(extensio
n)) | |
96 return WebInspector.resourceTypes.Document; | |
97 if (WebInspector.FileSystemWorkspaceBinding._imageExtensions.has(extension)) | |
98 return WebInspector.resourceTypes.Image; | |
99 if (WebInspector.FileSystemWorkspaceBinding._scriptExtensions.has(extension)
) | |
100 return WebInspector.resourceTypes.Script; | |
101 return WebInspector.resourceTypes.Other; | |
102 }; | |
103 | |
104 WebInspector.FileSystemWorkspaceBinding.prototype = { | |
105 /** | |
106 * @return {!WebInspector.IsolatedFileSystemManager} | |
107 */ | |
108 fileSystemManager: function() | |
109 { | |
110 return this._isolatedFileSystemManager; | |
111 }, | |
112 | |
113 /** | |
114 * @param {!Array<!WebInspector.IsolatedFileSystem>} fileSystems | |
115 */ | |
116 _onFileSystemsLoaded: function(fileSystems) | |
117 { | |
118 for (var fileSystem of fileSystems) | |
119 this._addFileSystem(fileSystem); | |
120 }, | |
121 | |
122 /** | |
123 * @param {!WebInspector.Event} event | |
124 */ | |
125 _onFileSystemAdded: function(event) | |
126 { | |
127 var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.
data); | |
128 this._addFileSystem(fileSystem); | |
129 }, | |
130 | |
131 /** | |
132 * @param {!WebInspector.IsolatedFileSystem} fileSystem | |
133 */ | |
134 _addFileSystem: function(fileSystem) | |
135 { | |
136 var boundFileSystem = new WebInspector.FileSystemWorkspaceBinding.FileSy
stem(this, fileSystem, this._workspace); | |
137 this._boundFileSystems.set(fileSystem.path(), boundFileSystem); | |
138 }, | |
139 | |
140 /** | |
141 * @param {!WebInspector.Event} event | |
142 */ | |
143 _onFileSystemRemoved: function(event) | |
144 { | |
145 var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.
data); | |
146 var boundFileSystem = this._boundFileSystems.get(fileSystem.path()); | |
147 boundFileSystem.dispose(); | |
148 this._boundFileSystems.remove(fileSystem.path()); | |
149 }, | |
150 | |
151 /** | |
152 * @param {!WebInspector.Event} event | |
153 */ | |
154 _fileSystemFilesChanged: function(event) | |
155 { | |
156 var paths = /** @type {!Array<string>} */ (event.data); | |
157 for (var path of paths) { | |
158 for (var key of this._boundFileSystems.keys()) { | |
159 if (!path.startsWith(key)) | |
160 continue; | |
161 this._boundFileSystems.get(key)._fileChanged(path); | |
162 } | |
163 } | |
164 }, | |
165 | |
166 dispose: function() | |
167 { | |
168 WebInspector.EventTarget.removeEventListeners(this._eventListeners); | |
169 for (var fileSystem of this._boundFileSystems.values()) { | |
170 fileSystem.dispose(); | |
171 this._boundFileSystems.remove(fileSystem._fileSystem.path()); | |
172 } | |
173 } | |
174 }; | |
175 | |
176 /** | |
177 * @param {string} projectId | |
178 * @return {string} | |
179 */ | |
180 WebInspector.FileSystemWorkspaceBinding.fileSystemPath = function(projectId) | |
181 { | |
182 return projectId; | |
183 }; | |
184 | |
185 /** | |
186 * @constructor | |
187 * @extends {WebInspector.ProjectStore} | |
188 * @implements {WebInspector.Project} | |
189 * @param {!WebInspector.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding | |
190 * @param {!WebInspector.IsolatedFileSystem} isolatedFileSystem | |
191 * @param {!WebInspector.Workspace} workspace | |
192 */ | |
193 WebInspector.FileSystemWorkspaceBinding.FileSystem = function(fileSystemWorkspac
eBinding, isolatedFileSystem, workspace) | |
194 { | |
195 var fileSystemPath = isolatedFileSystem.path(); | 191 var fileSystemPath = isolatedFileSystem.path(); |
196 var id = WebInspector.FileSystemWorkspaceBinding.projectId(fileSystemPath); | 192 var id = WebInspector.FileSystemWorkspaceBinding.projectId(fileSystemPath); |
197 console.assert(!workspace.project(id)); | 193 console.assert(!workspace.project(id)); |
198 var displayName = fileSystemPath.substr(fileSystemPath.lastIndexOf("/") + 1)
; | 194 var displayName = fileSystemPath.substr(fileSystemPath.lastIndexOf('/') + 1)
; |
199 | 195 |
200 WebInspector.ProjectStore.call(this, workspace, id, WebInspector.projectType
s.FileSystem, displayName); | 196 super(workspace, id, WebInspector.projectTypes.FileSystem, displayName); |
201 | 197 |
202 this._fileSystem = isolatedFileSystem; | 198 this._fileSystem = isolatedFileSystem; |
203 this._fileSystemBaseURL = this._fileSystem.path() + "/"; | 199 this._fileSystemBaseURL = this._fileSystem.path() + '/'; |
204 this._fileSystemWorkspaceBinding = fileSystemWorkspaceBinding; | 200 this._fileSystemWorkspaceBinding = fileSystemWorkspaceBinding; |
205 this._fileSystemPath = fileSystemPath; | 201 this._fileSystemPath = fileSystemPath; |
206 | 202 |
207 workspace.addProject(this); | 203 workspace.addProject(this); |
208 this.populate(); | 204 this.populate(); |
| 205 } |
| 206 |
| 207 /** |
| 208 * @return {string} |
| 209 */ |
| 210 fileSystemPath() { |
| 211 return this._fileSystemPath; |
| 212 } |
| 213 |
| 214 /** |
| 215 * @return {!Array<string>} |
| 216 */ |
| 217 gitFolders() { |
| 218 return this._fileSystem.gitFolders().map(folder => this._fileSystemPath + '/
' + folder); |
| 219 } |
| 220 |
| 221 /** |
| 222 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 223 * @return {string} |
| 224 */ |
| 225 _filePathForUISourceCode(uiSourceCode) { |
| 226 return uiSourceCode.url().substring(this._fileSystemPath.length); |
| 227 } |
| 228 |
| 229 /** |
| 230 * @override |
| 231 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 232 * @return {!Promise<?WebInspector.UISourceCodeMetadata>} |
| 233 */ |
| 234 requestMetadata(uiSourceCode) { |
| 235 if (uiSourceCode[WebInspector.FileSystemWorkspaceBinding._metadata]) |
| 236 return uiSourceCode[WebInspector.FileSystemWorkspaceBinding._metadata]; |
| 237 var relativePath = this._filePathForUISourceCode(uiSourceCode); |
| 238 var promise = this._fileSystem.getMetadata(relativePath).then(onMetadata); |
| 239 uiSourceCode[WebInspector.FileSystemWorkspaceBinding._metadata] = promise; |
| 240 return promise; |
| 241 |
| 242 /** |
| 243 * @param {?{modificationTime: !Date, size: number}} metadata |
| 244 * @return {?WebInspector.UISourceCodeMetadata} |
| 245 */ |
| 246 function onMetadata(metadata) { |
| 247 if (!metadata) |
| 248 return null; |
| 249 return new WebInspector.UISourceCodeMetadata(metadata.modificationTime, me
tadata.size); |
| 250 } |
| 251 } |
| 252 |
| 253 /** |
| 254 * @override |
| 255 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 256 * @param {function(?string)} callback |
| 257 */ |
| 258 requestFileContent(uiSourceCode, callback) { |
| 259 var filePath = this._filePathForUISourceCode(uiSourceCode); |
| 260 var isImage = |
| 261 WebInspector.FileSystemWorkspaceBinding._imageExtensions.has(WebInspecto
r.ParsedURL.extractExtension(filePath)); |
| 262 |
| 263 this._fileSystem.requestFileContent(filePath, isImage ? base64CallbackWrappe
r : callback); |
| 264 |
| 265 /** |
| 266 * @param {?string} result |
| 267 */ |
| 268 function base64CallbackWrapper(result) { |
| 269 if (!result) { |
| 270 callback(result); |
| 271 return; |
| 272 } |
| 273 var index = result.indexOf(','); |
| 274 callback(result.substring(index + 1)); |
| 275 } |
| 276 } |
| 277 |
| 278 /** |
| 279 * @override |
| 280 * @return {boolean} |
| 281 */ |
| 282 canSetFileContent() { |
| 283 return true; |
| 284 } |
| 285 |
| 286 /** |
| 287 * @override |
| 288 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 289 * @param {string} newContent |
| 290 * @param {function(?string)} callback |
| 291 */ |
| 292 setFileContent(uiSourceCode, newContent, callback) { |
| 293 var filePath = this._filePathForUISourceCode(uiSourceCode); |
| 294 this._fileSystem.setFileContent(filePath, newContent, callback.bind(this, ''
)); |
| 295 } |
| 296 |
| 297 /** |
| 298 * @override |
| 299 * @return {boolean} |
| 300 */ |
| 301 canRename() { |
| 302 return true; |
| 303 } |
| 304 |
| 305 /** |
| 306 * @override |
| 307 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 308 * @param {string} newName |
| 309 * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} c
allback |
| 310 */ |
| 311 rename(uiSourceCode, newName, callback) { |
| 312 if (newName === uiSourceCode.name()) { |
| 313 callback(true, uiSourceCode.name(), uiSourceCode.url(), uiSourceCode.conte
ntType()); |
| 314 return; |
| 315 } |
| 316 |
| 317 var filePath = this._filePathForUISourceCode(uiSourceCode); |
| 318 this._fileSystem.renameFile(filePath, newName, innerCallback.bind(this)); |
| 319 |
| 320 /** |
| 321 * @param {boolean} success |
| 322 * @param {string=} newName |
| 323 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} |
| 324 */ |
| 325 function innerCallback(success, newName) { |
| 326 if (!success || !newName) { |
| 327 callback(false, newName); |
| 328 return; |
| 329 } |
| 330 console.assert(newName); |
| 331 var slash = filePath.lastIndexOf('/'); |
| 332 var parentPath = filePath.substring(0, slash); |
| 333 filePath = parentPath + '/' + newName; |
| 334 filePath = filePath.substr(1); |
| 335 var extension = this._extensionForPath(newName); |
| 336 var newURL = this._fileSystemBaseURL + filePath; |
| 337 var newContentType = WebInspector.FileSystemWorkspaceBinding._contentTypeF
orExtension(extension); |
| 338 this.renameUISourceCode(uiSourceCode, newName); |
| 339 callback(true, newName, newURL, newContentType); |
| 340 } |
| 341 } |
| 342 |
| 343 /** |
| 344 * @override |
| 345 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 346 * @param {string} query |
| 347 * @param {boolean} caseSensitive |
| 348 * @param {boolean} isRegex |
| 349 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callb
ack |
| 350 */ |
| 351 searchInFileContent(uiSourceCode, query, caseSensitive, isRegex, callback) { |
| 352 var filePath = this._filePathForUISourceCode(uiSourceCode); |
| 353 this._fileSystem.requestFileContent(filePath, contentCallback); |
| 354 |
| 355 /** |
| 356 * @param {?string} content |
| 357 */ |
| 358 function contentCallback(content) { |
| 359 var result = []; |
| 360 if (content !== null) |
| 361 result = WebInspector.ContentProvider.performSearchInContent(content, qu
ery, caseSensitive, isRegex); |
| 362 callback(result); |
| 363 } |
| 364 } |
| 365 |
| 366 /** |
| 367 * @override |
| 368 * @param {!WebInspector.ProjectSearchConfig} searchConfig |
| 369 * @param {!Array.<string>} filesMathingFileQuery |
| 370 * @param {!WebInspector.Progress} progress |
| 371 * @param {function(!Array.<string>)} callback |
| 372 */ |
| 373 findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, progress,
callback) { |
| 374 var result = filesMathingFileQuery; |
| 375 var queriesToRun = searchConfig.queries().slice(); |
| 376 if (!queriesToRun.length) |
| 377 queriesToRun.push(''); |
| 378 progress.setTotalWork(queriesToRun.length); |
| 379 searchNextQuery.call(this); |
| 380 |
| 381 /** |
| 382 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} |
| 383 */ |
| 384 function searchNextQuery() { |
| 385 if (!queriesToRun.length) { |
| 386 progress.done(); |
| 387 callback(result); |
| 388 return; |
| 389 } |
| 390 var query = queriesToRun.shift(); |
| 391 this._fileSystem.searchInPath(searchConfig.isRegex() ? '' : query, progres
s, innerCallback.bind(this)); |
| 392 } |
| 393 |
| 394 /** |
| 395 * @param {!Array.<string>} files |
| 396 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} |
| 397 */ |
| 398 function innerCallback(files) { |
| 399 files = files.sort(); |
| 400 progress.worked(1); |
| 401 result = result.intersectOrdered(files, String.naturalOrderComparator); |
| 402 searchNextQuery.call(this); |
| 403 } |
| 404 } |
| 405 |
| 406 /** |
| 407 * @override |
| 408 * @param {!WebInspector.Progress} progress |
| 409 */ |
| 410 indexContent(progress) { |
| 411 this._fileSystem.indexContent(progress); |
| 412 } |
| 413 |
| 414 /** |
| 415 * @param {string} path |
| 416 * @return {string} |
| 417 */ |
| 418 _extensionForPath(path) { |
| 419 var extensionIndex = path.lastIndexOf('.'); |
| 420 if (extensionIndex === -1) |
| 421 return ''; |
| 422 return path.substring(extensionIndex + 1).toLowerCase(); |
| 423 } |
| 424 |
| 425 populate() { |
| 426 var chunkSize = 1000; |
| 427 var filePaths = this._fileSystem.filePaths(); |
| 428 reportFileChunk.call(this, 0); |
| 429 |
| 430 /** |
| 431 * @param {number} from |
| 432 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} |
| 433 */ |
| 434 function reportFileChunk(from) { |
| 435 var to = Math.min(from + chunkSize, filePaths.length); |
| 436 for (var i = from; i < to; ++i) |
| 437 this._addFile(filePaths[i]); |
| 438 if (to < filePaths.length) |
| 439 setTimeout(reportFileChunk.bind(this, to), 100); |
| 440 } |
| 441 } |
| 442 |
| 443 /** |
| 444 * @override |
| 445 * @param {string} url |
| 446 */ |
| 447 excludeFolder(url) { |
| 448 var relativeFolder = url.substring(this._fileSystemBaseURL.length); |
| 449 if (!relativeFolder.startsWith('/')) |
| 450 relativeFolder = '/' + relativeFolder; |
| 451 if (!relativeFolder.endsWith('/')) |
| 452 relativeFolder += '/'; |
| 453 this._fileSystem.addExcludedFolder(relativeFolder); |
| 454 |
| 455 var uiSourceCodes = this.uiSourceCodes().slice(); |
| 456 for (var i = 0; i < uiSourceCodes.length; ++i) { |
| 457 var uiSourceCode = uiSourceCodes[i]; |
| 458 if (uiSourceCode.url().startsWith(url)) |
| 459 this.removeUISourceCode(uiSourceCode.url()); |
| 460 } |
| 461 } |
| 462 |
| 463 /** |
| 464 * @override |
| 465 * @param {string} path |
| 466 * @param {?string} name |
| 467 * @param {string} content |
| 468 * @param {function(?WebInspector.UISourceCode)} callback |
| 469 */ |
| 470 createFile(path, name, content, callback) { |
| 471 this._fileSystem.createFile(path, name, innerCallback.bind(this)); |
| 472 var createFilePath; |
| 473 |
| 474 /** |
| 475 * @param {?string} filePath |
| 476 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} |
| 477 */ |
| 478 function innerCallback(filePath) { |
| 479 if (!filePath) { |
| 480 callback(null); |
| 481 return; |
| 482 } |
| 483 createFilePath = filePath; |
| 484 if (!content) { |
| 485 contentSet.call(this); |
| 486 return; |
| 487 } |
| 488 this._fileSystem.setFileContent(filePath, content, contentSet.bind(this)); |
| 489 } |
| 490 |
| 491 /** |
| 492 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} |
| 493 */ |
| 494 function contentSet() { |
| 495 callback(this._addFile(createFilePath)); |
| 496 } |
| 497 } |
| 498 |
| 499 /** |
| 500 * @override |
| 501 * @param {string} path |
| 502 */ |
| 503 deleteFile(path) { |
| 504 this._fileSystem.deleteFile(path); |
| 505 this.removeUISourceCode(path); |
| 506 } |
| 507 |
| 508 /** |
| 509 * @override |
| 510 */ |
| 511 remove() { |
| 512 this._fileSystemWorkspaceBinding._isolatedFileSystemManager.removeFileSystem
(this._fileSystem); |
| 513 } |
| 514 |
| 515 /** |
| 516 * @param {string} filePath |
| 517 * @return {!WebInspector.UISourceCode} |
| 518 */ |
| 519 _addFile(filePath) { |
| 520 var extension = this._extensionForPath(filePath); |
| 521 var contentType = WebInspector.FileSystemWorkspaceBinding._contentTypeForExt
ension(extension); |
| 522 |
| 523 var uiSourceCode = this.createUISourceCode(this._fileSystemBaseURL + filePat
h, contentType); |
| 524 this.addUISourceCode(uiSourceCode); |
| 525 return uiSourceCode; |
| 526 } |
| 527 |
| 528 /** |
| 529 * @param {string} path |
| 530 */ |
| 531 _fileChanged(path) { |
| 532 var uiSourceCode = this.uiSourceCodeForURL(path); |
| 533 if (!uiSourceCode) { |
| 534 var contentType = WebInspector.FileSystemWorkspaceBinding._contentTypeForE
xtension(this._extensionForPath(path)); |
| 535 this.addUISourceCode(this.createUISourceCode(path, contentType)); |
| 536 return; |
| 537 } |
| 538 uiSourceCode[WebInspector.FileSystemWorkspaceBinding._metadata] = null; |
| 539 uiSourceCode.checkContentUpdated(); |
| 540 } |
| 541 |
| 542 dispose() { |
| 543 this.removeProject(); |
| 544 } |
209 }; | 545 }; |
210 | 546 |
211 WebInspector.FileSystemWorkspaceBinding._metadata = Symbol("FileSystemWorkspaceB
inding.Metadata"); | 547 WebInspector.FileSystemWorkspaceBinding._metadata = Symbol('FileSystemWorkspaceB
inding.Metadata'); |
212 | |
213 WebInspector.FileSystemWorkspaceBinding.FileSystem.prototype = { | |
214 /** | |
215 * @return {string} | |
216 */ | |
217 fileSystemPath: function() | |
218 { | |
219 return this._fileSystemPath; | |
220 }, | |
221 | |
222 /** | |
223 * @return {!Array<string>} | |
224 */ | |
225 gitFolders: function() | |
226 { | |
227 return this._fileSystem.gitFolders().map(folder => this._fileSystemPath
+ "/" + folder); | |
228 }, | |
229 | |
230 /** | |
231 * @param {!WebInspector.UISourceCode} uiSourceCode | |
232 * @return {string} | |
233 */ | |
234 _filePathForUISourceCode: function(uiSourceCode) | |
235 { | |
236 return uiSourceCode.url().substring(this._fileSystemPath.length); | |
237 }, | |
238 | |
239 /** | |
240 * @override | |
241 * @param {!WebInspector.UISourceCode} uiSourceCode | |
242 * @return {!Promise<?WebInspector.UISourceCodeMetadata>} | |
243 */ | |
244 requestMetadata: function(uiSourceCode) | |
245 { | |
246 if (uiSourceCode[WebInspector.FileSystemWorkspaceBinding._metadata]) | |
247 return uiSourceCode[WebInspector.FileSystemWorkspaceBinding._metadat
a]; | |
248 var relativePath = this._filePathForUISourceCode(uiSourceCode); | |
249 var promise = this._fileSystem.getMetadata(relativePath).then(onMetadata
); | |
250 uiSourceCode[WebInspector.FileSystemWorkspaceBinding._metadata] = promis
e; | |
251 return promise; | |
252 | |
253 /** | |
254 * @param {?{modificationTime: !Date, size: number}} metadata | |
255 * @return {?WebInspector.UISourceCodeMetadata} | |
256 */ | |
257 function onMetadata(metadata) | |
258 { | |
259 if (!metadata) | |
260 return null; | |
261 return new WebInspector.UISourceCodeMetadata(metadata.modificationTi
me, metadata.size); | |
262 } | |
263 }, | |
264 | |
265 /** | |
266 * @override | |
267 * @param {!WebInspector.UISourceCode} uiSourceCode | |
268 * @param {function(?string)} callback | |
269 */ | |
270 requestFileContent: function(uiSourceCode, callback) | |
271 { | |
272 var filePath = this._filePathForUISourceCode(uiSourceCode); | |
273 var isImage = WebInspector.FileSystemWorkspaceBinding._imageExtensions.h
as(WebInspector.ParsedURL.extractExtension(filePath)); | |
274 | |
275 this._fileSystem.requestFileContent(filePath, isImage ? base64CallbackWr
apper : callback); | |
276 | |
277 /** | |
278 * @param {?string} result | |
279 */ | |
280 function base64CallbackWrapper(result) | |
281 { | |
282 if (!result) { | |
283 callback(result); | |
284 return; | |
285 } | |
286 var index = result.indexOf(","); | |
287 callback(result.substring(index + 1)); | |
288 } | |
289 }, | |
290 | |
291 /** | |
292 * @override | |
293 * @return {boolean} | |
294 */ | |
295 canSetFileContent: function() | |
296 { | |
297 return true; | |
298 }, | |
299 | |
300 /** | |
301 * @override | |
302 * @param {!WebInspector.UISourceCode} uiSourceCode | |
303 * @param {string} newContent | |
304 * @param {function(?string)} callback | |
305 */ | |
306 setFileContent: function(uiSourceCode, newContent, callback) | |
307 { | |
308 var filePath = this._filePathForUISourceCode(uiSourceCode); | |
309 this._fileSystem.setFileContent(filePath, newContent, callback.bind(this
, "")); | |
310 }, | |
311 | |
312 /** | |
313 * @override | |
314 * @return {boolean} | |
315 */ | |
316 canRename: function() | |
317 { | |
318 return true; | |
319 }, | |
320 | |
321 /** | |
322 * @override | |
323 * @param {!WebInspector.UISourceCode} uiSourceCode | |
324 * @param {string} newName | |
325 * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)}
callback | |
326 */ | |
327 rename: function(uiSourceCode, newName, callback) | |
328 { | |
329 if (newName === uiSourceCode.name()) { | |
330 callback(true, uiSourceCode.name(), uiSourceCode.url(), uiSourceCode
.contentType()); | |
331 return; | |
332 } | |
333 | |
334 var filePath = this._filePathForUISourceCode(uiSourceCode); | |
335 this._fileSystem.renameFile(filePath, newName, innerCallback.bind(this))
; | |
336 | |
337 /** | |
338 * @param {boolean} success | |
339 * @param {string=} newName | |
340 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} | |
341 */ | |
342 function innerCallback(success, newName) | |
343 { | |
344 if (!success || !newName) { | |
345 callback(false, newName); | |
346 return; | |
347 } | |
348 console.assert(newName); | |
349 var slash = filePath.lastIndexOf("/"); | |
350 var parentPath = filePath.substring(0, slash); | |
351 filePath = parentPath + "/" + newName; | |
352 filePath = filePath.substr(1); | |
353 var extension = this._extensionForPath(newName); | |
354 var newURL = this._fileSystemBaseURL + filePath; | |
355 var newContentType = WebInspector.FileSystemWorkspaceBinding._conten
tTypeForExtension(extension); | |
356 this.renameUISourceCode(uiSourceCode, newName); | |
357 callback(true, newName, newURL, newContentType); | |
358 } | |
359 }, | |
360 | |
361 /** | |
362 * @override | |
363 * @param {!WebInspector.UISourceCode} uiSourceCode | |
364 * @param {string} query | |
365 * @param {boolean} caseSensitive | |
366 * @param {boolean} isRegex | |
367 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} cal
lback | |
368 */ | |
369 searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, c
allback) | |
370 { | |
371 var filePath = this._filePathForUISourceCode(uiSourceCode); | |
372 this._fileSystem.requestFileContent(filePath, contentCallback); | |
373 | |
374 /** | |
375 * @param {?string} content | |
376 */ | |
377 function contentCallback(content) | |
378 { | |
379 var result = []; | |
380 if (content !== null) | |
381 result = WebInspector.ContentProvider.performSearchInContent(con
tent, query, caseSensitive, isRegex); | |
382 callback(result); | |
383 } | |
384 }, | |
385 | |
386 /** | |
387 * @override | |
388 * @param {!WebInspector.ProjectSearchConfig} searchConfig | |
389 * @param {!Array.<string>} filesMathingFileQuery | |
390 * @param {!WebInspector.Progress} progress | |
391 * @param {function(!Array.<string>)} callback | |
392 */ | |
393 findFilesMatchingSearchRequest: function(searchConfig, filesMathingFileQuery
, progress, callback) | |
394 { | |
395 var result = filesMathingFileQuery; | |
396 var queriesToRun = searchConfig.queries().slice(); | |
397 if (!queriesToRun.length) | |
398 queriesToRun.push(""); | |
399 progress.setTotalWork(queriesToRun.length); | |
400 searchNextQuery.call(this); | |
401 | |
402 /** | |
403 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} | |
404 */ | |
405 function searchNextQuery() | |
406 { | |
407 if (!queriesToRun.length) { | |
408 progress.done(); | |
409 callback(result); | |
410 return; | |
411 } | |
412 var query = queriesToRun.shift(); | |
413 this._fileSystem.searchInPath(searchConfig.isRegex() ? "" : query, p
rogress, innerCallback.bind(this)); | |
414 } | |
415 | |
416 /** | |
417 * @param {!Array.<string>} files | |
418 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} | |
419 */ | |
420 function innerCallback(files) | |
421 { | |
422 files = files.sort(); | |
423 progress.worked(1); | |
424 result = result.intersectOrdered(files, String.naturalOrderComparato
r); | |
425 searchNextQuery.call(this); | |
426 } | |
427 }, | |
428 | |
429 /** | |
430 * @override | |
431 * @param {!WebInspector.Progress} progress | |
432 */ | |
433 indexContent: function(progress) | |
434 { | |
435 this._fileSystem.indexContent(progress); | |
436 }, | |
437 | |
438 /** | |
439 * @param {string} path | |
440 * @return {string} | |
441 */ | |
442 _extensionForPath: function(path) | |
443 { | |
444 var extensionIndex = path.lastIndexOf("."); | |
445 if (extensionIndex === -1) | |
446 return ""; | |
447 return path.substring(extensionIndex + 1).toLowerCase(); | |
448 }, | |
449 | |
450 populate: function() | |
451 { | |
452 var chunkSize = 1000; | |
453 var filePaths = this._fileSystem.filePaths(); | |
454 reportFileChunk.call(this, 0); | |
455 | |
456 /** | |
457 * @param {number} from | |
458 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} | |
459 */ | |
460 function reportFileChunk(from) | |
461 { | |
462 var to = Math.min(from + chunkSize, filePaths.length); | |
463 for (var i = from; i < to; ++i) | |
464 this._addFile(filePaths[i]); | |
465 if (to < filePaths.length) | |
466 setTimeout(reportFileChunk.bind(this, to), 100); | |
467 } | |
468 }, | |
469 | |
470 /** | |
471 * @override | |
472 * @param {string} url | |
473 */ | |
474 excludeFolder: function(url) | |
475 { | |
476 var relativeFolder = url.substring(this._fileSystemBaseURL.length); | |
477 if (!relativeFolder.startsWith("/")) | |
478 relativeFolder = "/" + relativeFolder; | |
479 if (!relativeFolder.endsWith("/")) | |
480 relativeFolder += "/"; | |
481 this._fileSystem.addExcludedFolder(relativeFolder); | |
482 | |
483 var uiSourceCodes = this.uiSourceCodes().slice(); | |
484 for (var i = 0; i < uiSourceCodes.length; ++i) { | |
485 var uiSourceCode = uiSourceCodes[i]; | |
486 if (uiSourceCode.url().startsWith(url)) | |
487 this.removeUISourceCode(uiSourceCode.url()); | |
488 } | |
489 }, | |
490 | |
491 /** | |
492 * @override | |
493 * @param {string} path | |
494 * @param {?string} name | |
495 * @param {string} content | |
496 * @param {function(?WebInspector.UISourceCode)} callback | |
497 */ | |
498 createFile: function(path, name, content, callback) | |
499 { | |
500 this._fileSystem.createFile(path, name, innerCallback.bind(this)); | |
501 var createFilePath; | |
502 | |
503 /** | |
504 * @param {?string} filePath | |
505 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} | |
506 */ | |
507 function innerCallback(filePath) | |
508 { | |
509 if (!filePath) { | |
510 callback(null); | |
511 return; | |
512 } | |
513 createFilePath = filePath; | |
514 if (!content) { | |
515 contentSet.call(this); | |
516 return; | |
517 } | |
518 this._fileSystem.setFileContent(filePath, content, contentSet.bind(t
his)); | |
519 } | |
520 | |
521 /** | |
522 * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem} | |
523 */ | |
524 function contentSet() | |
525 { | |
526 callback(this._addFile(createFilePath)); | |
527 } | |
528 }, | |
529 | |
530 /** | |
531 * @override | |
532 * @param {string} path | |
533 */ | |
534 deleteFile: function(path) | |
535 { | |
536 this._fileSystem.deleteFile(path); | |
537 this.removeUISourceCode(path); | |
538 }, | |
539 | |
540 /** | |
541 * @override | |
542 */ | |
543 remove: function() | |
544 { | |
545 this._fileSystemWorkspaceBinding._isolatedFileSystemManager.removeFileSy
stem(this._fileSystem); | |
546 }, | |
547 | |
548 /** | |
549 * @param {string} filePath | |
550 * @return {!WebInspector.UISourceCode} | |
551 */ | |
552 _addFile: function(filePath) | |
553 { | |
554 var extension = this._extensionForPath(filePath); | |
555 var contentType = WebInspector.FileSystemWorkspaceBinding._contentTypeFo
rExtension(extension); | |
556 | |
557 var uiSourceCode = this.createUISourceCode(this._fileSystemBaseURL + fil
ePath, contentType); | |
558 this.addUISourceCode(uiSourceCode); | |
559 return uiSourceCode; | |
560 }, | |
561 | |
562 /** | |
563 * @param {string} path | |
564 */ | |
565 _fileChanged: function(path) | |
566 { | |
567 var uiSourceCode = this.uiSourceCodeForURL(path); | |
568 if (!uiSourceCode) { | |
569 var contentType = WebInspector.FileSystemWorkspaceBinding._contentTy
peForExtension(this._extensionForPath(path)); | |
570 this.addUISourceCode(this.createUISourceCode(path, contentType)); | |
571 return; | |
572 } | |
573 uiSourceCode[WebInspector.FileSystemWorkspaceBinding._metadata] = null; | |
574 uiSourceCode.checkContentUpdated(); | |
575 }, | |
576 | |
577 dispose: function() | |
578 { | |
579 this.removeProject(); | |
580 }, | |
581 | |
582 __proto__: WebInspector.ProjectStore.prototype | |
583 }; | |
OLD | NEW |