| 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  * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding | 
|  | 8  * @param {!WebInspector.NetworkMapping} networkMapping | 
|  | 9  */ | 
|  | 10 WebInspector.BlackboxManager = function(debuggerWorkspaceBinding, networkMapping
     ) | 
|  | 11 { | 
|  | 12     this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; | 
|  | 13     this._networkMapping = networkMapping; | 
|  | 14 | 
|  | 15     WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebI
     nspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this
     ); | 
|  | 16     WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebI
     nspector.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, th
     is); | 
|  | 17     WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this.
     _patternChanged.bind(this)); | 
|  | 18     WebInspector.moduleSetting("skipContentScripts").addChangeListener(this._pat
     ternChanged.bind(this)); | 
|  | 19 | 
|  | 20     /** @type {!Map<string, !Array<!DebuggerAgent.ScriptPosition>>} */ | 
|  | 21     this._scriptIdToPositions = new Map(); | 
|  | 22     /** @type {!Map<string, boolean>} */ | 
|  | 23     this._isBlackboxedURLCache = new Map(); | 
|  | 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.DebuggerModel.Location} location | 
|  | 48      * @return {boolean} | 
|  | 49      */ | 
|  | 50     isBlackboxedRawLocation: function(location) | 
|  | 51     { | 
|  | 52         if (!this._scriptIdToPositions.has(location.scriptId)) | 
|  | 53             return false; | 
|  | 54         var positions = this._scriptIdToPositions.get(location.scriptId); | 
|  | 55         var index = positions.lowerBound(location, comparator); | 
|  | 56         return !!(index % 2); | 
|  | 57 | 
|  | 58         /** | 
|  | 59          * @param {!WebInspector.DebuggerModel.Location} a | 
|  | 60          * @param {!DebuggerAgent.ScriptPosition} b | 
|  | 61          * @return {number} | 
|  | 62          */ | 
|  | 63         function comparator(a, b) | 
|  | 64         { | 
|  | 65             if (a.lineNumber !== b.line) | 
|  | 66                 return a.lineNumber - b.line; | 
|  | 67             return a.columnNumber - b.column; | 
|  | 68         } | 
|  | 69     }, | 
|  | 70 | 
|  | 71     /** | 
|  | 72      * @param {!WebInspector.UISourceCode} uiSourceCode | 
|  | 73      * @return {boolean} | 
|  | 74      */ | 
|  | 75     isBlackboxedUISourceCode: function(uiSourceCode) | 
|  | 76     { | 
|  | 77         var projectType = uiSourceCode.project().type(); | 
|  | 78         var isContentScript = projectType === WebInspector.projectTypes.ContentS
     cripts; | 
|  | 79         if (isContentScript && WebInspector.moduleSetting("skipContentScripts").
     get()) | 
|  | 80             return true; | 
|  | 81         var networkURL = this._networkMapping.networkURL(uiSourceCode); | 
|  | 82         var url = projectType === WebInspector.projectTypes.Formatter ? uiSource
     Code.url() : networkURL; | 
|  | 83         return this.isBlackboxedURL(url); | 
|  | 84     }, | 
|  | 85 | 
|  | 86     /** | 
|  | 87      * @param {string} url | 
|  | 88      * @return {boolean} | 
|  | 89      */ | 
|  | 90     isBlackboxedURL: function(url) | 
|  | 91     { | 
|  | 92         if (this._isBlackboxedURLCache.has(url)) | 
|  | 93             return !!this._isBlackboxedURLCache.get(url); | 
|  | 94         var regex = WebInspector.moduleSetting("skipStackFramesPattern").asRegEx
     p(); | 
|  | 95         var isBlackboxed = regex && regex.test(url); | 
|  | 96         this._isBlackboxedURLCache.set(url, isBlackboxed); | 
|  | 97         return isBlackboxed; | 
|  | 98     }, | 
|  | 99 | 
|  | 100     /** | 
|  | 101      * @param {!WebInspector.Script} script | 
|  | 102      * @param {?WebInspector.SourceMap} sourceMap | 
|  | 103      * @return {!Promise<undefined>} | 
|  | 104      */ | 
|  | 105     sourceMapLoaded: function(script, sourceMap) | 
|  | 106     { | 
|  | 107         if (!sourceMap) | 
|  | 108             return Promise.resolve(); | 
|  | 109         if (!this._scriptIdToPositions.has(script.scriptId)) | 
|  | 110             return Promise.resolve(); | 
|  | 111 | 
|  | 112         var mappings = sourceMap.mappings().slice(); | 
|  | 113         mappings.sort(mappingComparator); | 
|  | 114 | 
|  | 115         var previousScriptState = this._scriptIdToPositions.get(script.scriptId)
     ; | 
|  | 116         if (!mappings.length) { | 
|  | 117             if (previousScriptState.length > 0) | 
|  | 118                 return this._setScriptState(script, []).then(this._sourceMapLoad
     edForTest); | 
|  | 119         } | 
|  | 120 | 
|  | 121         var currentBlackboxed = false; | 
|  | 122         var isBlackboxed = false; | 
|  | 123         var positions = []; | 
|  | 124         // If content in script file begin is not mapped and one or more ranges 
     are blackboxed then blackbox it. | 
|  | 125         if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) { | 
|  | 126             positions.push({ line: 0, column: 0}); | 
|  | 127             currentBlackboxed = true; | 
|  | 128         } | 
|  | 129         for (var mapping of mappings) { | 
|  | 130             if (currentBlackboxed !== this.isBlackboxedURL(mapping.sourceURL)) { | 
|  | 131                 positions.push({ line: mapping.lineNumber, column: mapping.colum
     nNumber }); | 
|  | 132                 currentBlackboxed = !currentBlackboxed; | 
|  | 133             } | 
|  | 134             isBlackboxed = currentBlackboxed || isBlackboxed; | 
|  | 135         } | 
|  | 136         return this._setScriptState(script, !isBlackboxed ? [] : positions).then
     (this._sourceMapLoadedForTest); | 
|  | 137         /** | 
|  | 138          * @param {!WebInspector.SourceMap.Entry} a | 
|  | 139          * @param {!WebInspector.SourceMap.Entry} b | 
|  | 140          * @return {number} | 
|  | 141          */ | 
|  | 142         function mappingComparator(a, b) | 
|  | 143         { | 
|  | 144             if (a.lineNumber !== b.lineNumber) | 
|  | 145                 return a.lineNumber - b.lineNumber; | 
|  | 146             return a.columnNumber - b.columnNumber; | 
|  | 147         } | 
|  | 148     }, | 
|  | 149 | 
|  | 150     _sourceMapLoadedForTest: function() | 
|  | 151     { | 
|  | 152         // This method is sniffed in tests. | 
|  | 153     }, | 
|  | 154 | 
|  | 155     /** | 
|  | 156      * @param {string} url | 
|  | 157      * @return {boolean} | 
|  | 158      */ | 
|  | 159     canBlackboxURL: function(url) | 
|  | 160     { | 
|  | 161         return !!this._urlToRegExpString(url); | 
|  | 162     }, | 
|  | 163 | 
|  | 164     /** | 
|  | 165      * @param {string} url | 
|  | 166      */ | 
|  | 167     blackboxURL: function(url) | 
|  | 168     { | 
|  | 169         var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern")
     .getAsArray(); | 
|  | 170         var regexValue = this._urlToRegExpString(url); | 
|  | 171         if (!regexValue) | 
|  | 172             return; | 
|  | 173         var found = false; | 
|  | 174         for (var i = 0; i < regexPatterns.length; ++i) { | 
|  | 175             var item = regexPatterns[i]; | 
|  | 176             if (item.pattern === regexValue) { | 
|  | 177                 item.disabled = false; | 
|  | 178                 found = true; | 
|  | 179                 break; | 
|  | 180             } | 
|  | 181         } | 
|  | 182         if (!found) | 
|  | 183             regexPatterns.push({ pattern: regexValue }); | 
|  | 184         WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPat
     terns); | 
|  | 185     }, | 
|  | 186 | 
|  | 187     /** | 
|  | 188      * @param {string} url | 
|  | 189      * @param {boolean} isContentScript | 
|  | 190      */ | 
|  | 191     unblackbox: function(url, isContentScript) | 
|  | 192     { | 
|  | 193         if (isContentScript) | 
|  | 194             WebInspector.moduleSetting("skipContentScripts").set(false); | 
|  | 195 | 
|  | 196         var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern")
     .getAsArray(); | 
|  | 197         var regexValue = WebInspector.blackboxManager._urlToRegExpString(url); | 
|  | 198         if (!regexValue) | 
|  | 199             return; | 
|  | 200         regexPatterns = regexPatterns.filter(function(item) { | 
|  | 201             return item.pattern !== regexValue; | 
|  | 202         }); | 
|  | 203         for (var i = 0; i < regexPatterns.length; ++i) { | 
|  | 204             var item = regexPatterns[i]; | 
|  | 205             if (item.disabled) | 
|  | 206                 continue; | 
|  | 207             try { | 
|  | 208                 var regex = new RegExp(item.pattern); | 
|  | 209                 if (regex.test(url)) | 
|  | 210                     item.disabled = true; | 
|  | 211             } catch (e) { | 
|  | 212             } | 
|  | 213         } | 
|  | 214         WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPat
     terns); | 
|  | 215     }, | 
|  | 216 | 
|  | 217     _patternChanged: function() | 
|  | 218     { | 
|  | 219         this._isBlackboxedURLCache.clear(); | 
|  | 220 | 
|  | 221         var promises = []; | 
|  | 222         for (var debuggerModel of WebInspector.DebuggerModel.instances()) { | 
|  | 223             for (var scriptId in debuggerModel.scripts) { | 
|  | 224                 let script = debuggerModel.scripts[scriptId]; | 
|  | 225                 promises.push(this._addScript(script) | 
|  | 226                                   .then(() => this._debuggerWorkspaceBinding.sou
     rceMapForScript(script)) | 
|  | 227                                   .then(loadSourceMap.bind(this, script))); | 
|  | 228             } | 
|  | 229         } | 
|  | 230         Promise.all(promises).then(this._patternChangeFinishedForTests); | 
|  | 231 | 
|  | 232         /** | 
|  | 233          * @param {!WebInspector.Script} script | 
|  | 234          * @param {?WebInspector.SourceMap} sourceMap | 
|  | 235          * @return {!Promise<undefined>} | 
|  | 236          * @this {WebInspector.BlackboxManager} | 
|  | 237          */ | 
|  | 238         function loadSourceMap(script, sourceMap) | 
|  | 239         { | 
|  | 240             return this.sourceMapLoaded(script, sourceMap); | 
|  | 241         } | 
|  | 242     }, | 
|  | 243 | 
|  | 244     _patternChangeFinishedForTests: function() | 
|  | 245     { | 
|  | 246         // This method is sniffed in tests. | 
|  | 247     }, | 
|  | 248 | 
|  | 249     _globalObjectCleared: function() | 
|  | 250     { | 
|  | 251         this._scriptIdToPositions.clear(); | 
|  | 252         this._isBlackboxedURLCache.clear(); | 
|  | 253     }, | 
|  | 254 | 
|  | 255     /** | 
|  | 256      * @param {!WebInspector.Event} event | 
|  | 257      */ | 
|  | 258     _parsedScriptSource: function(event) | 
|  | 259     { | 
|  | 260         var script = /** @type {!WebInspector.Script} */ (event.data); | 
|  | 261         this._addScript(script); | 
|  | 262     }, | 
|  | 263 | 
|  | 264     /** | 
|  | 265      * @param {!WebInspector.Script} script | 
|  | 266      * @return {!Promise<undefined>} | 
|  | 267      */ | 
|  | 268     _addScript: function(script) | 
|  | 269     { | 
|  | 270         var blackboxed = this._isBlackboxedScript(script); | 
|  | 271         return this._setScriptState(script, blackboxed ? [ { line: 0, column: 0 
     } ] : []); | 
|  | 272     }, | 
|  | 273 | 
|  | 274     /** | 
|  | 275      * @param {!WebInspector.Script} script | 
|  | 276      * @return {boolean} | 
|  | 277      */ | 
|  | 278     _isBlackboxedScript: function(script) | 
|  | 279     { | 
|  | 280         if (script.isContentScript() && WebInspector.moduleSetting("skipContentS
     cripts").get()) | 
|  | 281             return true; | 
|  | 282         return this.isBlackboxedURL(script.sourceURL); | 
|  | 283     }, | 
|  | 284 | 
|  | 285     /** | 
|  | 286      * @param {!WebInspector.Script} script | 
|  | 287      * @param {!Array<!DebuggerAgent.ScriptPosition>} positions | 
|  | 288      * @return {!Promise<undefined>} | 
|  | 289      */ | 
|  | 290     _setScriptState: function(script, positions) | 
|  | 291     { | 
|  | 292         if (this._scriptIdToPositions.has(script.scriptId)) { | 
|  | 293             var hasChanged = false; | 
|  | 294             var previousScriptState = this._scriptIdToPositions.get(script.scrip
     tId); | 
|  | 295             hasChanged = previousScriptState.length !== positions.length; | 
|  | 296             for (var i = 0; !hasChanged && i < positions.length; ++i) | 
|  | 297                 hasChanged = positions[i].line !== previousScriptState[i].line |
     | positions[i].column !== previousScriptState[i].column; | 
|  | 298             if (!hasChanged) | 
|  | 299                 return Promise.resolve(); | 
|  | 300         } else { | 
|  | 301             if (positions.length === 0) | 
|  | 302                 return Promise.resolve().then(updateState.bind(this, false)); | 
|  | 303         } | 
|  | 304 | 
|  | 305         return script.setBlackboxedRanges(positions).then(updateState.bind(this)
     ); | 
|  | 306 | 
|  | 307         /** | 
|  | 308          * @param {boolean} success | 
|  | 309          * @this {WebInspector.BlackboxManager} | 
|  | 310          */ | 
|  | 311         function updateState(success) | 
|  | 312         { | 
|  | 313             if (success) | 
|  | 314                 this._scriptIdToPositions.set(script.scriptId, positions); | 
|  | 315             else if (!this._scriptIdToPositions.has(script.scriptId)) | 
|  | 316                 this._scriptIdToPositions.set(script.scriptId, []); | 
|  | 317         } | 
|  | 318     }, | 
|  | 319 | 
|  | 320     /** | 
|  | 321      * @param {string} url | 
|  | 322      * @return {string} | 
|  | 323      */ | 
|  | 324     _urlToRegExpString: function(url) | 
|  | 325     { | 
|  | 326         var parsedURL = new WebInspector.ParsedURL(url); | 
|  | 327         if (parsedURL.isAboutBlank() || parsedURL.isDataURL()) | 
|  | 328             return ""; | 
|  | 329         if (!parsedURL.isValid) | 
|  | 330             return "^" + url.escapeForRegExp() + "$"; | 
|  | 331         var name = parsedURL.lastPathComponent; | 
|  | 332         if (name) | 
|  | 333             name = "/" + name; | 
|  | 334         else if (parsedURL.folderPathComponents) | 
|  | 335             name = parsedURL.folderPathComponents + "/"; | 
|  | 336         if (!name) | 
|  | 337             name = parsedURL.host; | 
|  | 338         if (!name) | 
|  | 339             return ""; | 
|  | 340         var scheme = parsedURL.scheme; | 
|  | 341         var prefix = ""; | 
|  | 342         if (scheme && scheme !== "http" && scheme !== "https") { | 
|  | 343             prefix = "^" + scheme + "://"; | 
|  | 344             if (scheme === "chrome-extension") | 
|  | 345                 prefix += parsedURL.host + "\\b"; | 
|  | 346             prefix += ".*"; | 
|  | 347         } | 
|  | 348         return prefix + name.escapeForRegExp() + (url.endsWith(name) ? "$" : "\\
     b"); | 
|  | 349     } | 
|  | 350 } | 
|  | 351 | 
|  | 352 /** @type {!WebInspector.BlackboxManager} */ | 
|  | 353 WebInspector.blackboxManager; | 
| OLD | NEW | 
|---|