| 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 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 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 | 30 |
| 31 /** | 31 /** |
| 32 * @constructor | |
| 33 * @extends {WebInspector.ProjectStore} | |
| 34 * @implements {WebInspector.Project} | 32 * @implements {WebInspector.Project} |
| 35 * @param {!WebInspector.Workspace} workspace | 33 * @unrestricted |
| 36 * @param {string} id | |
| 37 * @param {!WebInspector.projectTypes} type | |
| 38 * @param {string} displayName | |
| 39 */ | 34 */ |
| 40 WebInspector.ContentProviderBasedProject = function(workspace, id, type, display
Name) | 35 WebInspector.ContentProviderBasedProject = class extends WebInspector.ProjectSto
re { |
| 41 { | 36 /** |
| 42 WebInspector.ProjectStore.call(this, workspace, id, type, displayName); | 37 * @param {!WebInspector.Workspace} workspace |
| 38 * @param {string} id |
| 39 * @param {!WebInspector.projectTypes} type |
| 40 * @param {string} displayName |
| 41 */ |
| 42 constructor(workspace, id, type, displayName) { |
| 43 super(workspace, id, type, displayName); |
| 43 /** @type {!Object.<string, !WebInspector.ContentProvider>} */ | 44 /** @type {!Object.<string, !WebInspector.ContentProvider>} */ |
| 44 this._contentProviders = {}; | 45 this._contentProviders = {}; |
| 45 workspace.addProject(this); | 46 workspace.addProject(this); |
| 46 }; | 47 } |
| 47 | 48 |
| 48 WebInspector.ContentProviderBasedProject._metadata = Symbol("ContentProviderBase
dProject.Metadata"); | 49 /** |
| 49 | 50 * @override |
| 50 WebInspector.ContentProviderBasedProject.prototype = { | 51 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 52 * @param {function(?string)} callback |
| 53 */ |
| 54 requestFileContent(uiSourceCode, callback) { |
| 55 var contentProvider = this._contentProviders[uiSourceCode.url()]; |
| 56 contentProvider.requestContent().then(callback); |
| 57 } |
| 58 |
| 59 /** |
| 60 * @override |
| 61 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 62 * @return {!Promise<?WebInspector.UISourceCodeMetadata>} |
| 63 */ |
| 64 requestMetadata(uiSourceCode) { |
| 65 return Promise.resolve(uiSourceCode[WebInspector.ContentProviderBasedProject
._metadata]); |
| 66 } |
| 67 |
| 68 /** |
| 69 * @override |
| 70 * @return {boolean} |
| 71 */ |
| 72 canSetFileContent() { |
| 73 return false; |
| 74 } |
| 75 |
| 76 /** |
| 77 * @override |
| 78 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 79 * @param {string} newContent |
| 80 * @param {function(?string)} callback |
| 81 */ |
| 82 setFileContent(uiSourceCode, newContent, callback) { |
| 83 callback(null); |
| 84 } |
| 85 |
| 86 /** |
| 87 * @override |
| 88 * @return {boolean} |
| 89 */ |
| 90 canRename() { |
| 91 return false; |
| 92 } |
| 93 |
| 94 /** |
| 95 * @override |
| 96 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 97 * @param {string} newName |
| 98 * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)} c
allback |
| 99 */ |
| 100 rename(uiSourceCode, newName, callback) { |
| 101 var path = uiSourceCode.url(); |
| 102 this.performRename(path, newName, innerCallback.bind(this)); |
| 103 |
| 51 /** | 104 /** |
| 52 * @override | 105 * @param {boolean} success |
| 53 * @param {!WebInspector.UISourceCode} uiSourceCode | 106 * @param {string=} newName |
| 54 * @param {function(?string)} callback | 107 * @this {WebInspector.ContentProviderBasedProject} |
| 55 */ | 108 */ |
| 56 requestFileContent: function(uiSourceCode, callback) | 109 function innerCallback(success, newName) { |
| 57 { | 110 if (success && newName) { |
| 58 var contentProvider = this._contentProviders[uiSourceCode.url()]; | 111 var copyOfPath = path.split('/'); |
| 59 contentProvider.requestContent().then(callback); | 112 copyOfPath[copyOfPath.length - 1] = newName; |
| 60 }, | 113 var newPath = copyOfPath.join('/'); |
| 61 | 114 this._contentProviders[newPath] = this._contentProviders[path]; |
| 62 /** | 115 delete this._contentProviders[path]; |
| 63 * @override | 116 this.renameUISourceCode(uiSourceCode, newName); |
| 64 * @param {!WebInspector.UISourceCode} uiSourceCode | 117 } |
| 65 * @return {!Promise<?WebInspector.UISourceCodeMetadata>} | 118 callback(success, newName); |
| 66 */ | 119 } |
| 67 requestMetadata: function(uiSourceCode) | 120 } |
| 68 { | 121 |
| 69 return Promise.resolve(uiSourceCode[WebInspector.ContentProviderBasedPro
ject._metadata]); | 122 /** |
| 70 }, | 123 * @override |
| 71 | 124 * @param {string} path |
| 72 /** | 125 */ |
| 73 * @override | 126 excludeFolder(path) { |
| 74 * @return {boolean} | 127 } |
| 75 */ | 128 |
| 76 canSetFileContent: function() | 129 /** |
| 77 { | 130 * @override |
| 78 return false; | 131 * @param {string} path |
| 79 }, | 132 * @param {?string} name |
| 80 | 133 * @param {string} content |
| 81 /** | 134 * @param {function(?WebInspector.UISourceCode)} callback |
| 82 * @override | 135 */ |
| 83 * @param {!WebInspector.UISourceCode} uiSourceCode | 136 createFile(path, name, content, callback) { |
| 84 * @param {string} newContent | 137 } |
| 85 * @param {function(?string)} callback | 138 |
| 86 */ | 139 /** |
| 87 setFileContent: function(uiSourceCode, newContent, callback) | 140 * @override |
| 88 { | 141 * @param {string} path |
| 89 callback(null); | 142 */ |
| 90 }, | 143 deleteFile(path) { |
| 91 | 144 } |
| 92 /** | 145 |
| 93 * @override | 146 /** |
| 94 * @return {boolean} | 147 * @override |
| 95 */ | 148 */ |
| 96 canRename: function() | 149 remove() { |
| 97 { | 150 } |
| 98 return false; | 151 |
| 99 }, | 152 /** |
| 100 | 153 * @param {string} path |
| 101 /** | 154 * @param {string} newName |
| 102 * @override | 155 * @param {function(boolean, string=)} callback |
| 103 * @param {!WebInspector.UISourceCode} uiSourceCode | 156 */ |
| 104 * @param {string} newName | 157 performRename(path, newName, callback) { |
| 105 * @param {function(boolean, string=, string=, !WebInspector.ResourceType=)}
callback | 158 callback(false); |
| 106 */ | 159 } |
| 107 rename: function(uiSourceCode, newName, callback) | 160 |
| 108 { | 161 /** |
| 109 var path = uiSourceCode.url(); | 162 * @override |
| 110 this.performRename(path, newName, innerCallback.bind(this)); | 163 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 111 | 164 * @param {string} query |
| 112 /** | 165 * @param {boolean} caseSensitive |
| 113 * @param {boolean} success | 166 * @param {boolean} isRegex |
| 114 * @param {string=} newName | 167 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callb
ack |
| 115 * @this {WebInspector.ContentProviderBasedProject} | 168 */ |
| 116 */ | 169 searchInFileContent(uiSourceCode, query, caseSensitive, isRegex, callback) { |
| 117 function innerCallback(success, newName) | 170 var contentProvider = this._contentProviders[uiSourceCode.url()]; |
| 118 { | 171 contentProvider.searchInContent(query, caseSensitive, isRegex, callback); |
| 119 if (success && newName) { | 172 } |
| 120 var copyOfPath = path.split("/"); | 173 |
| 121 copyOfPath[copyOfPath.length - 1] = newName; | 174 /** |
| 122 var newPath = copyOfPath.join("/"); | 175 * @override |
| 123 this._contentProviders[newPath] = this._contentProviders[path]; | 176 * @param {!WebInspector.ProjectSearchConfig} searchConfig |
| 124 delete this._contentProviders[path]; | 177 * @param {!Array.<string>} filesMathingFileQuery |
| 125 this.renameUISourceCode(uiSourceCode, newName); | 178 * @param {!WebInspector.Progress} progress |
| 126 } | 179 * @param {function(!Array.<string>)} callback |
| 127 callback(success, newName); | 180 */ |
| 128 } | 181 findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, progress,
callback) { |
| 129 }, | 182 var result = []; |
| 130 | 183 var paths = filesMathingFileQuery; |
| 131 /** | 184 var totalCount = paths.length; |
| 132 * @override | 185 if (totalCount === 0) { |
| 133 * @param {string} path | 186 // searchInContent should call back later. |
| 134 */ | 187 setTimeout(doneCallback, 0); |
| 135 excludeFolder: function(path) | 188 return; |
| 136 { | 189 } |
| 137 }, | 190 |
| 138 | 191 var barrier = new CallbackBarrier(); |
| 139 /** | 192 progress.setTotalWork(paths.length); |
| 140 * @override | 193 for (var i = 0; i < paths.length; ++i) |
| 141 * @param {string} path | 194 searchInContent.call(this, paths[i], barrier.createCallback(searchInConten
tCallback.bind(null, paths[i]))); |
| 142 * @param {?string} name | 195 barrier.callWhenDone(doneCallback); |
| 143 * @param {string} content | |
| 144 * @param {function(?WebInspector.UISourceCode)} callback | |
| 145 */ | |
| 146 createFile: function(path, name, content, callback) | |
| 147 { | |
| 148 }, | |
| 149 | |
| 150 /** | |
| 151 * @override | |
| 152 * @param {string} path | |
| 153 */ | |
| 154 deleteFile: function(path) | |
| 155 { | |
| 156 }, | |
| 157 | |
| 158 /** | |
| 159 * @override | |
| 160 */ | |
| 161 remove: function() | |
| 162 { | |
| 163 }, | |
| 164 | 196 |
| 165 /** | 197 /** |
| 166 * @param {string} path | 198 * @param {string} path |
| 167 * @param {string} newName | 199 * @param {function(boolean)} callback |
| 168 * @param {function(boolean, string=)} callback | 200 * @this {WebInspector.ContentProviderBasedProject} |
| 169 */ | 201 */ |
| 170 performRename: function(path, newName, callback) | 202 function searchInContent(path, callback) { |
| 171 { | 203 var queriesToRun = searchConfig.queries().slice(); |
| 172 callback(false); | 204 searchNextQuery.call(this); |
| 173 }, | 205 |
| 174 | 206 /** |
| 175 /** | 207 * @this {WebInspector.ContentProviderBasedProject} |
| 176 * @override | 208 */ |
| 177 * @param {!WebInspector.UISourceCode} uiSourceCode | 209 function searchNextQuery() { |
| 178 * @param {string} query | 210 if (!queriesToRun.length) { |
| 179 * @param {boolean} caseSensitive | 211 callback(true); |
| 180 * @param {boolean} isRegex | 212 return; |
| 181 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} cal
lback | |
| 182 */ | |
| 183 searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, c
allback) | |
| 184 { | |
| 185 var contentProvider = this._contentProviders[uiSourceCode.url()]; | |
| 186 contentProvider.searchInContent(query, caseSensitive, isRegex, callback)
; | |
| 187 }, | |
| 188 | |
| 189 /** | |
| 190 * @override | |
| 191 * @param {!WebInspector.ProjectSearchConfig} searchConfig | |
| 192 * @param {!Array.<string>} filesMathingFileQuery | |
| 193 * @param {!WebInspector.Progress} progress | |
| 194 * @param {function(!Array.<string>)} callback | |
| 195 */ | |
| 196 findFilesMatchingSearchRequest: function(searchConfig, filesMathingFileQuery
, progress, callback) | |
| 197 { | |
| 198 var result = []; | |
| 199 var paths = filesMathingFileQuery; | |
| 200 var totalCount = paths.length; | |
| 201 if (totalCount === 0) { | |
| 202 // searchInContent should call back later. | |
| 203 setTimeout(doneCallback, 0); | |
| 204 return; | |
| 205 } | 213 } |
| 206 | 214 var query = queriesToRun.shift(); |
| 207 var barrier = new CallbackBarrier(); | 215 this._contentProviders[path].searchInContent( |
| 208 progress.setTotalWork(paths.length); | 216 query, !searchConfig.ignoreCase(), searchConfig.isRegex(), contentCa
llback.bind(this)); |
| 209 for (var i = 0; i < paths.length; ++i) | 217 } |
| 210 searchInContent.call(this, paths[i], barrier.createCallback(searchIn
ContentCallback.bind(null, paths[i]))); | 218 |
| 211 barrier.callWhenDone(doneCallback); | 219 /** |
| 212 | 220 * @param {!Array.<!WebInspector.ContentProvider.SearchMatch>} searchMatch
es |
| 213 /** | 221 * @this {WebInspector.ContentProviderBasedProject} |
| 214 * @param {string} path | 222 */ |
| 215 * @param {function(boolean)} callback | 223 function contentCallback(searchMatches) { |
| 216 * @this {WebInspector.ContentProviderBasedProject} | 224 if (!searchMatches.length) { |
| 217 */ | 225 callback(false); |
| 218 function searchInContent(path, callback) | 226 return; |
| 219 { | |
| 220 var queriesToRun = searchConfig.queries().slice(); | |
| 221 searchNextQuery.call(this); | |
| 222 | |
| 223 /** | |
| 224 * @this {WebInspector.ContentProviderBasedProject} | |
| 225 */ | |
| 226 function searchNextQuery() | |
| 227 { | |
| 228 if (!queriesToRun.length) { | |
| 229 callback(true); | |
| 230 return; | |
| 231 } | |
| 232 var query = queriesToRun.shift(); | |
| 233 this._contentProviders[path].searchInContent(query, !searchConfi
g.ignoreCase(), searchConfig.isRegex(), contentCallback.bind(this)); | |
| 234 } | |
| 235 | |
| 236 /** | |
| 237 * @param {!Array.<!WebInspector.ContentProvider.SearchMatch>} searc
hMatches | |
| 238 * @this {WebInspector.ContentProviderBasedProject} | |
| 239 */ | |
| 240 function contentCallback(searchMatches) | |
| 241 { | |
| 242 if (!searchMatches.length) { | |
| 243 callback(false); | |
| 244 return; | |
| 245 } | |
| 246 searchNextQuery.call(this); | |
| 247 } | |
| 248 } | 227 } |
| 249 | 228 searchNextQuery.call(this); |
| 250 /** | 229 } |
| 251 * @param {string} path | 230 } |
| 252 * @param {boolean} matches | |
| 253 */ | |
| 254 function searchInContentCallback(path, matches) | |
| 255 { | |
| 256 if (matches) | |
| 257 result.push(path); | |
| 258 progress.worked(1); | |
| 259 } | |
| 260 | |
| 261 function doneCallback() | |
| 262 { | |
| 263 callback(result); | |
| 264 progress.done(); | |
| 265 } | |
| 266 }, | |
| 267 | |
| 268 /** | |
| 269 * @override | |
| 270 * @param {!WebInspector.Progress} progress | |
| 271 */ | |
| 272 indexContent: function(progress) | |
| 273 { | |
| 274 setImmediate(progress.done.bind(progress)); | |
| 275 }, | |
| 276 | |
| 277 /** | |
| 278 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 279 * @param {!WebInspector.ContentProvider} contentProvider | |
| 280 * @param {?WebInspector.UISourceCodeMetadata} metadata | |
| 281 */ | |
| 282 addUISourceCodeWithProvider: function(uiSourceCode, contentProvider, metadat
a) | |
| 283 { | |
| 284 this._contentProviders[uiSourceCode.url()] = contentProvider; | |
| 285 uiSourceCode[WebInspector.ContentProviderBasedProject._metadata] = metad
ata; | |
| 286 this.addUISourceCode(uiSourceCode, true); | |
| 287 }, | |
| 288 | |
| 289 /** | |
| 290 * @param {string} url | |
| 291 * @param {!WebInspector.ContentProvider} contentProvider | |
| 292 * @return {!WebInspector.UISourceCode} | |
| 293 */ | |
| 294 addContentProvider: function(url, contentProvider) | |
| 295 { | |
| 296 var uiSourceCode = this.createUISourceCode(url, contentProvider.contentT
ype()); | |
| 297 this.addUISourceCodeWithProvider(uiSourceCode, contentProvider, null); | |
| 298 return uiSourceCode; | |
| 299 }, | |
| 300 | 231 |
| 301 /** | 232 /** |
| 302 * @param {string} path | 233 * @param {string} path |
| 234 * @param {boolean} matches |
| 303 */ | 235 */ |
| 304 removeFile: function(path) | 236 function searchInContentCallback(path, matches) { |
| 305 { | 237 if (matches) |
| 306 delete this._contentProviders[path]; | 238 result.push(path); |
| 307 this.removeUISourceCode(path); | 239 progress.worked(1); |
| 308 }, | 240 } |
| 309 | 241 |
| 310 reset: function() | 242 function doneCallback() { |
| 311 { | 243 callback(result); |
| 312 this._contentProviders = {}; | 244 progress.done(); |
| 313 this.removeProject(); | 245 } |
| 314 this.workspace().addProject(this); | 246 } |
| 315 }, | 247 |
| 316 | 248 /** |
| 317 dispose: function() | 249 * @override |
| 318 { | 250 * @param {!WebInspector.Progress} progress |
| 319 this._contentProviders = {}; | 251 */ |
| 320 this.removeProject(); | 252 indexContent(progress) { |
| 321 }, | 253 setImmediate(progress.done.bind(progress)); |
| 322 | 254 } |
| 323 __proto__: WebInspector.ProjectStore.prototype | 255 |
| 256 /** |
| 257 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 258 * @param {!WebInspector.ContentProvider} contentProvider |
| 259 * @param {?WebInspector.UISourceCodeMetadata} metadata |
| 260 */ |
| 261 addUISourceCodeWithProvider(uiSourceCode, contentProvider, metadata) { |
| 262 this._contentProviders[uiSourceCode.url()] = contentProvider; |
| 263 uiSourceCode[WebInspector.ContentProviderBasedProject._metadata] = metadata; |
| 264 this.addUISourceCode(uiSourceCode, true); |
| 265 } |
| 266 |
| 267 /** |
| 268 * @param {string} url |
| 269 * @param {!WebInspector.ContentProvider} contentProvider |
| 270 * @return {!WebInspector.UISourceCode} |
| 271 */ |
| 272 addContentProvider(url, contentProvider) { |
| 273 var uiSourceCode = this.createUISourceCode(url, contentProvider.contentType(
)); |
| 274 this.addUISourceCodeWithProvider(uiSourceCode, contentProvider, null); |
| 275 return uiSourceCode; |
| 276 } |
| 277 |
| 278 /** |
| 279 * @param {string} path |
| 280 */ |
| 281 removeFile(path) { |
| 282 delete this._contentProviders[path]; |
| 283 this.removeUISourceCode(path); |
| 284 } |
| 285 |
| 286 reset() { |
| 287 this._contentProviders = {}; |
| 288 this.removeProject(); |
| 289 this.workspace().addProject(this); |
| 290 } |
| 291 |
| 292 dispose() { |
| 293 this._contentProviders = {}; |
| 294 this.removeProject(); |
| 295 } |
| 324 }; | 296 }; |
| 297 |
| 298 WebInspector.ContentProviderBasedProject._metadata = Symbol('ContentProviderBase
dProject.Metadata'); |
| OLD | NEW |