 Chromium Code Reviews
 Chromium Code Reviews Issue 1663723002:
  [DevTools] Add sourceMap support for blackboxing  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@call-set-blackboxed-ranges-on-script-parsed
    
  
    Issue 1663723002:
  [DevTools] Add sourceMap support for blackboxing  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@call-set-blackboxed-ranges-on-script-parsed| OLD | NEW | 
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * @constructor | |
| 7 */ | |
| 8 WebInspector.BlackboxManager = function() | |
| 9 { | |
| 10 WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebI nspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this ); | |
| 11 WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this. _patternChanged.bind(this)); | |
| 12 WebInspector.moduleSetting("skipContentScripts").addChangeListener(this._pat ternChanged.bind(this)); | |
| 13 | |
| 14 /** @type {!Map<string, string>} */ | |
| 15 this._scripts = new Map(); | |
| 
dgozman
2016/02/09 23:44:50
Clean this up on GlobalObjectCleared.
 
dgozman
2016/02/09 23:44:50
Store blackbox ranges per script instead.
 
kozy
2016/02/10 01:19:41
Done.
 
kozy
2016/02/10 01:19:41
Done.
 | |
| 16 /** @type {!Map<string, boolean>} */ | |
| 17 this._isBlackboxedURLCache = new Map(); | |
| 
dgozman
2016/02/09 23:44:50
Let's clear on GlobalObjectCleared to avoid leaks.
 
kozy
2016/02/10 01:19:41
Done.
 | |
| 18 } | |
| 19 | |
| 20 WebInspector.BlackboxManager.ScriptState = { | |
| 
dgozman
2016/02/09 23:44:50
Make this a enum and use in JSDocs.
 
kozy
2016/02/10 01:19:41
Removed.
 | |
| 21 NotBlackboxed: "NotBlackboxed", | |
| 22 Blackboxed: "Blackboxed", | |
| 23 PartiallyBlackboxed: "PartiallyBlackboxed" | |
| 24 } | |
| 25 | |
| 26 WebInspector.BlackboxManager.prototype = { | |
| 27 | |
| 28 /** | |
| 29 * @param {function(!WebInspector.Event)} listener | |
| 30 * @param {!Object=} thisObject | |
| 31 */ | |
| 32 addChangeListener: function(listener, thisObject) | |
| 33 { | |
| 34 WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(l istener, thisObject); | |
| 35 }, | |
| 36 | |
| 37 /** | |
| 38 * @param {function(!WebInspector.Event)} listener | |
| 39 * @param {!Object=} thisObject | |
| 40 */ | |
| 41 removeChangeListener: function(listener, thisObject) | |
| 42 { | |
| 43 WebInspector.moduleSetting("skipStackFramesPattern").removeChangeListene r(listener, thisObject); | |
| 44 }, | |
| 45 | |
| 46 /** | |
| 47 * @param {!WebInspector.Script} script | |
| 48 * @return {boolean} | |
| 49 */ | |
| 50 isBlackboxedScript: function(script) | |
| 
dgozman
2016/02/09 23:44:50
Remove this method, add one with rawLocation inste
 
kozy
2016/02/10 01:19:41
Done.
 | |
| 51 { | |
| 52 if (!this._scripts.has(script.scriptId)) | |
| 53 return false; | |
| 54 if (this._scripts.get(script.scriptId) !== WebInspector.BlackboxManager. ScriptState.NotBlackboxed) | |
| 55 return true; | |
| 56 return false; | |
| 57 }, | |
| 58 | |
| 59 /** | |
| 60 * @param {string} url | |
| 61 * @return {boolean} | |
| 62 */ | |
| 63 isBlackboxedURL: function(url) | |
| 64 { | |
| 65 if (this._isBlackboxedURLCache.has(url)) | |
| 66 return !!this._isBlackboxedURLCache.get(url); | |
| 67 var regex = WebInspector.moduleSetting("skipStackFramesPattern").asRegEx p(); | |
| 68 var isBlackboxed = regex && regex.test(url); | |
| 69 this._isBlackboxedURLCache.set(url, isBlackboxed); | |
| 70 return isBlackboxed; | |
| 71 }, | |
| 72 | |
| 73 /** | |
| 74 * @return {boolean} | |
| 75 */ | |
| 76 isBlackboxedContentScripts: function() | |
| 
dgozman
2016/02/09 23:44:50
Replace with isUISourceCodeBlackboxed.
 
kozy
2016/02/10 01:19:41
Done.
 | |
| 77 { | |
| 78 return WebInspector.moduleSetting("skipContentScripts").get(); | |
| 79 }, | |
| 80 | |
| 81 /** | |
| 82 * @param {!WebInspector.Script} script | |
| 83 * @param {?WebInspector.SourceMap} sourceMap | |
| 84 */ | |
| 85 sourceMapLoaded: function(script, sourceMap) | |
| 86 { | |
| 87 if (!sourceMap) | |
| 88 return; | |
| 89 if (!this._scripts.has(script.scriptId)) | |
| 90 return; | |
| 91 | |
| 92 var previousScriptState = this._scripts.get(script.scriptId); | |
| 93 console.assert(previousScriptState !== WebInspector.BlackboxManager.Scri ptState.Blackboxed, "Source map is loaded for blackboxed script."); | |
| 94 | |
| 95 var mappings = sourceMap.mappings().slice(); | |
| 96 mappings.sort(mappingComparator); | |
| 97 | |
| 98 if (!mappings.length) { | |
| 99 if (previousScriptState === WebInspector.BlackboxManager.ScriptState .PartiallyBlackboxed) | |
| 100 script.setBlackboxedRanges([]).then(this._setScriptState.bind(th is, script, WebInspector.BlackboxManager.ScriptState.NotBlackboxed)); | |
| 101 return; | |
| 102 } | |
| 103 | |
| 104 var currentBlackboxed = false; | |
| 105 var isBlackboxed = false; | |
| 106 var positions = []; | |
| 107 if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) { | |
| 108 positions.push({ line: 0, column: 0}); | |
| 109 currentBlackboxed = true; | |
| 110 } | |
| 111 for (var mapping of sourceMap.mappings()) { | |
| 112 if (currentBlackboxed !== this.isBlackboxedURL(mapping.sourceURL)) { | |
| 113 positions.push({ line: mapping.lineNumber, column: mapping.colum nNumber }); | |
| 114 currentBlackboxed = !currentBlackboxed; | |
| 115 } | |
| 116 if (currentBlackboxed) | |
| 117 isBlackboxed = true; | |
| 118 } | |
| 119 | |
| 120 if (isBlackboxed) | |
| 121 script.setBlackboxedRanges(positions).then(this._setScriptState.bind (this, script, WebInspector.BlackboxManager.ScriptState.PartiallyBlackboxed)); | |
| 122 else | |
| 123 script.setBlackboxedRanges([]).then(this._setScriptState.bind(this, script, WebInspector.BlackboxManager.ScriptState.NotBlackboxed)); | |
| 124 /** | |
| 125 * @param {!WebInspector.SourceMap.Entry} a | |
| 126 * @param {!WebInspector.SourceMap.Entry} b | |
| 127 */ | |
| 128 function mappingComparator(a, b) | |
| 129 { | |
| 130 if (a.lineNumber !== b.lineNumber) | |
| 131 return a.lineNumber - b.lineNumber; | |
| 132 return a.columnNumber - b.columnNumber; | |
| 133 } | |
| 134 }, | |
| 135 | |
| 136 /** | |
| 137 * @param {string} url | |
| 138 * @return {boolean} | |
| 139 */ | |
| 140 canBlackboxURL: function(url) | |
| 141 { | |
| 142 return !!this._urlToRegExpString(url); | |
| 143 }, | |
| 144 | |
| 145 /** | |
| 146 * @param {string} url | |
| 147 */ | |
| 148 blackboxURL: function(url) | |
| 149 { | |
| 150 var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern") .getAsArray(); | |
| 151 var regexValue = this._urlToRegExpString(url); | |
| 152 if (!regexValue) | |
| 153 return; | |
| 154 var found = false; | |
| 155 for (var i = 0; i < regexPatterns.length; ++i) { | |
| 156 var item = regexPatterns[i]; | |
| 157 if (item.pattern === regexValue) { | |
| 158 item.disabled = false; | |
| 159 found = true; | |
| 160 break; | |
| 161 } | |
| 162 } | |
| 163 if (!found) | |
| 164 regexPatterns.push({ pattern: regexValue }); | |
| 165 WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPat terns); | |
| 166 }, | |
| 167 | |
| 168 /** | |
| 169 * @param {string} url | |
| 170 * @param {boolean} isContentScript | |
| 171 */ | |
| 172 unblackbox: function(url, isContentScript) | |
| 173 { | |
| 174 if (isContentScript) | |
| 175 WebInspector.moduleSetting("skipContentScripts").set(false); | |
| 176 | |
| 177 var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern") .getAsArray(); | |
| 178 var regexValue = WebInspector.blackboxManager._urlToRegExpString(url); | |
| 179 if (!regexValue) | |
| 180 return; | |
| 181 regexPatterns = regexPatterns.filter(function(item) { | |
| 182 return item.pattern !== regexValue; | |
| 183 }); | |
| 184 for (var i = 0; i < regexPatterns.length; ++i) { | |
| 185 var item = regexPatterns[i]; | |
| 186 if (item.disabled) | |
| 187 continue; | |
| 188 try { | |
| 189 var regex = new RegExp(item.pattern); | |
| 190 if (regex.test(url)) | |
| 191 item.disabled = true; | |
| 192 } catch (e) { | |
| 193 } | |
| 194 } | |
| 195 WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPat terns); | |
| 196 }, | |
| 197 | |
| 198 _patternChanged: function() | |
| 199 { | |
| 200 this._isBlackboxedURLCache.clear(); | |
| 201 this._scripts.clear(); | |
| 202 | |
| 203 var promises = []; | |
| 204 for (var debuggerModel of WebInspector.DebuggerModel.instances()) { | |
| 205 for (var scriptId in debuggerModel.scripts) { | |
| 206 var script = debuggerModel.scripts[scriptId]; | |
| 207 promises.push(this._addScript(script).then(checkSourceMap.bind(t his, script))); | |
| 208 } | |
| 209 } | |
| 210 Promise.all(promises).then(this._patternChangeFinished); | |
| 211 | |
| 212 /** | |
| 213 * @param {!WebInspector.Script} script | |
| 214 * @param {boolean} isBlackboxed | |
| 215 * @this {!WebInspector.BlackboxManager} | |
| 216 */ | |
| 217 function checkSourceMap(script, isBlackboxed) | |
| 218 { | |
| 219 if (isBlackboxed) | |
| 220 return; | |
| 221 this.sourceMapLoaded(script, this._sourceMapForScript(script)); | |
| 222 } | |
| 223 }, | |
| 224 | |
| 225 _patternChangeFinished: function() | |
| 
dgozman
2016/02/09 23:44:51
...forTests
 
kozy
2016/02/10 01:19:41
Done.
 | |
| 226 { | |
| 
dgozman
2016/02/09 23:44:50
// This method is sniffed in tests.
 
kozy
2016/02/10 01:19:41
Done.
 | |
| 227 }, | |
| 228 | |
| 229 /** | |
| 230 * @param {!WebInspector.Event} event | |
| 231 */ | |
| 232 _parsedScriptSource: function(event) | |
| 233 { | |
| 234 var script = /** @type {!WebInspector.Script} */ (event.data); | |
| 235 this._addScript(script); | |
| 236 }, | |
| 237 | |
| 238 /** | |
| 239 * @param {!WebInspector.Script} script | |
| 240 * @return {!Promise<boolean>} | |
| 241 */ | |
| 242 _addScript: function(script) | |
| 243 { | |
| 244 var blackboxed = this._isBlackboxedScript(script); | |
| 245 if (!blackboxed) | |
| 246 return Promise.resolve(this._setScriptState(script, WebInspector.Bla ckboxManager.ScriptState.NotBlackboxed)); | |
| 247 return script.setBlackboxedRanges([ { line: 0, column: 0 } ]).then(this. _setScriptState.bind(this, script, WebInspector.BlackboxManager.ScriptState.Blac kboxed)); | |
| 248 }, | |
| 249 | |
| 250 /** | |
| 251 * @param {!WebInspector.Script} script | |
| 252 * @return {boolean} | |
| 253 */ | |
| 254 _isBlackboxedScript: function(script) | |
| 255 { | |
| 256 if (script.isContentScript() && WebInspector.moduleSetting("skipContentS cripts").get()) | |
| 257 return true; | |
| 258 return this.isBlackboxedURL(script.sourceURL); | |
| 259 }, | |
| 260 | |
| 261 /** | |
| 262 * @param {!WebInspector.Script} script | |
| 263 * @return {?WebInspector.SourceMap} | |
| 264 */ | |
| 265 _sourceMapForScript: function(script) | |
| 266 { | |
| 267 return WebInspector.debuggerWorkspaceBinding.sourceMapForScript(script); | |
| 
dgozman
2016/02/09 23:44:50
Pass it as a parameter in constructor.
 
kozy
2016/02/10 01:19:41
Done.
 | |
| 268 }, | |
| 269 | |
| 270 /** | |
| 271 * @param {!WebInspector.Script} script | |
| 272 * @param {string} state | |
| 273 * @return {boolean} | |
| 274 */ | |
| 275 _setScriptState: function(script, state) | |
| 276 { | |
| 277 this._scripts.set(script.scriptId, state); | |
| 278 return state !== WebInspector.BlackboxManager.ScriptState.NotBlackboxed; | |
| 279 }, | |
| 280 | |
| 281 /** | |
| 282 * @param {string} url | |
| 283 * @return {string} | |
| 284 */ | |
| 285 _urlToRegExpString: function(url) | |
| 286 { | |
| 287 var parsedURL = new WebInspector.ParsedURL(url); | |
| 288 if (parsedURL.isAboutBlank() || parsedURL.isDataURL()) | |
| 289 return ""; | |
| 290 if (!parsedURL.isValid) | |
| 291 return "^" + url.escapeForRegExp() + "$"; | |
| 292 var name = parsedURL.lastPathComponent; | |
| 293 if (name) | |
| 294 name = "/" + name; | |
| 295 else if (parsedURL.folderPathComponents) | |
| 296 name = parsedURL.folderPathComponents + "/"; | |
| 297 if (!name) | |
| 298 name = parsedURL.host; | |
| 299 if (!name) | |
| 300 return ""; | |
| 301 var scheme = parsedURL.scheme; | |
| 302 var prefix = ""; | |
| 303 if (scheme && scheme !== "http" && scheme !== "https") { | |
| 304 prefix = "^" + scheme + "://"; | |
| 305 if (scheme === "chrome-extension") | |
| 306 prefix += parsedURL.host + "\\b"; | |
| 307 prefix += ".*"; | |
| 308 } | |
| 309 return prefix + name.escapeForRegExp() + (url.endsWith(name) ? "$" : "\\ b"); | |
| 310 } | |
| 311 } | |
| 312 | |
| 313 /** @type {!WebInspector.BlackboxManager} */ | |
| 314 WebInspector.blackboxManager; | |
| OLD | NEW |