Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Unified Diff: third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js

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
Patch Set: rebased Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js b/third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js
new file mode 100644
index 0000000000000000000000000000000000000000..4fcfa0c67fda193ab15d0aa1c182e0e8b8402767
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js
@@ -0,0 +1,337 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
+ * @param {!WebInspector.NetworkMapping} networkMapping
+ */
+WebInspector.BlackboxManager = function(debuggerWorkspaceBinding, networkMapping)
+{
+ this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
+ this._networkMapping = networkMapping;
+
+ WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
+ WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this);
+ WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._patternChanged.bind(this));
+ WebInspector.moduleSetting("skipContentScripts").addChangeListener(this._patternChanged.bind(this));
+
+ /** @type {!Map<string, !Array<!DebuggerAgent.ScriptPosition>>} */
+ this._scripts = new Map();
dgozman 2016/02/17 01:34:44 this._scriptIdToPositions
kozy 2016/02/17 03:40:42 Done.
+ /** @type {!Map<string, boolean>} */
+ this._isBlackboxedURLCache = new Map();
+}
+
+WebInspector.BlackboxManager.prototype = {
+
+ /**
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ addChangeListener: function(listener, thisObject)
+ {
+ WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(listener, thisObject);
+ },
+
+ /**
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ removeChangeListener: function(listener, thisObject)
+ {
+ WebInspector.moduleSetting("skipStackFramesPattern").removeChangeListener(listener, thisObject);
+ },
+
+ /**
+ * @param {!WebInspector.DebuggerModel.Location} location
+ * @return {boolean}
+ */
+ isBlackboxedRawLocation: function(location)
+ {
+ if (!this._scripts.has(location.scriptId))
+ return false;
+ var positions = this._scripts.get(location.scriptId);
+ var index = positions.lowerBound(location, comparator);
+ return !!(index % 2);
+
+ function comparator(a, b)
dgozman 2016/02/17 01:34:44 JSDoc plesae.
kozy 2016/02/17 03:40:43 Done.
+ {
+ if (a.lineNumber !== b.line)
+ return a.lineNumber - b.line;
+ return a.columnNumber - b.column;
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ isBlackboxedUISourceCode: function(uiSourceCode)
+ {
+ var projectType = uiSourceCode.project().type();
+ var isContentScript = projectType === WebInspector.projectTypes.ContentScripts;
+ if (isContentScript && WebInspector.moduleSetting("skipContentScripts").get())
+ return true;
+ var networkURL = this._networkMapping.networkURL(uiSourceCode);
+ var url = projectType === WebInspector.projectTypes.Formatter ? uiSourceCode.url() : networkURL;
+ return this.isBlackboxedURL(url);
+ },
+
+ /**
+ * @param {string} url
+ * @return {boolean}
+ */
+ isBlackboxedURL: function(url)
+ {
+ if (this._isBlackboxedURLCache.has(url))
+ return !!this._isBlackboxedURLCache.get(url);
+ var regex = WebInspector.moduleSetting("skipStackFramesPattern").asRegExp();
+ var isBlackboxed = regex && regex.test(url);
+ this._isBlackboxedURLCache.set(url, isBlackboxed);
+ return isBlackboxed;
+ },
+
+ /**
+ * @param {!WebInspector.Script} script
+ * @param {?WebInspector.SourceMap} sourceMap
+ */
+ sourceMapLoaded: function(script, sourceMap)
+ {
+ if (!sourceMap)
+ return;
+ if (!this._scripts.has(script.scriptId))
+ return;
+
+ var mappings = sourceMap.mappings().slice();
+ mappings.sort(mappingComparator);
+
+ var previousScriptState = this._scripts.get(script.scriptId);
+ if (!mappings.length) {
+ if (previousScriptState.length > 0)
+ script.setBlackboxedRanges([]).then(this._setScriptState.bind(this, script));
+ return;
+ }
+
+ var currentBlackboxed = false;
+ var isBlackboxed = false;
+ var positions = [];
+ if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) {
dgozman 2016/02/17 01:34:44 Let's add a comment.
kozy 2016/02/17 03:40:43 Done.
+ positions.push({ line: 0, column: 0});
+ currentBlackboxed = true;
+ }
+ for (var mapping of sourceMap.mappings()) {
+ if (currentBlackboxed !== this.isBlackboxedURL(mapping.sourceURL)) {
+ positions.push({ line: mapping.lineNumber, column: mapping.columnNumber });
+ currentBlackboxed = !currentBlackboxed;
+ }
+ if (currentBlackboxed)
+ isBlackboxed = true;
+ }
+
+ var isChanged = previousScriptState.length !== positions.length;
+ for (var i = 0; !isChanged && i < positions.length; ++i)
+ isChanged = positions[i].line !== previousScriptState[i].line || positions[i].column !== previousScriptState[i].column;
+ if (!isChanged)
dgozman 2016/02/17 01:34:44 hasChanged
kozy 2016/02/17 03:40:42 Done.
+ return;
+
+ if (isBlackboxed)
dgozman 2016/02/17 01:34:44 Can we get rid of this flag?
kozy 2016/02/17 03:40:42 We can't rid of this because when positions.length
+ script.setBlackboxedRanges(positions).then(this._setScriptState.bind(this, script));
+ else
+ script.setBlackboxedRanges([]).then(this._setScriptState.bind(this, script));
+ /**
+ * @param {!WebInspector.SourceMap.Entry} a
+ * @param {!WebInspector.SourceMap.Entry} b
dgozman 2016/02/17 01:34:44 @return {number}
kozy 2016/02/17 03:40:43 Done.
+ */
+ function mappingComparator(a, b)
+ {
+ if (a.lineNumber !== b.lineNumber)
+ return a.lineNumber - b.lineNumber;
+ return a.columnNumber - b.columnNumber;
+ }
+ },
+
+ /**
+ * @param {string} url
+ * @return {boolean}
+ */
+ canBlackboxURL: function(url)
+ {
+ return !!this._urlToRegExpString(url);
+ },
+
+ /**
+ * @param {string} url
+ */
+ blackboxURL: function(url)
+ {
+ var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern").getAsArray();
+ var regexValue = this._urlToRegExpString(url);
+ if (!regexValue)
+ return;
+ var found = false;
+ for (var i = 0; i < regexPatterns.length; ++i) {
+ var item = regexPatterns[i];
+ if (item.pattern === regexValue) {
+ item.disabled = false;
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ regexPatterns.push({ pattern: regexValue });
+ WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPatterns);
+ },
+
+ /**
+ * @param {string} url
+ * @param {boolean} isContentScript
+ */
+ unblackbox: function(url, isContentScript)
+ {
+ if (isContentScript)
+ WebInspector.moduleSetting("skipContentScripts").set(false);
+
+ var regexPatterns = WebInspector.moduleSetting("skipStackFramesPattern").getAsArray();
+ var regexValue = WebInspector.blackboxManager._urlToRegExpString(url);
+ if (!regexValue)
+ return;
+ regexPatterns = regexPatterns.filter(function(item) {
+ return item.pattern !== regexValue;
+ });
+ for (var i = 0; i < regexPatterns.length; ++i) {
+ var item = regexPatterns[i];
+ if (item.disabled)
+ continue;
+ try {
+ var regex = new RegExp(item.pattern);
+ if (regex.test(url))
+ item.disabled = true;
+ } catch (e) {
+ }
+ }
+ WebInspector.moduleSetting("skipStackFramesPattern").setAsArray(regexPatterns);
+ },
+
+ _patternChanged: function()
+ {
+ this._isBlackboxedURLCache.clear();
+ this._scripts.clear();
+
+ var promises = [];
+ for (var debuggerModel of WebInspector.DebuggerModel.instances()) {
+ for (var scriptId in debuggerModel.scripts) {
+ var script = debuggerModel.scripts[scriptId];
+ promises.push(this._addScript(script).then(loadSourceMap.bind(this, script)));
dgozman 2016/02/17 01:34:44 this._addScript(script) .then(() => this._sour
kozy 2016/02/17 03:40:42 Done.
+ }
+ }
+ Promise.all(promises).then(this._patternChangeFinishedForTests);
+
+ /**
+ * @param {!WebInspector.Script} script
+ * @this {!WebInspector.BlackboxManager}
+ */
+ function loadSourceMap(script)
+ {
+ this.sourceMapLoaded(script, this._sourceMapForScript(script));
+ }
+ },
+
+ // This method is sniffed in tests.
+ _patternChangeFinishedForTests: function()
+ {
+ },
+
+ _globalObjectCleared: function()
+ {
+ this._scripts.clear();
+ this._isBlackboxedURLCache.clear();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _parsedScriptSource: function(event)
+ {
+ var script = /** @type {!WebInspector.Script} */ (event.data);
+ this._addScript(script);
+ },
+
+ /**
+ * @param {!WebInspector.Script} script
+ * @return {!Promise<undefined>}
+ */
+ _addScript: function(script)
+ {
+ var blackboxed = this._isBlackboxedScript(script);
+ if (!blackboxed)
+ return Promise.resolve(this._setScriptState(script, []));
+ return script.setBlackboxedRanges([ { line: 0, column: 0 } ]).then(this._setScriptState.bind(this, script));
+ },
+
+ /**
+ * @param {!WebInspector.Script} script
+ * @return {boolean}
+ */
+ _isBlackboxedScript: function(script)
+ {
+ if (script.isContentScript() && WebInspector.moduleSetting("skipContentScripts").get())
+ return true;
+ return this.isBlackboxedURL(script.sourceURL);
+ },
+
+ /**
+ * @param {!WebInspector.Script} script
+ * @return {?WebInspector.SourceMap}
+ */
+ _sourceMapForScript: function(script)
+ {
+ return this._debuggerWorkspaceBinding.sourceMapForScript(script);
dgozman 2016/02/17 01:34:44 Inline it!
kozy 2016/02/17 03:40:43 Done.
+ },
+
+ /**
+ * @param {!WebInspector.Script} script
+ * @param {?Array<!DebuggerAgent.ScriptPosition>} positions
+ */
+ _setScriptState: function(script, positions)
+ {
+ if (positions)
+ this._scripts.set(script.scriptId, positions);
+ else if (!this._scripts.has(script.scriptId))
+ this._scripts.set(script.scriptId, []);
+ },
+
+ /**
+ * @param {string} url
+ * @return {string}
+ */
+ _urlToRegExpString: function(url)
+ {
+ var parsedURL = new WebInspector.ParsedURL(url);
+ if (parsedURL.isAboutBlank() || parsedURL.isDataURL())
+ return "";
+ if (!parsedURL.isValid)
+ return "^" + url.escapeForRegExp() + "$";
+ var name = parsedURL.lastPathComponent;
+ if (name)
+ name = "/" + name;
+ else if (parsedURL.folderPathComponents)
+ name = parsedURL.folderPathComponents + "/";
+ if (!name)
+ name = parsedURL.host;
+ if (!name)
+ return "";
+ var scheme = parsedURL.scheme;
+ var prefix = "";
+ if (scheme && scheme !== "http" && scheme !== "https") {
+ prefix = "^" + scheme + "://";
+ if (scheme === "chrome-extension")
+ prefix += parsedURL.host + "\\b";
+ prefix += ".*";
+ }
+ return prefix + name.escapeForRegExp() + (url.endsWith(name) ? "$" : "\\b");
+ }
+}
+
+/** @type {!WebInspector.BlackboxManager} */
+WebInspector.blackboxManager;

Powered by Google App Engine
This is Rietveld 408576698