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 |