| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 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 * @extends {WebInspector.Object} | |
| 34 */ | 32 */ |
| 35 WebInspector.FileSystemMapping = function() | 33 WebInspector.FileSystemMapping = class extends WebInspector.Object { |
| 36 { | 34 constructor() { |
| 37 WebInspector.Object.call(this); | 35 super(); |
| 38 this._fileSystemMappingSetting = WebInspector.settings.createLocalSetting("f
ileSystemMapping", {}); | 36 this._fileSystemMappingSetting = WebInspector.settings.createLocalSetting('f
ileSystemMapping', {}); |
| 39 /** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.Entry>>}
*/ | 37 /** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.Entry>>}
*/ |
| 40 this._fileSystemMappings = {}; | 38 this._fileSystemMappings = {}; |
| 41 this._loadFromSettings(); | 39 this._loadFromSettings(); |
| 40 } |
| 41 |
| 42 _loadFromSettings() { |
| 43 var savedMapping = this._fileSystemMappingSetting.get(); |
| 44 this._fileSystemMappings = {}; |
| 45 for (var fileSystemPath in savedMapping) { |
| 46 var savedFileSystemMappings = savedMapping[fileSystemPath]; |
| 47 fileSystemPath = WebInspector.ParsedURL.platformPathToURL(fileSystemPath); |
| 48 this._fileSystemMappings[fileSystemPath] = []; |
| 49 var fileSystemMappings = this._fileSystemMappings[fileSystemPath]; |
| 50 |
| 51 for (var i = 0; i < savedFileSystemMappings.length; ++i) { |
| 52 var savedEntry = savedFileSystemMappings[i]; |
| 53 var entry = |
| 54 new WebInspector.FileSystemMapping.Entry(fileSystemPath, savedEntry.
urlPrefix, savedEntry.pathPrefix, true); |
| 55 fileSystemMappings.push(entry); |
| 56 } |
| 57 } |
| 58 |
| 59 this._rebuildIndexes(); |
| 60 } |
| 61 |
| 62 _saveToSettings() { |
| 63 var setting = {}; |
| 64 for (var fileSystemPath in this._fileSystemMappings) { |
| 65 setting[fileSystemPath] = []; |
| 66 var entries = this._fileSystemMappings[fileSystemPath]; |
| 67 for (var entry of entries) { |
| 68 if (entry.configurable) |
| 69 setting[fileSystemPath].push(entry); |
| 70 } |
| 71 } |
| 72 this._fileSystemMappingSetting.set(setting); |
| 73 } |
| 74 |
| 75 _rebuildIndexes() { |
| 76 // We are building an index here to search for the longest url prefix match
faster. |
| 77 this._mappingForURLPrefix = {}; |
| 78 this._urlPrefixes = []; |
| 79 for (var fileSystemPath in this._fileSystemMappings) { |
| 80 var fileSystemMapping = this._fileSystemMappings[fileSystemPath]; |
| 81 for (var i = 0; i < fileSystemMapping.length; ++i) { |
| 82 var entry = fileSystemMapping[i]; |
| 83 // Resolve conflict in favor of configurable mapping. |
| 84 if (this._mappingForURLPrefix[entry.urlPrefix] && !entry.configurable) |
| 85 continue; |
| 86 this._mappingForURLPrefix[entry.urlPrefix] = entry; |
| 87 if (this._urlPrefixes.indexOf(entry.urlPrefix) === -1) |
| 88 this._urlPrefixes.push(entry.urlPrefix); |
| 89 } |
| 90 } |
| 91 this._urlPrefixes.sort(); |
| 92 } |
| 93 |
| 94 /** |
| 95 * @param {string} fileSystemPath |
| 96 */ |
| 97 addFileSystem(fileSystemPath) { |
| 98 if (this._fileSystemMappings[fileSystemPath]) |
| 99 return; |
| 100 |
| 101 this._fileSystemMappings[fileSystemPath] = []; |
| 102 this._saveToSettings(); |
| 103 } |
| 104 |
| 105 /** |
| 106 * @param {string} fileSystemPath |
| 107 */ |
| 108 removeFileSystem(fileSystemPath) { |
| 109 if (!this._fileSystemMappings[fileSystemPath]) |
| 110 return; |
| 111 delete this._fileSystemMappings[fileSystemPath]; |
| 112 this._rebuildIndexes(); |
| 113 this._saveToSettings(); |
| 114 } |
| 115 |
| 116 /** |
| 117 * @param {string} fileSystemPath |
| 118 * @param {string} urlPrefix |
| 119 * @param {string} pathPrefix |
| 120 */ |
| 121 addFileMapping(fileSystemPath, urlPrefix, pathPrefix) { |
| 122 if (!urlPrefix.endsWith('/')) |
| 123 urlPrefix += '/'; |
| 124 if (!pathPrefix.endsWith('/')) |
| 125 pathPrefix += '/'; |
| 126 if (!pathPrefix.startsWith('/')) |
| 127 pathPrefix = '/' + pathPrefix; |
| 128 this._innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, true); |
| 129 this._saveToSettings(); |
| 130 } |
| 131 |
| 132 /** |
| 133 * @param {string} fileSystemPath |
| 134 * @param {string} urlPrefix |
| 135 * @param {string} pathPrefix |
| 136 */ |
| 137 addNonConfigurableFileMapping(fileSystemPath, urlPrefix, pathPrefix) { |
| 138 this._innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, false); |
| 139 } |
| 140 |
| 141 /** |
| 142 * @param {string} fileSystemPath |
| 143 * @param {string} urlPrefix |
| 144 * @param {string} pathPrefix |
| 145 * @param {boolean} configurable |
| 146 */ |
| 147 _innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, configurable) { |
| 148 var entry = new WebInspector.FileSystemMapping.Entry(fileSystemPath, urlPref
ix, pathPrefix, configurable); |
| 149 this._fileSystemMappings[fileSystemPath].push(entry); |
| 150 this._rebuildIndexes(); |
| 151 this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.FileMapp
ingAdded, entry); |
| 152 } |
| 153 |
| 154 /** |
| 155 * @param {string} fileSystemPath |
| 156 * @param {string} urlPrefix |
| 157 * @param {string} pathPrefix |
| 158 */ |
| 159 removeFileMapping(fileSystemPath, urlPrefix, pathPrefix) { |
| 160 var entry = this._configurableMappingEntryForPathPrefix(fileSystemPath, path
Prefix); |
| 161 if (!entry) |
| 162 return; |
| 163 this._fileSystemMappings[fileSystemPath].remove(entry); |
| 164 this._rebuildIndexes(); |
| 165 this._saveToSettings(); |
| 166 this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.FileMapp
ingRemoved, entry); |
| 167 } |
| 168 |
| 169 /** |
| 170 * @param {string} url |
| 171 * @return {?WebInspector.FileSystemMapping.Entry} |
| 172 */ |
| 173 _mappingEntryForURL(url) { |
| 174 for (var i = this._urlPrefixes.length - 1; i >= 0; --i) { |
| 175 var urlPrefix = this._urlPrefixes[i]; |
| 176 if (url.startsWith(urlPrefix)) |
| 177 return this._mappingForURLPrefix[urlPrefix]; |
| 178 } |
| 179 return null; |
| 180 } |
| 181 |
| 182 /** |
| 183 * @param {string} fileSystemPath |
| 184 * @param {string} filePath |
| 185 * @return {?WebInspector.FileSystemMapping.Entry} |
| 186 */ |
| 187 _mappingEntryForPath(fileSystemPath, filePath) { |
| 188 var entries = this._fileSystemMappings[fileSystemPath]; |
| 189 if (!entries) |
| 190 return null; |
| 191 |
| 192 var entry = null; |
| 193 for (var i = 0; i < entries.length; ++i) { |
| 194 var pathPrefix = entries[i].pathPrefix; |
| 195 if (entry && entry.configurable && !entries[i].configurable) |
| 196 continue; |
| 197 // We are looking for the longest pathPrefix match. |
| 198 if (entry && entry.pathPrefix.length > pathPrefix.length) |
| 199 continue; |
| 200 if (filePath.startsWith(pathPrefix)) |
| 201 entry = entries[i]; |
| 202 } |
| 203 return entry; |
| 204 } |
| 205 |
| 206 /** |
| 207 * @param {string} fileSystemPath |
| 208 * @param {string} pathPrefix |
| 209 * @return {?WebInspector.FileSystemMapping.Entry} |
| 210 */ |
| 211 _configurableMappingEntryForPathPrefix(fileSystemPath, pathPrefix) { |
| 212 var entries = this._fileSystemMappings[fileSystemPath]; |
| 213 for (var i = 0; i < entries.length; ++i) { |
| 214 if (entries[i].configurable && pathPrefix === entries[i].pathPrefix) |
| 215 return entries[i]; |
| 216 } |
| 217 return null; |
| 218 } |
| 219 |
| 220 /** |
| 221 * @param {string} fileSystemPath |
| 222 * @return {!Array.<!WebInspector.FileSystemMapping.Entry>} |
| 223 */ |
| 224 mappingEntries(fileSystemPath) { |
| 225 return this._fileSystemMappings[fileSystemPath].slice(); |
| 226 } |
| 227 |
| 228 /** |
| 229 * @param {string} url |
| 230 * @return {boolean} |
| 231 */ |
| 232 hasMappingForNetworkURL(url) { |
| 233 return !!this._mappingEntryForURL(url); |
| 234 } |
| 235 |
| 236 /** |
| 237 * @param {string} url |
| 238 * @return {?{fileSystemPath: string, fileURL: string}} |
| 239 */ |
| 240 fileForURL(url) { |
| 241 var entry = this._mappingEntryForURL(url); |
| 242 if (!entry) |
| 243 return null; |
| 244 var file = {}; |
| 245 file.fileSystemPath = entry.fileSystemPath; |
| 246 file.fileURL = entry.fileSystemPath + entry.pathPrefix + url.substr(entry.ur
lPrefix.length); |
| 247 return file; |
| 248 } |
| 249 |
| 250 /** |
| 251 * @param {string} fileSystemPath |
| 252 * @param {string} filePath |
| 253 * @return {string} |
| 254 */ |
| 255 networkURLForFileSystemURL(fileSystemPath, filePath) { |
| 256 var relativePath = filePath.substring(fileSystemPath.length); |
| 257 var entry = this._mappingEntryForPath(fileSystemPath, relativePath); |
| 258 if (!entry) |
| 259 return ''; |
| 260 return entry.urlPrefix + relativePath.substring(entry.pathPrefix.length); |
| 261 } |
| 262 |
| 263 /** |
| 264 * @param {string} url |
| 265 */ |
| 266 removeMappingForURL(url) { |
| 267 var entry = this._mappingEntryForURL(url); |
| 268 if (!entry || !entry.configurable) |
| 269 return; |
| 270 this._fileSystemMappings[entry.fileSystemPath].remove(entry); |
| 271 this._saveToSettings(); |
| 272 } |
| 273 |
| 274 /** |
| 275 * @param {string} url |
| 276 * @param {string} fileSystemPath |
| 277 * @param {string} filePath |
| 278 */ |
| 279 addMappingForResource(url, fileSystemPath, filePath) { |
| 280 var commonPathSuffixLength = 0; |
| 281 for (var i = 0; i < filePath.length; ++i) { |
| 282 var filePathCharacter = filePath[filePath.length - 1 - i]; |
| 283 var urlCharacter = url[url.length - 1 - i]; |
| 284 if (filePathCharacter !== urlCharacter) |
| 285 break; |
| 286 if (filePathCharacter === '/') |
| 287 commonPathSuffixLength = i; |
| 288 } |
| 289 var from = fileSystemPath.length; |
| 290 var to = filePath.length - commonPathSuffixLength; |
| 291 var pathPrefix = filePath.substring(from, to); |
| 292 var urlPrefix = url.substr(0, url.length - commonPathSuffixLength); |
| 293 if (to >= from) |
| 294 this.addFileMapping(fileSystemPath, urlPrefix, pathPrefix); |
| 295 else |
| 296 this.addFileMapping(fileSystemPath, urlPrefix + pathPrefix, '/'); |
| 297 } |
| 298 |
| 299 resetForTesting() { |
| 300 this._fileSystemMappings = {}; |
| 301 } |
| 42 }; | 302 }; |
| 43 | 303 |
| 44 /** @enum {symbol} */ | 304 /** @enum {symbol} */ |
| 45 WebInspector.FileSystemMapping.Events = { | 305 WebInspector.FileSystemMapping.Events = { |
| 46 FileMappingAdded: Symbol("FileMappingAdded"), | 306 FileMappingAdded: Symbol('FileMappingAdded'), |
| 47 FileMappingRemoved: Symbol("FileMappingRemoved") | 307 FileMappingRemoved: Symbol('FileMappingRemoved') |
| 48 }; | 308 }; |
| 49 | 309 |
| 50 WebInspector.FileSystemMapping.prototype = { | |
| 51 _loadFromSettings: function() | |
| 52 { | |
| 53 var savedMapping = this._fileSystemMappingSetting.get(); | |
| 54 this._fileSystemMappings = {}; | |
| 55 for (var fileSystemPath in savedMapping) { | |
| 56 var savedFileSystemMappings = savedMapping[fileSystemPath]; | |
| 57 fileSystemPath = WebInspector.ParsedURL.platformPathToURL(fileSystem
Path); | |
| 58 this._fileSystemMappings[fileSystemPath] = []; | |
| 59 var fileSystemMappings = this._fileSystemMappings[fileSystemPath]; | |
| 60 | |
| 61 for (var i = 0; i < savedFileSystemMappings.length; ++i) { | |
| 62 var savedEntry = savedFileSystemMappings[i]; | |
| 63 var entry = new WebInspector.FileSystemMapping.Entry(fileSystemP
ath, savedEntry.urlPrefix, savedEntry.pathPrefix, true); | |
| 64 fileSystemMappings.push(entry); | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 this._rebuildIndexes(); | |
| 69 }, | |
| 70 | |
| 71 _saveToSettings: function() | |
| 72 { | |
| 73 var setting = {}; | |
| 74 for (var fileSystemPath in this._fileSystemMappings) { | |
| 75 setting[fileSystemPath] = []; | |
| 76 var entries = this._fileSystemMappings[fileSystemPath]; | |
| 77 for (var entry of entries) { | |
| 78 if (entry.configurable) | |
| 79 setting[fileSystemPath].push(entry); | |
| 80 } | |
| 81 } | |
| 82 this._fileSystemMappingSetting.set(setting); | |
| 83 }, | |
| 84 | |
| 85 _rebuildIndexes: function() | |
| 86 { | |
| 87 // We are building an index here to search for the longest url prefix ma
tch faster. | |
| 88 this._mappingForURLPrefix = {}; | |
| 89 this._urlPrefixes = []; | |
| 90 for (var fileSystemPath in this._fileSystemMappings) { | |
| 91 var fileSystemMapping = this._fileSystemMappings[fileSystemPath]; | |
| 92 for (var i = 0; i < fileSystemMapping.length; ++i) { | |
| 93 var entry = fileSystemMapping[i]; | |
| 94 // Resolve conflict in favor of configurable mapping. | |
| 95 if (this._mappingForURLPrefix[entry.urlPrefix] && !entry.configu
rable) | |
| 96 continue; | |
| 97 this._mappingForURLPrefix[entry.urlPrefix] = entry; | |
| 98 if (this._urlPrefixes.indexOf(entry.urlPrefix) === -1) | |
| 99 this._urlPrefixes.push(entry.urlPrefix); | |
| 100 } | |
| 101 } | |
| 102 this._urlPrefixes.sort(); | |
| 103 }, | |
| 104 | |
| 105 /** | |
| 106 * @param {string} fileSystemPath | |
| 107 */ | |
| 108 addFileSystem: function(fileSystemPath) | |
| 109 { | |
| 110 if (this._fileSystemMappings[fileSystemPath]) | |
| 111 return; | |
| 112 | |
| 113 this._fileSystemMappings[fileSystemPath] = []; | |
| 114 this._saveToSettings(); | |
| 115 }, | |
| 116 | |
| 117 /** | |
| 118 * @param {string} fileSystemPath | |
| 119 */ | |
| 120 removeFileSystem: function(fileSystemPath) | |
| 121 { | |
| 122 if (!this._fileSystemMappings[fileSystemPath]) | |
| 123 return; | |
| 124 delete this._fileSystemMappings[fileSystemPath]; | |
| 125 this._rebuildIndexes(); | |
| 126 this._saveToSettings(); | |
| 127 }, | |
| 128 | |
| 129 /** | |
| 130 * @param {string} fileSystemPath | |
| 131 * @param {string} urlPrefix | |
| 132 * @param {string} pathPrefix | |
| 133 */ | |
| 134 addFileMapping: function(fileSystemPath, urlPrefix, pathPrefix) | |
| 135 { | |
| 136 if (!urlPrefix.endsWith("/")) | |
| 137 urlPrefix += "/"; | |
| 138 if (!pathPrefix.endsWith("/")) | |
| 139 pathPrefix += "/"; | |
| 140 if (!pathPrefix.startsWith("/")) | |
| 141 pathPrefix = "/" + pathPrefix; | |
| 142 this._innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, true); | |
| 143 this._saveToSettings(); | |
| 144 }, | |
| 145 | |
| 146 /** | |
| 147 * @param {string} fileSystemPath | |
| 148 * @param {string} urlPrefix | |
| 149 * @param {string} pathPrefix | |
| 150 */ | |
| 151 addNonConfigurableFileMapping: function(fileSystemPath, urlPrefix, pathPrefi
x) | |
| 152 { | |
| 153 this._innerAddFileMapping(fileSystemPath, urlPrefix, pathPrefix, false); | |
| 154 }, | |
| 155 | |
| 156 /** | |
| 157 * @param {string} fileSystemPath | |
| 158 * @param {string} urlPrefix | |
| 159 * @param {string} pathPrefix | |
| 160 * @param {boolean} configurable | |
| 161 */ | |
| 162 _innerAddFileMapping: function(fileSystemPath, urlPrefix, pathPrefix, config
urable) | |
| 163 { | |
| 164 var entry = new WebInspector.FileSystemMapping.Entry(fileSystemPath, url
Prefix, pathPrefix, configurable); | |
| 165 this._fileSystemMappings[fileSystemPath].push(entry); | |
| 166 this._rebuildIndexes(); | |
| 167 this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.File
MappingAdded, entry); | |
| 168 }, | |
| 169 | |
| 170 /** | |
| 171 * @param {string} fileSystemPath | |
| 172 * @param {string} urlPrefix | |
| 173 * @param {string} pathPrefix | |
| 174 */ | |
| 175 removeFileMapping: function(fileSystemPath, urlPrefix, pathPrefix) | |
| 176 { | |
| 177 var entry = this._configurableMappingEntryForPathPrefix(fileSystemPath,
pathPrefix); | |
| 178 if (!entry) | |
| 179 return; | |
| 180 this._fileSystemMappings[fileSystemPath].remove(entry); | |
| 181 this._rebuildIndexes(); | |
| 182 this._saveToSettings(); | |
| 183 this.dispatchEventToListeners(WebInspector.FileSystemMapping.Events.File
MappingRemoved, entry); | |
| 184 }, | |
| 185 | |
| 186 /** | |
| 187 * @param {string} url | |
| 188 * @return {?WebInspector.FileSystemMapping.Entry} | |
| 189 */ | |
| 190 _mappingEntryForURL: function(url) | |
| 191 { | |
| 192 for (var i = this._urlPrefixes.length - 1; i >= 0; --i) { | |
| 193 var urlPrefix = this._urlPrefixes[i]; | |
| 194 if (url.startsWith(urlPrefix)) | |
| 195 return this._mappingForURLPrefix[urlPrefix]; | |
| 196 } | |
| 197 return null; | |
| 198 }, | |
| 199 | |
| 200 /** | |
| 201 * @param {string} fileSystemPath | |
| 202 * @param {string} filePath | |
| 203 * @return {?WebInspector.FileSystemMapping.Entry} | |
| 204 */ | |
| 205 _mappingEntryForPath: function(fileSystemPath, filePath) | |
| 206 { | |
| 207 var entries = this._fileSystemMappings[fileSystemPath]; | |
| 208 if (!entries) | |
| 209 return null; | |
| 210 | |
| 211 var entry = null; | |
| 212 for (var i = 0; i < entries.length; ++i) { | |
| 213 var pathPrefix = entries[i].pathPrefix; | |
| 214 if (entry && entry.configurable && !entries[i].configurable) | |
| 215 continue; | |
| 216 // We are looking for the longest pathPrefix match. | |
| 217 if (entry && entry.pathPrefix.length > pathPrefix.length) | |
| 218 continue; | |
| 219 if (filePath.startsWith(pathPrefix)) | |
| 220 entry = entries[i]; | |
| 221 } | |
| 222 return entry; | |
| 223 }, | |
| 224 | |
| 225 /** | |
| 226 * @param {string} fileSystemPath | |
| 227 * @param {string} pathPrefix | |
| 228 * @return {?WebInspector.FileSystemMapping.Entry} | |
| 229 */ | |
| 230 _configurableMappingEntryForPathPrefix: function(fileSystemPath, pathPrefix) | |
| 231 { | |
| 232 var entries = this._fileSystemMappings[fileSystemPath]; | |
| 233 for (var i = 0; i < entries.length; ++i) { | |
| 234 if (entries[i].configurable && pathPrefix === entries[i].pathPrefix) | |
| 235 return entries[i]; | |
| 236 } | |
| 237 return null; | |
| 238 }, | |
| 239 | |
| 240 /** | |
| 241 * @param {string} fileSystemPath | |
| 242 * @return {!Array.<!WebInspector.FileSystemMapping.Entry>} | |
| 243 */ | |
| 244 mappingEntries: function(fileSystemPath) | |
| 245 { | |
| 246 return this._fileSystemMappings[fileSystemPath].slice(); | |
| 247 }, | |
| 248 | |
| 249 /** | |
| 250 * @param {string} url | |
| 251 * @return {boolean} | |
| 252 */ | |
| 253 hasMappingForNetworkURL: function(url) | |
| 254 { | |
| 255 return !!this._mappingEntryForURL(url); | |
| 256 }, | |
| 257 | |
| 258 /** | |
| 259 * @param {string} url | |
| 260 * @return {?{fileSystemPath: string, fileURL: string}} | |
| 261 */ | |
| 262 fileForURL: function(url) | |
| 263 { | |
| 264 var entry = this._mappingEntryForURL(url); | |
| 265 if (!entry) | |
| 266 return null; | |
| 267 var file = {}; | |
| 268 file.fileSystemPath = entry.fileSystemPath; | |
| 269 file.fileURL = entry.fileSystemPath + entry.pathPrefix + url.substr(entr
y.urlPrefix.length); | |
| 270 return file; | |
| 271 }, | |
| 272 | |
| 273 /** | |
| 274 * @param {string} fileSystemPath | |
| 275 * @param {string} filePath | |
| 276 * @return {string} | |
| 277 */ | |
| 278 networkURLForFileSystemURL: function(fileSystemPath, filePath) | |
| 279 { | |
| 280 var relativePath = filePath.substring(fileSystemPath.length); | |
| 281 var entry = this._mappingEntryForPath(fileSystemPath, relativePath); | |
| 282 if (!entry) | |
| 283 return ""; | |
| 284 return entry.urlPrefix + relativePath.substring(entry.pathPrefix.length)
; | |
| 285 }, | |
| 286 | |
| 287 /** | |
| 288 * @param {string} url | |
| 289 */ | |
| 290 removeMappingForURL: function(url) | |
| 291 { | |
| 292 var entry = this._mappingEntryForURL(url); | |
| 293 if (!entry || !entry.configurable) | |
| 294 return; | |
| 295 this._fileSystemMappings[entry.fileSystemPath].remove(entry); | |
| 296 this._saveToSettings(); | |
| 297 }, | |
| 298 | |
| 299 /** | |
| 300 * @param {string} url | |
| 301 * @param {string} fileSystemPath | |
| 302 * @param {string} filePath | |
| 303 */ | |
| 304 addMappingForResource: function(url, fileSystemPath, filePath) | |
| 305 { | |
| 306 var commonPathSuffixLength = 0; | |
| 307 for (var i = 0; i < filePath.length; ++i) { | |
| 308 var filePathCharacter = filePath[filePath.length - 1 - i]; | |
| 309 var urlCharacter = url[url.length - 1 - i]; | |
| 310 if (filePathCharacter !== urlCharacter) | |
| 311 break; | |
| 312 if (filePathCharacter === "/") | |
| 313 commonPathSuffixLength = i; | |
| 314 } | |
| 315 var from = fileSystemPath.length; | |
| 316 var to = filePath.length - commonPathSuffixLength; | |
| 317 var pathPrefix = filePath.substring(from, to); | |
| 318 var urlPrefix = url.substr(0, url.length - commonPathSuffixLength); | |
| 319 if (to >= from) | |
| 320 this.addFileMapping(fileSystemPath, urlPrefix, pathPrefix); | |
| 321 else | |
| 322 this.addFileMapping(fileSystemPath, urlPrefix + pathPrefix, "/"); | |
| 323 }, | |
| 324 | |
| 325 resetForTesting: function() | |
| 326 { | |
| 327 this._fileSystemMappings = {}; | |
| 328 }, | |
| 329 | |
| 330 __proto__: WebInspector.Object.prototype | |
| 331 }; | |
| 332 | |
| 333 /** | 310 /** |
| 334 * @constructor | 311 * @unrestricted |
| 335 * @param {string} fileSystemPath | |
| 336 * @param {string} urlPrefix | |
| 337 * @param {string} pathPrefix | |
| 338 * @param {boolean} configurable | |
| 339 */ | 312 */ |
| 340 WebInspector.FileSystemMapping.Entry = function(fileSystemPath, urlPrefix, pathP
refix, configurable) | 313 WebInspector.FileSystemMapping.Entry = class { |
| 341 { | 314 /** |
| 315 * @param {string} fileSystemPath |
| 316 * @param {string} urlPrefix |
| 317 * @param {string} pathPrefix |
| 318 * @param {boolean} configurable |
| 319 */ |
| 320 constructor(fileSystemPath, urlPrefix, pathPrefix, configurable) { |
| 342 this.fileSystemPath = fileSystemPath; | 321 this.fileSystemPath = fileSystemPath; |
| 343 this.urlPrefix = urlPrefix; | 322 this.urlPrefix = urlPrefix; |
| 344 this.pathPrefix = pathPrefix; | 323 this.pathPrefix = pathPrefix; |
| 345 this.configurable = configurable; | 324 this.configurable = configurable; |
| 325 } |
| 346 }; | 326 }; |
| 347 | 327 |
| 348 /** | 328 /** |
| 349 * @type {!WebInspector.FileSystemMapping} | 329 * @type {!WebInspector.FileSystemMapping} |
| 350 */ | 330 */ |
| 351 WebInspector.fileSystemMapping; | 331 WebInspector.fileSystemMapping; |
| OLD | NEW |