| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | |
| 5 /** | 4 /** |
| 6 * @constructor | |
| 7 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding | |
| 8 * @implements {WebInspector.TargetManager.Observer} | 5 * @implements {WebInspector.TargetManager.Observer} |
| 6 * @unrestricted |
| 9 */ | 7 */ |
| 10 WebInspector.BlackboxManager = function(debuggerWorkspaceBinding) | 8 WebInspector.BlackboxManager = class { |
| 11 { | 9 /** |
| 10 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding |
| 11 */ |
| 12 constructor(debuggerWorkspaceBinding) { |
| 12 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; | 13 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; |
| 13 | 14 |
| 14 WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebI
nspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this
); | 15 WebInspector.targetManager.addModelListener( |
| 15 WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebI
nspector.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, th
is); | 16 WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ParsedScri
ptSource, this._parsedScriptSource, |
| 16 WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this.
_patternChanged.bind(this)); | 17 this); |
| 17 WebInspector.moduleSetting("skipContentScripts").addChangeListener(this._pat
ternChanged.bind(this)); | 18 WebInspector.targetManager.addModelListener( |
| 19 WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObje
ctCleared, this._globalObjectCleared, |
| 20 this); |
| 21 WebInspector.moduleSetting('skipStackFramesPattern').addChangeListener(this.
_patternChanged.bind(this)); |
| 22 WebInspector.moduleSetting('skipContentScripts').addChangeListener(this._pat
ternChanged.bind(this)); |
| 18 | 23 |
| 19 /** @type {!Map<!WebInspector.DebuggerModel, !Map<string, !Array<!DebuggerAg
ent.ScriptPosition>>>} */ | 24 /** @type {!Map<!WebInspector.DebuggerModel, !Map<string, !Array<!DebuggerAg
ent.ScriptPosition>>>} */ |
| 20 this._debuggerModelData = new Map(); | 25 this._debuggerModelData = new Map(); |
| 21 /** @type {!Map<string, boolean>} */ | 26 /** @type {!Map<string, boolean>} */ |
| 22 this._isBlackboxedURLCache = new Map(); | 27 this._isBlackboxedURLCache = new Map(); |
| 23 | 28 |
| 24 WebInspector.targetManager.observeTargets(this); | 29 WebInspector.targetManager.observeTargets(this); |
| 25 }; | 30 } |
| 26 | 31 |
| 27 WebInspector.BlackboxManager.prototype = { | 32 /** |
| 33 * @param {function(!WebInspector.Event)} listener |
| 34 * @param {!Object=} thisObject |
| 35 */ |
| 36 addChangeListener(listener, thisObject) { |
| 37 WebInspector.moduleSetting('skipStackFramesPattern').addChangeListener(liste
ner, thisObject); |
| 38 } |
| 39 |
| 40 /** |
| 41 * @param {function(!WebInspector.Event)} listener |
| 42 * @param {!Object=} thisObject |
| 43 */ |
| 44 removeChangeListener(listener, thisObject) { |
| 45 WebInspector.moduleSetting('skipStackFramesPattern').removeChangeListener(li
stener, thisObject); |
| 46 } |
| 47 |
| 48 /** |
| 49 * @override |
| 50 * @param {!WebInspector.Target} target |
| 51 */ |
| 52 targetAdded(target) { |
| 53 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| 54 if (debuggerModel) |
| 55 this._setBlackboxPatterns(debuggerModel); |
| 56 } |
| 57 |
| 58 /** |
| 59 * @override |
| 60 * @param {!WebInspector.Target} target |
| 61 */ |
| 62 targetRemoved(target) { |
| 63 } |
| 64 |
| 65 /** |
| 66 * @param {!WebInspector.DebuggerModel} debuggerModel |
| 67 * @return {!Promise<boolean>} |
| 68 */ |
| 69 _setBlackboxPatterns(debuggerModel) { |
| 70 var regexPatterns = WebInspector.moduleSetting('skipStackFramesPattern').get
AsArray(); |
| 71 var patterns = /** @type {!Array<string>} */ ([]); |
| 72 for (var item of regexPatterns) { |
| 73 if (!item.disabled && item.pattern) |
| 74 patterns.push(item.pattern); |
| 75 } |
| 76 return debuggerModel.setBlackboxPatterns(patterns); |
| 77 } |
| 78 |
| 79 /** |
| 80 * @param {!WebInspector.DebuggerModel.Location} location |
| 81 * @return {boolean} |
| 82 */ |
| 83 isBlackboxedRawLocation(location) { |
| 84 var script = location.script(); |
| 85 if (!script) |
| 86 return false; |
| 87 var positions = this._scriptPositions(script); |
| 88 if (!positions) |
| 89 return this._isBlackboxedScript(script); |
| 90 var index = positions.lowerBound(location, comparator); |
| 91 return !!(index % 2); |
| 92 |
| 28 /** | 93 /** |
| 29 * @param {function(!WebInspector.Event)} listener | 94 * @param {!WebInspector.DebuggerModel.Location} a |
| 30 * @param {!Object=} thisObject | 95 * @param {!DebuggerAgent.ScriptPosition} b |
| 96 * @return {number} |
| 31 */ | 97 */ |
| 32 addChangeListener: function(listener, thisObject) | 98 function comparator(a, b) { |
| 33 { | 99 if (a.lineNumber !== b.lineNumber) |
| 34 WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(l
istener, thisObject); | 100 return a.lineNumber - b.lineNumber; |
| 35 }, | 101 return a.columnNumber - b.columnNumber; |
| 36 | 102 } |
| 103 } |
| 104 |
| 105 /** |
| 106 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 107 * @return {boolean} |
| 108 */ |
| 109 isBlackboxedUISourceCode(uiSourceCode) { |
| 110 var projectType = uiSourceCode.project().type(); |
| 111 var isContentScript = projectType === WebInspector.projectTypes.ContentScrip
ts; |
| 112 if (isContentScript && WebInspector.moduleSetting('skipContentScripts').get(
)) |
| 113 return true; |
| 114 var url = this._uiSourceCodeURL(uiSourceCode); |
| 115 return url ? this.isBlackboxedURL(url) : false; |
| 116 } |
| 117 |
| 118 /** |
| 119 * @param {string} url |
| 120 * @param {boolean=} isContentScript |
| 121 * @return {boolean} |
| 122 */ |
| 123 isBlackboxedURL(url, isContentScript) { |
| 124 if (this._isBlackboxedURLCache.has(url)) |
| 125 return !!this._isBlackboxedURLCache.get(url); |
| 126 if (isContentScript && WebInspector.moduleSetting('skipContentScripts').get(
)) |
| 127 return true; |
| 128 var regex = WebInspector.moduleSetting('skipStackFramesPattern').asRegExp(); |
| 129 var isBlackboxed = regex && regex.test(url); |
| 130 this._isBlackboxedURLCache.set(url, isBlackboxed); |
| 131 return isBlackboxed; |
| 132 } |
| 133 |
| 134 /** |
| 135 * @param {!WebInspector.Script} script |
| 136 * @param {?WebInspector.TextSourceMap} sourceMap |
| 137 * @return {!Promise<undefined>} |
| 138 */ |
| 139 sourceMapLoaded(script, sourceMap) { |
| 140 if (!sourceMap) |
| 141 return Promise.resolve(); |
| 142 var previousScriptState = this._scriptPositions(script); |
| 143 if (!previousScriptState) |
| 144 return Promise.resolve(); |
| 145 |
| 146 var hasBlackboxedMappings = sourceMap.sourceURLs().some((url) => this.isBlac
kboxedURL(url)); |
| 147 var mappings = hasBlackboxedMappings ? sourceMap.mappings().slice() : []; |
| 148 if (!mappings.length) { |
| 149 if (previousScriptState.length > 0) |
| 150 return this._setScriptState(script, []); |
| 151 return Promise.resolve(); |
| 152 } |
| 153 mappings.sort(mappingComparator); |
| 154 |
| 155 var currentBlackboxed = false; |
| 156 var isBlackboxed = false; |
| 157 var positions = []; |
| 158 // If content in script file begin is not mapped and one or more ranges are
blackboxed then blackbox it. |
| 159 if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) { |
| 160 positions.push({lineNumber: 0, columnNumber: 0}); |
| 161 currentBlackboxed = true; |
| 162 } |
| 163 for (var mapping of mappings) { |
| 164 if (mapping.sourceURL && currentBlackboxed !== this.isBlackboxedURL(mappin
g.sourceURL)) { |
| 165 positions.push({lineNumber: mapping.lineNumber, columnNumber: mapping.co
lumnNumber}); |
| 166 currentBlackboxed = !currentBlackboxed; |
| 167 } |
| 168 isBlackboxed = currentBlackboxed || isBlackboxed; |
| 169 } |
| 170 return this._setScriptState(script, !isBlackboxed ? [] : positions); |
| 37 /** | 171 /** |
| 38 * @param {function(!WebInspector.Event)} listener | 172 * @param {!WebInspector.SourceMapEntry} a |
| 39 * @param {!Object=} thisObject | 173 * @param {!WebInspector.SourceMapEntry} b |
| 174 * @return {number} |
| 40 */ | 175 */ |
| 41 removeChangeListener: function(listener, thisObject) | 176 function mappingComparator(a, b) { |
| 42 { | 177 if (a.lineNumber !== b.lineNumber) |
| 43 WebInspector.moduleSetting("skipStackFramesPattern").removeChangeListene
r(listener, thisObject); | 178 return a.lineNumber - b.lineNumber; |
| 44 }, | 179 return a.columnNumber - b.columnNumber; |
| 45 | 180 } |
| 46 /** | 181 } |
| 47 * @override | 182 |
| 48 * @param {!WebInspector.Target} target | 183 /** |
| 49 */ | 184 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 50 targetAdded: function(target) | 185 * @return {?string} |
| 51 { | 186 */ |
| 52 var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); | 187 _uiSourceCodeURL(uiSourceCode) { |
| 53 if (debuggerModel) | 188 return uiSourceCode.project().type() === WebInspector.projectTypes.Debugger
? null : uiSourceCode.url(); |
| 54 this._setBlackboxPatterns(debuggerModel); | 189 } |
| 55 }, | 190 |
| 56 | 191 /** |
| 57 /** | 192 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 58 * @override | 193 * @return {boolean} |
| 59 * @param {!WebInspector.Target} target | 194 */ |
| 60 */ | 195 canBlackboxUISourceCode(uiSourceCode) { |
| 61 targetRemoved: function(target) | 196 var url = this._uiSourceCodeURL(uiSourceCode); |
| 62 { | 197 return url ? !!this._urlToRegExpString(url) : false; |
| 63 }, | 198 } |
| 64 | 199 |
| 65 /** | 200 /** |
| 66 * @param {!WebInspector.DebuggerModel} debuggerModel | 201 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 67 * @return {!Promise<boolean>} | 202 */ |
| 68 */ | 203 blackboxUISourceCode(uiSourceCode) { |
| 69 _setBlackboxPatterns: function(debuggerModel) | 204 var url = this._uiSourceCodeURL(uiSourceCode); |
| 70 { | 205 if (url) |
| 71 var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern")
.getAsArray(); | 206 this._blackboxURL(url); |
| 72 var patterns = /** @type {!Array<string>} */([]); | 207 } |
| 73 for (var item of regexPatterns) { | 208 |
| 74 if (!item.disabled && item.pattern) | 209 /** |
| 75 patterns.push(item.pattern); | 210 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 76 } | 211 */ |
| 77 return debuggerModel.setBlackboxPatterns(patterns); | 212 unblackboxUISourceCode(uiSourceCode) { |
| 78 }, | 213 var url = this._uiSourceCodeURL(uiSourceCode); |
| 79 | 214 if (url) |
| 80 /** | 215 this._unblackboxURL(url); |
| 81 * @param {!WebInspector.DebuggerModel.Location} location | 216 } |
| 82 * @return {boolean} | 217 |
| 83 */ | 218 blackboxContentScripts() { |
| 84 isBlackboxedRawLocation: function(location) | 219 WebInspector.moduleSetting('skipContentScripts').set(true); |
| 85 { | 220 } |
| 86 var script = location.script(); | 221 |
| 87 if (!script) | 222 unblackboxContentScripts() { |
| 88 return false; | 223 WebInspector.moduleSetting('skipContentScripts').set(false); |
| 89 var positions = this._scriptPositions(script); | 224 } |
| 90 if (!positions) | 225 |
| 91 return this._isBlackboxedScript(script); | 226 /** |
| 92 var index = positions.lowerBound(location, comparator); | 227 * @param {string} url |
| 93 return !!(index % 2); | 228 */ |
| 94 | 229 _blackboxURL(url) { |
| 95 /** | 230 var regexPatterns = WebInspector.moduleSetting('skipStackFramesPattern').get
AsArray(); |
| 96 * @param {!WebInspector.DebuggerModel.Location} a | 231 var regexValue = this._urlToRegExpString(url); |
| 97 * @param {!DebuggerAgent.ScriptPosition} b | 232 if (!regexValue) |
| 98 * @return {number} | 233 return; |
| 99 */ | 234 var found = false; |
| 100 function comparator(a, b) | 235 for (var i = 0; i < regexPatterns.length; ++i) { |
| 101 { | 236 var item = regexPatterns[i]; |
| 102 if (a.lineNumber !== b.lineNumber) | 237 if (item.pattern === regexValue) { |
| 103 return a.lineNumber - b.lineNumber; | 238 item.disabled = false; |
| 104 return a.columnNumber - b.columnNumber; | 239 found = true; |
| 105 } | 240 break; |
| 106 }, | 241 } |
| 107 | 242 } |
| 108 /** | 243 if (!found) |
| 109 * @param {!WebInspector.UISourceCode} uiSourceCode | 244 regexPatterns.push({pattern: regexValue}); |
| 110 * @return {boolean} | 245 WebInspector.moduleSetting('skipStackFramesPattern').setAsArray(regexPattern
s); |
| 111 */ | 246 } |
| 112 isBlackboxedUISourceCode: function(uiSourceCode) | 247 |
| 113 { | 248 /** |
| 114 var projectType = uiSourceCode.project().type(); | 249 * @param {string} url |
| 115 var isContentScript = projectType === WebInspector.projectTypes.ContentS
cripts; | 250 */ |
| 116 if (isContentScript && WebInspector.moduleSetting("skipContentScripts").
get()) | 251 _unblackboxURL(url) { |
| 117 return true; | 252 var regexPatterns = WebInspector.moduleSetting('skipStackFramesPattern').get
AsArray(); |
| 118 var url = this._uiSourceCodeURL(uiSourceCode); | 253 var regexValue = WebInspector.blackboxManager._urlToRegExpString(url); |
| 119 return url ? this.isBlackboxedURL(url) : false; | 254 if (!regexValue) |
| 120 }, | 255 return; |
| 121 | 256 regexPatterns = regexPatterns.filter(function(item) { |
| 122 /** | 257 return item.pattern !== regexValue; |
| 123 * @param {string} url | 258 }); |
| 124 * @param {boolean=} isContentScript | 259 for (var i = 0; i < regexPatterns.length; ++i) { |
| 125 * @return {boolean} | 260 var item = regexPatterns[i]; |
| 126 */ | 261 if (item.disabled) |
| 127 isBlackboxedURL: function(url, isContentScript) | 262 continue; |
| 128 { | 263 try { |
| 129 if (this._isBlackboxedURLCache.has(url)) | 264 var regex = new RegExp(item.pattern); |
| 130 return !!this._isBlackboxedURLCache.get(url); | 265 if (regex.test(url)) |
| 131 if (isContentScript && WebInspector.moduleSetting("skipContentScripts").
get()) | 266 item.disabled = true; |
| 132 return true; | 267 } catch (e) { |
| 133 var regex = WebInspector.moduleSetting("skipStackFramesPattern").asRegEx
p(); | 268 } |
| 134 var isBlackboxed = regex && regex.test(url); | 269 } |
| 135 this._isBlackboxedURLCache.set(url, isBlackboxed); | 270 WebInspector.moduleSetting('skipStackFramesPattern').setAsArray(regexPattern
s); |
| 136 return isBlackboxed; | 271 } |
| 137 }, | 272 |
| 138 | 273 _patternChanged() { |
| 139 /** | 274 this._isBlackboxedURLCache.clear(); |
| 140 * @param {!WebInspector.Script} script | 275 |
| 141 * @param {?WebInspector.TextSourceMap} sourceMap | 276 var promises = []; |
| 142 * @return {!Promise<undefined>} | 277 for (var debuggerModel of WebInspector.DebuggerModel.instances()) { |
| 143 */ | 278 promises.push(this._setBlackboxPatterns.bind(this, debuggerModel)); |
| 144 sourceMapLoaded: function(script, sourceMap) | 279 for (var scriptId in debuggerModel.scripts) { |
| 145 { | 280 var script = debuggerModel.scripts[scriptId]; |
| 146 if (!sourceMap) | 281 promises.push(this._addScript(script).then(loadSourceMap.bind(this, scri
pt))); |
| 147 return Promise.resolve(); | 282 } |
| 148 var previousScriptState = this._scriptPositions(script); | 283 } |
| 149 if (!previousScriptState) | 284 Promise.all(promises).then(this._patternChangeFinishedForTests.bind(this)); |
| 150 return Promise.resolve(); | |
| 151 | |
| 152 var hasBlackboxedMappings = sourceMap.sourceURLs().some((url) => this.is
BlackboxedURL(url)); | |
| 153 var mappings = hasBlackboxedMappings ? sourceMap.mappings().slice() : []
; | |
| 154 if (!mappings.length) { | |
| 155 if (previousScriptState.length > 0) | |
| 156 return this._setScriptState(script, []); | |
| 157 return Promise.resolve(); | |
| 158 } | |
| 159 mappings.sort(mappingComparator); | |
| 160 | |
| 161 var currentBlackboxed = false; | |
| 162 var isBlackboxed = false; | |
| 163 var positions = []; | |
| 164 // If content in script file begin is not mapped and one or more ranges
are blackboxed then blackbox it. | |
| 165 if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) { | |
| 166 positions.push({ lineNumber: 0, columnNumber: 0}); | |
| 167 currentBlackboxed = true; | |
| 168 } | |
| 169 for (var mapping of mappings) { | |
| 170 if (mapping.sourceURL && currentBlackboxed !== this.isBlackboxedURL(
mapping.sourceURL)) { | |
| 171 positions.push({ lineNumber: mapping.lineNumber, columnNumber: m
apping.columnNumber }); | |
| 172 currentBlackboxed = !currentBlackboxed; | |
| 173 } | |
| 174 isBlackboxed = currentBlackboxed || isBlackboxed; | |
| 175 } | |
| 176 return this._setScriptState(script, !isBlackboxed ? [] : positions); | |
| 177 /** | |
| 178 * @param {!WebInspector.SourceMapEntry} a | |
| 179 * @param {!WebInspector.SourceMapEntry} b | |
| 180 * @return {number} | |
| 181 */ | |
| 182 function mappingComparator(a, b) | |
| 183 { | |
| 184 if (a.lineNumber !== b.lineNumber) | |
| 185 return a.lineNumber - b.lineNumber; | |
| 186 return a.columnNumber - b.columnNumber; | |
| 187 } | |
| 188 }, | |
| 189 | |
| 190 /** | |
| 191 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 192 * @return {?string} | |
| 193 */ | |
| 194 _uiSourceCodeURL: function(uiSourceCode) | |
| 195 { | |
| 196 return uiSourceCode.project().type() === WebInspector.projectTypes.Debug
ger ? null : uiSourceCode.url(); | |
| 197 }, | |
| 198 | |
| 199 /** | |
| 200 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 201 * @return {boolean} | |
| 202 */ | |
| 203 canBlackboxUISourceCode: function(uiSourceCode) | |
| 204 { | |
| 205 var url = this._uiSourceCodeURL(uiSourceCode); | |
| 206 return url ? !!this._urlToRegExpString(url) : false; | |
| 207 }, | |
| 208 | |
| 209 /** | |
| 210 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 211 */ | |
| 212 blackboxUISourceCode: function(uiSourceCode) | |
| 213 { | |
| 214 var url = this._uiSourceCodeURL(uiSourceCode); | |
| 215 if (url) | |
| 216 this._blackboxURL(url); | |
| 217 }, | |
| 218 | |
| 219 /** | |
| 220 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 221 */ | |
| 222 unblackboxUISourceCode: function(uiSourceCode) | |
| 223 { | |
| 224 var url = this._uiSourceCodeURL(uiSourceCode); | |
| 225 if (url) | |
| 226 this._unblackboxURL(url); | |
| 227 }, | |
| 228 | |
| 229 blackboxContentScripts: function() | |
| 230 { | |
| 231 WebInspector.moduleSetting("skipContentScripts").set(true); | |
| 232 }, | |
| 233 | |
| 234 unblackboxContentScripts: function() | |
| 235 { | |
| 236 WebInspector.moduleSetting("skipContentScripts").set(false); | |
| 237 }, | |
| 238 | |
| 239 /** | |
| 240 * @param {string} url | |
| 241 */ | |
| 242 _blackboxURL: function(url) | |
| 243 { | |
| 244 var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern")
.getAsArray(); | |
| 245 var regexValue = this._urlToRegExpString(url); | |
| 246 if (!regexValue) | |
| 247 return; | |
| 248 var found = false; | |
| 249 for (var i = 0; i < regexPatterns.length; ++i) { | |
| 250 var item = regexPatterns[i]; | |
| 251 if (item.pattern === regexValue) { | |
| 252 item.disabled = false; | |
| 253 found = true; | |
| 254 break; | |
| 255 } | |
| 256 } | |
| 257 if (!found) | |
| 258 regexPatterns.push({ pattern: regexValue }); | |
| 259 WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPat
terns); | |
| 260 }, | |
| 261 | |
| 262 /** | |
| 263 * @param {string} url | |
| 264 */ | |
| 265 _unblackboxURL: function(url) | |
| 266 { | |
| 267 var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern")
.getAsArray(); | |
| 268 var regexValue = WebInspector.blackboxManager._urlToRegExpString(url); | |
| 269 if (!regexValue) | |
| 270 return; | |
| 271 regexPatterns = regexPatterns.filter(function(item) { | |
| 272 return item.pattern !== regexValue; | |
| 273 }); | |
| 274 for (var i = 0; i < regexPatterns.length; ++i) { | |
| 275 var item = regexPatterns[i]; | |
| 276 if (item.disabled) | |
| 277 continue; | |
| 278 try { | |
| 279 var regex = new RegExp(item.pattern); | |
| 280 if (regex.test(url)) | |
| 281 item.disabled = true; | |
| 282 } catch (e) { | |
| 283 } | |
| 284 } | |
| 285 WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPat
terns); | |
| 286 }, | |
| 287 | |
| 288 _patternChanged: function() | |
| 289 { | |
| 290 this._isBlackboxedURLCache.clear(); | |
| 291 | |
| 292 var promises = []; | |
| 293 for (var debuggerModel of WebInspector.DebuggerModel.instances()) { | |
| 294 promises.push(this._setBlackboxPatterns.bind(this, debuggerModel)); | |
| 295 for (var scriptId in debuggerModel.scripts) { | |
| 296 var script = debuggerModel.scripts[scriptId]; | |
| 297 promises.push(this._addScript(script) | |
| 298 .then(loadSourceMap.bind(this, script))); | |
| 299 } | |
| 300 } | |
| 301 Promise.all(promises).then(this._patternChangeFinishedForTests.bind(this
)); | |
| 302 | |
| 303 /** | |
| 304 * @param {!WebInspector.Script} script | |
| 305 * @return {!Promise<undefined>} | |
| 306 * @this {WebInspector.BlackboxManager} | |
| 307 */ | |
| 308 function loadSourceMap(script) | |
| 309 { | |
| 310 return this.sourceMapLoaded(script, this._debuggerWorkspaceBinding.s
ourceMapForScript(script)); | |
| 311 } | |
| 312 }, | |
| 313 | |
| 314 _patternChangeFinishedForTests: function() | |
| 315 { | |
| 316 // This method is sniffed in tests. | |
| 317 }, | |
| 318 | |
| 319 /** | |
| 320 * @param {!WebInspector.Event} event | |
| 321 */ | |
| 322 _globalObjectCleared: function(event) | |
| 323 { | |
| 324 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.ta
rget); | |
| 325 this._debuggerModelData.delete(debuggerModel); | |
| 326 this._isBlackboxedURLCache.clear(); | |
| 327 }, | |
| 328 | |
| 329 /** | |
| 330 * @param {!WebInspector.Event} event | |
| 331 */ | |
| 332 _parsedScriptSource: function(event) | |
| 333 { | |
| 334 var script = /** @type {!WebInspector.Script} */ (event.data); | |
| 335 this._addScript(script); | |
| 336 }, | |
| 337 | 285 |
| 338 /** | 286 /** |
| 339 * @param {!WebInspector.Script} script | 287 * @param {!WebInspector.Script} script |
| 340 * @return {!Promise<undefined>} | 288 * @return {!Promise<undefined>} |
| 289 * @this {WebInspector.BlackboxManager} |
| 341 */ | 290 */ |
| 342 _addScript: function(script) | 291 function loadSourceMap(script) { |
| 343 { | 292 return this.sourceMapLoaded(script, this._debuggerWorkspaceBinding.sourceM
apForScript(script)); |
| 344 var blackboxed = this._isBlackboxedScript(script); | 293 } |
| 345 return this._setScriptState(script, blackboxed ? [ { lineNumber: 0, colu
mnNumber: 0 } ] : []); | 294 } |
| 346 }, | 295 |
| 296 _patternChangeFinishedForTests() { |
| 297 // This method is sniffed in tests. |
| 298 } |
| 299 |
| 300 /** |
| 301 * @param {!WebInspector.Event} event |
| 302 */ |
| 303 _globalObjectCleared(event) { |
| 304 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target
); |
| 305 this._debuggerModelData.delete(debuggerModel); |
| 306 this._isBlackboxedURLCache.clear(); |
| 307 } |
| 308 |
| 309 /** |
| 310 * @param {!WebInspector.Event} event |
| 311 */ |
| 312 _parsedScriptSource(event) { |
| 313 var script = /** @type {!WebInspector.Script} */ (event.data); |
| 314 this._addScript(script); |
| 315 } |
| 316 |
| 317 /** |
| 318 * @param {!WebInspector.Script} script |
| 319 * @return {!Promise<undefined>} |
| 320 */ |
| 321 _addScript(script) { |
| 322 var blackboxed = this._isBlackboxedScript(script); |
| 323 return this._setScriptState(script, blackboxed ? [{lineNumber: 0, columnNumb
er: 0}] : []); |
| 324 } |
| 325 |
| 326 /** |
| 327 * @param {!WebInspector.Script} script |
| 328 * @return {boolean} |
| 329 */ |
| 330 _isBlackboxedScript(script) { |
| 331 return this.isBlackboxedURL(script.sourceURL, script.isContentScript()); |
| 332 } |
| 333 |
| 334 /** |
| 335 * @param {!WebInspector.Script} script |
| 336 * @return {?Array<!DebuggerAgent.ScriptPosition>} |
| 337 */ |
| 338 _scriptPositions(script) { |
| 339 if (this._debuggerModelData.has(script.debuggerModel)) |
| 340 return this._debuggerModelData.get(script.debuggerModel).get(script.script
Id) || null; |
| 341 return null; |
| 342 } |
| 343 |
| 344 /** |
| 345 * @param {!WebInspector.Script} script |
| 346 * @param {!Array<!DebuggerAgent.ScriptPosition>} positions |
| 347 */ |
| 348 _setScriptPositions(script, positions) { |
| 349 var debuggerModel = script.debuggerModel; |
| 350 if (!this._debuggerModelData.has(debuggerModel)) |
| 351 this._debuggerModelData.set(debuggerModel, new Map()); |
| 352 this._debuggerModelData.get(debuggerModel).set(script.scriptId, positions); |
| 353 } |
| 354 |
| 355 /** |
| 356 * @param {!WebInspector.Script} script |
| 357 * @param {!Array<!DebuggerAgent.ScriptPosition>} positions |
| 358 * @return {!Promise<undefined>} |
| 359 */ |
| 360 _setScriptState(script, positions) { |
| 361 var previousScriptState = this._scriptPositions(script); |
| 362 if (previousScriptState) { |
| 363 var hasChanged = false; |
| 364 hasChanged = previousScriptState.length !== positions.length; |
| 365 for (var i = 0; !hasChanged && i < positions.length; ++i) |
| 366 hasChanged = positions[i].lineNumber !== previousScriptState[i].lineNumb
er || |
| 367 positions[i].columnNumber !== previousScriptState[i].columnNumber; |
| 368 if (!hasChanged) |
| 369 return Promise.resolve(); |
| 370 } else { |
| 371 if (positions.length === 0) |
| 372 return Promise.resolve().then(updateState.bind(this, false)); |
| 373 } |
| 374 |
| 375 return script.setBlackboxedRanges(positions).then(updateState.bind(this)); |
| 347 | 376 |
| 348 /** | 377 /** |
| 349 * @param {!WebInspector.Script} script | 378 * @param {boolean} success |
| 350 * @return {boolean} | 379 * @this {WebInspector.BlackboxManager} |
| 351 */ | 380 */ |
| 352 _isBlackboxedScript: function(script) | 381 function updateState(success) { |
| 353 { | 382 if (success) { |
| 354 return this.isBlackboxedURL(script.sourceURL, script.isContentScript()); | 383 this._setScriptPositions(script, positions); |
| 355 }, | 384 this._debuggerWorkspaceBinding.updateLocations(script); |
| 356 | 385 var isBlackboxed = positions.length !== 0; |
| 357 /** | 386 if (!isBlackboxed && script.sourceMapURL) |
| 358 * @param {!WebInspector.Script} script | 387 this._debuggerWorkspaceBinding.maybeLoadSourceMap(script); |
| 359 * @return {?Array<!DebuggerAgent.ScriptPosition>} | 388 } else { |
| 360 */ | 389 var hasPositions = !!this._scriptPositions(script); |
| 361 _scriptPositions: function(script) | 390 if (!hasPositions) |
| 362 { | 391 this._setScriptPositions(script, []); |
| 363 if (this._debuggerModelData.has(script.debuggerModel)) | 392 } |
| 364 return this._debuggerModelData.get(script.debuggerModel).get(script.
scriptId) || null; | 393 } |
| 365 return null; | 394 } |
| 366 }, | 395 |
| 367 | 396 /** |
| 368 /** | 397 * @param {string} url |
| 369 * @param {!WebInspector.Script} script | 398 * @return {string} |
| 370 * @param {!Array<!DebuggerAgent.ScriptPosition>} positions | 399 */ |
| 371 */ | 400 _urlToRegExpString(url) { |
| 372 _setScriptPositions: function(script, positions) | 401 var parsedURL = new WebInspector.ParsedURL(url); |
| 373 { | 402 if (parsedURL.isAboutBlank() || parsedURL.isDataURL()) |
| 374 var debuggerModel = script.debuggerModel; | 403 return ''; |
| 375 if (!this._debuggerModelData.has(debuggerModel)) | 404 if (!parsedURL.isValid) |
| 376 this._debuggerModelData.set(debuggerModel, new Map()); | 405 return '^' + url.escapeForRegExp() + '$'; |
| 377 this._debuggerModelData.get(debuggerModel).set(script.scriptId, position
s); | 406 var name = parsedURL.lastPathComponent; |
| 378 }, | 407 if (name) |
| 379 | 408 name = '/' + name; |
| 380 /** | 409 else if (parsedURL.folderPathComponents) |
| 381 * @param {!WebInspector.Script} script | 410 name = parsedURL.folderPathComponents + '/'; |
| 382 * @param {!Array<!DebuggerAgent.ScriptPosition>} positions | 411 if (!name) |
| 383 * @return {!Promise<undefined>} | 412 name = parsedURL.host; |
| 384 */ | 413 if (!name) |
| 385 _setScriptState: function(script, positions) | 414 return ''; |
| 386 { | 415 var scheme = parsedURL.scheme; |
| 387 var previousScriptState = this._scriptPositions(script); | 416 var prefix = ''; |
| 388 if (previousScriptState) { | 417 if (scheme && scheme !== 'http' && scheme !== 'https') { |
| 389 var hasChanged = false; | 418 prefix = '^' + scheme + '://'; |
| 390 hasChanged = previousScriptState.length !== positions.length; | 419 if (scheme === 'chrome-extension') |
| 391 for (var i = 0; !hasChanged && i < positions.length; ++i) | 420 prefix += parsedURL.host + '\\b'; |
| 392 hasChanged = positions[i].lineNumber !== previousScriptState[i].
lineNumber || positions[i].columnNumber !== previousScriptState[i].columnNumber; | 421 prefix += '.*'; |
| 393 if (!hasChanged) | 422 } |
| 394 return Promise.resolve(); | 423 return prefix + name.escapeForRegExp() + (url.endsWith(name) ? '$' : '\\b'); |
| 395 } else { | 424 } |
| 396 if (positions.length === 0) | |
| 397 return Promise.resolve().then(updateState.bind(this, false)); | |
| 398 } | |
| 399 | |
| 400 return script.setBlackboxedRanges(positions).then(updateState.bind(this)
); | |
| 401 | |
| 402 /** | |
| 403 * @param {boolean} success | |
| 404 * @this {WebInspector.BlackboxManager} | |
| 405 */ | |
| 406 function updateState(success) | |
| 407 { | |
| 408 if (success) { | |
| 409 this._setScriptPositions(script, positions); | |
| 410 this._debuggerWorkspaceBinding.updateLocations(script); | |
| 411 var isBlackboxed = positions.length !== 0; | |
| 412 if (!isBlackboxed && script.sourceMapURL) | |
| 413 this._debuggerWorkspaceBinding.maybeLoadSourceMap(script); | |
| 414 } else { | |
| 415 var hasPositions = !!this._scriptPositions(script); | |
| 416 if (!hasPositions) | |
| 417 this._setScriptPositions(script, []); | |
| 418 } | |
| 419 } | |
| 420 }, | |
| 421 | |
| 422 /** | |
| 423 * @param {string} url | |
| 424 * @return {string} | |
| 425 */ | |
| 426 _urlToRegExpString: function(url) | |
| 427 { | |
| 428 var parsedURL = new WebInspector.ParsedURL(url); | |
| 429 if (parsedURL.isAboutBlank() || parsedURL.isDataURL()) | |
| 430 return ""; | |
| 431 if (!parsedURL.isValid) | |
| 432 return "^" + url.escapeForRegExp() + "$"; | |
| 433 var name = parsedURL.lastPathComponent; | |
| 434 if (name) | |
| 435 name = "/" + name; | |
| 436 else if (parsedURL.folderPathComponents) | |
| 437 name = parsedURL.folderPathComponents + "/"; | |
| 438 if (!name) | |
| 439 name = parsedURL.host; | |
| 440 if (!name) | |
| 441 return ""; | |
| 442 var scheme = parsedURL.scheme; | |
| 443 var prefix = ""; | |
| 444 if (scheme && scheme !== "http" && scheme !== "https") { | |
| 445 prefix = "^" + scheme + "://"; | |
| 446 if (scheme === "chrome-extension") | |
| 447 prefix += parsedURL.host + "\\b"; | |
| 448 prefix += ".*"; | |
| 449 } | |
| 450 return prefix + name.escapeForRegExp() + (url.endsWith(name) ? "$" : "\\
b"); | |
| 451 } | |
| 452 }; | 425 }; |
| 453 | 426 |
| 454 /** @type {!WebInspector.BlackboxManager} */ | 427 /** @type {!WebInspector.BlackboxManager} */ |
| 455 WebInspector.blackboxManager; | 428 WebInspector.blackboxManager; |
| OLD | NEW |