Diff
Modified: trunk/LayoutTests/ChangeLog (249449 => 249450)
--- trunk/LayoutTests/ChangeLog 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/LayoutTests/ChangeLog 2019-09-04 02:26:37 UTC (rev 249450)
@@ -1,5 +1,19 @@
2019-09-03 Devin Rousso <drou...@apple.com>
+ Web Inspector: implement blackboxing of script resources
+ https://bugs.webkit.org/show_bug.cgi?id=17240
+ <rdar://problem/5732847>
+
+ Reviewed by Joseph Pecoraro.
+
+ * inspector/debugger/setShouldBlackboxURL.html: Added.
+ * inspector/debugger/setShouldBlackboxURL-expected.txt: Added.
+
+ * inspector/model/remote-object-api-expected.txt:
+ Update output since `WI.TestHarness.prototype.expectException` now logs the `.constructor.name`.
+
+2019-09-03 Devin Rousso <drou...@apple.com>
+
REGRESSION (r249132): [macOS WK2] Layout Test inspector/layers/layerTreeDidChange.html is a flaky failure
https://bugs.webkit.org/show_bug.cgi?id=201435
Added: trunk/LayoutTests/inspector/debugger/setShouldBlackboxURL-expected.txt (0 => 249450)
--- trunk/LayoutTests/inspector/debugger/setShouldBlackboxURL-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/debugger/setShouldBlackboxURL-expected.txt 2019-09-04 02:26:37 UTC (rev 249450)
@@ -0,0 +1,105 @@
+Tests Debugger.setShouldBlackboxURL.
+
+
+== Running test suite: Debugger.setShouldBlackboxURL
+-- Running test case: Debugger.setShouldBlackboxURL.stepOver
+Evaluating 'createScripts("stepOver")'...
+Blackboxing 'stepOverMiddle.js'...
+Setting breakpoint in 'stepOverInner.js'...
+Evaluating 'stepOverOuter(10)'...
+
+Paused in 'stepOverInner:3:1'.
+Reason: 'Breakpoint'
+{
+ "breakpointId": "stepOverInner.js:3:0"
+}
+Stepping over...
+
+Paused in 'stepOverOuter:3:1'.
+Reason: 'BlackboxedScript'
+{
+ "originalReason": "other",
+ "originalData": {
+ "breakpointId": "stepOverInner.js:3:0"
+ }
+}
+Stepping over...
+
+Resuming...
+PASS: Resumed.
+PASS: Should not pause in 'stepOverMiddle'.
+
+-- Running test case: Debugger.setShouldBlackboxURL.PauseInCaller
+Evaluating 'createScripts("pauseInCaller")'...
+Blackboxing 'pauseInCallerInner.js'...
+Setting breakpoint in 'pauseInCallerInner.js'...
+Evaluating 'pauseInCallerOuter(10)'...
+
+Paused in 'pauseInCallerMiddle:3:1'.
+Reason: 'BlackboxedScript'
+{
+ "originalReason": "Breakpoint",
+ "originalData": {
+ "breakpointId": "pauseInCallerInner.js:2:0"
+ }
+}
+Stepping over...
+
+Paused in 'pauseInCallerOuter:3:1'.
+Reason: 'other'
+Stepping over...
+
+Resuming...
+PASS: Resumed.
+PASS: Should not pause in 'pauseInCallerInner'.
+
+-- Running test case: Debugger.setShouldBlackboxURL.PauseInCallee
+Evaluating 'createScripts("pauseInCallee")'...
+Blackboxing 'pauseInCalleeOuter.js'...
+Setting breakpoint in 'pauseInCalleeOuter.js'...
+Evaluating 'pauseInCalleeOuter(10)'...
+
+Paused in 'pauseInCalleeMiddle:2:4'.
+Reason: 'BlackboxedScript'
+{
+ "originalReason": "Breakpoint",
+ "originalData": {
+ "breakpointId": "pauseInCalleeOuter.js:2:0"
+ }
+}
+Stepping over...
+
+Paused in 'pauseInCalleeMiddle:3:1'.
+Reason: 'other'
+Stepping over...
+
+Resuming...
+PASS: Resumed.
+PASS: Should not pause in 'pauseInCalleeOuter'.
+
+-- Running test case: Debugger.setShouldBlackboxURL.Invalid.emptyURL
+PASS: Should produce an exception.
+{
+ "code": -32000,
+ "message": "URL must not be empty",
+ "data": [
+ {
+ "code": -32000,
+ "message": "URL must not be empty"
+ }
+ ]
+}
+
+-- Running test case: Debugger.setShouldBlackboxURL.Invalid.injectedScript
+PASS: Should produce an exception.
+{
+ "code": -32000,
+ "message": "Blackboxing of internal scripts is controlled by 'Debugger.setPauseForInternalScripts'",
+ "data": [
+ {
+ "code": -32000,
+ "message": "Blackboxing of internal scripts is controlled by 'Debugger.setPauseForInternalScripts'"
+ }
+ ]
+}
+
Added: trunk/LayoutTests/inspector/debugger/setShouldBlackboxURL.html (0 => 249450)
--- trunk/LayoutTests/inspector/debugger/setShouldBlackboxURL.html (rev 0)
+++ trunk/LayoutTests/inspector/debugger/setShouldBlackboxURL.html 2019-09-04 02:26:37 UTC (rev 249450)
@@ -0,0 +1,228 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function createScripts(id) {
+ eval(
+`
+window.${id}Inner = function ${id}Inner(x) {
+ return x + 42;
+};
+//# sourceURL=${id}Inner.js
+`
+ );
+
+ eval(
+`
+window.${id}Middle = function ${id}Middle(x) {
+ return ${id}Inner(x);
+};
+//# sourceURL=${id}Middle.js
+`
+ );
+
+ eval(
+`
+window.${id}Outer = function ${id}Outer(x) {
+ return ${id}Middle(x);
+};
+//# sourceURL=${id}Outer.js
+`
+ );
+}
+
+function test()
+{
+ let suite = ProtocolTest.createAsyncSuite("Debugger.setShouldBlackboxURL");
+
+ let sourceURLRegExpQueries = new Map;
+ let pausedFunctionNames = [];
+ let resumeCallback = null;
+
+ InspectorProtocol.sendCommand("Debugger.enable", {});
+ InspectorProtocol.sendCommand("Debugger.setBreakpointsActive", {active: true});
+
+ InspectorProtocol.eventHandler["Debugger.scriptParsed"] = function(message) {
+ let sourceURL = message.params.sourceURL;
+ for (let [regExp, callback] of sourceURLRegExpQueries) {
+ if (regExp.test(sourceURL)) {
+ sourceURLRegExpQueries.delete(regExp);
+ callback(sourceURL);
+ }
+ };
+ };
+
+ InspectorProtocol.eventHandler["Debugger.paused"] = function(message) {
+ let topCallFrame = message.params.callFrames[0];
+ let functionName = topCallFrame.functionName;
+ if (functionName === "global code") {
+ ProtocolTest.log("Resuming...");
+ InspectorProtocol.sendCommand(`Debugger.resume`, {}, InspectorProtocol.checkForError);
+ return;
+ }
+
+ ProtocolTest.log(`Paused in '${functionName}:${topCallFrame.location.lineNumber}:${topCallFrame.location.columnNumber}'.`);
+ ProtocolTest.log(`Reason: '${message.params.reason}'`);
+ if (message.params.data)
+ ProtocolTest.json(message.params.data);
+ pausedFunctionNames.push(functionName);
+
+ ProtocolTest.log("Stepping over...");
+ ProtocolTest.newline();
+ InspectorProtocol.sendCommand(`Debugger.stepOver`, {}, InspectorProtocol.checkForError);
+ };
+
+ InspectorProtocol.eventHandler["Debugger.resumed"] = function(message) {
+ ProtocolTest.pass("Resumed.");
+ resumeCallback();
+ };
+
+ async function setBlackbox(url) {
+ ProtocolTest.log(`Blackboxing '${url}'...`);
+ await InspectorProtocol.awaitCommand({
+ method: "Debugger.setShouldBlackboxURL",
+ params: {url, shouldBlackbox: true},
+ });
+ }
+
+ async function setBreakpoint(url, lineNumber) {
+ ProtocolTest.log(`Setting breakpoint in '${url}'...`);
+ await InspectorProtocol.awaitCommand({
+ method: "Debugger.setBreakpointByUrl",
+ params: {url, lineNumber},
+ });
+ }
+
+ async function listenForSourceParsed(sourceURLRegExp) {
+ return new Promise((resolve, reject) => {
+ sourceURLRegExpQueries.set(sourceURLRegExp, resolve);
+ });
+ }
+
+ async function evaluate(_expression_) {
+ ProtocolTest.log(`Evaluating '${_expression_}'...`);
+ return InspectorProtocol.awaitCommand({
+ method: "Runtime.evaluate",
+ params: {_expression_},
+ });
+ }
+
+ suite.addTestCase({
+ name: "Debugger.setShouldBlackboxURL.stepOver",
+ description: "Check that stepping through a blackboxed script doesn't pause.",
+ async test() {
+ let resumePromise = new Promise((resolve, reject) => {
+ resumeCallback = function() {
+ ProtocolTest.expectThat(!pausedFunctionNames.includes("stepOverMiddle"), "Should not pause in 'stepOverMiddle'.");
+ resolve();
+ };
+ });
+
+ let [stepOverInnerSourceURL, stepOverMiddleSourceURL] = await Promise.all([
+ listenForSourceParsed(/stepOverInner\.js$/),
+ listenForSourceParsed(/stepOverMiddle\.js$/),
+ listenForSourceParsed(/stepOverOuter\.js$/),
+ evaluate(`createScripts("stepOver")`),
+ ]);
+
+ await setBlackbox(stepOverMiddleSourceURL);
+ await setBreakpoint(stepOverInnerSourceURL, 3); // last line of function, so it only pauses once
+ evaluate(`stepOverOuter(10)`);
+
+ ProtocolTest.newline();
+
+ await resumePromise;
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setShouldBlackboxURL.PauseInCaller",
+ description: "Check that the debugger will pause in the caller if a breakpoint is set in a blackboxed script.",
+ async test() {
+ let resumePromise = new Promise((resolve, reject) => {
+ resumeCallback = function() {
+ ProtocolTest.expectThat(!pausedFunctionNames.includes("pauseInCallerInner"), "Should not pause in 'pauseInCallerInner'.");
+ resolve();
+ };
+ });
+
+ let [pauseInCallerInnerSourceURL] = await Promise.all([
+ listenForSourceParsed(/pauseInCallerInner\.js$/),
+ listenForSourceParsed(/pauseInCallerMiddle\.js$/),
+ listenForSourceParsed(/pauseInCallerOuter\.js$/),
+ evaluate(`createScripts("pauseInCaller")`),
+ ]);
+
+ await setBlackbox(pauseInCallerInnerSourceURL);
+ await setBreakpoint(pauseInCallerInnerSourceURL, 2);
+ evaluate(`pauseInCallerOuter(10)`);
+
+ ProtocolTest.newline();
+
+ await resumePromise;
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setShouldBlackboxURL.PauseInCallee",
+ description: "Check that the debugger will pause in the callee if a breakpoint is set in a blackboxed script.",
+ async test() {
+ let resumePromise = new Promise((resolve, reject) => {
+ resumeCallback = function() {
+ ProtocolTest.expectThat(!pausedFunctionNames.includes("pauseInCalleeOuter"), "Should not pause in 'pauseInCalleeOuter'.");
+ resolve();
+ };
+ });
+
+ let [pauseInCalleeInnerSourceURL, pauseInCalleeMiddleSourceURL, pauseInCalleeOuterSourceURL] = await Promise.all([
+ listenForSourceParsed(/pauseInCalleeInner\.js$/),
+ listenForSourceParsed(/pauseInCalleeMiddle\.js$/),
+ listenForSourceParsed(/pauseInCalleeOuter\.js$/),
+ evaluate(`createScripts("pauseInCallee")`),
+ ]);
+
+ await setBlackbox(pauseInCalleeOuterSourceURL);
+ await setBreakpoint(pauseInCalleeOuterSourceURL, 2);
+ evaluate(`pauseInCalleeOuter(10)`);
+
+ ProtocolTest.newline();
+
+ await resumePromise;
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setShouldBlackboxURL.Invalid.emptyURL",
+ description: "Check that an error is thrown if the given url is empty.",
+ async test() {
+ await ProtocolTest.expectException(async () => {
+ await InspectorProtocol.awaitCommand({
+ method: "Debugger.setShouldBlackboxURL",
+ params: {url: "", shouldBlackbox: true},
+ });
+ });
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setShouldBlackboxURL.Invalid.injectedScript",
+ description: "Check that an error is thrown if the given url matches an injected script url.",
+ async test() {
+ await ProtocolTest.expectException(async () => {
+ await InspectorProtocol.awaitCommand({
+ method: "Debugger.setShouldBlackboxURL",
+ params: {url: "__InjectedScript__test.js", shouldBlackbox: true},
+ });
+ });
+ },
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests Debugger.setShouldBlackboxURL.</p>
+</body>
+</html>
Modified: trunk/LayoutTests/inspector/model/remote-object-api-expected.txt (249449 => 249450)
--- trunk/LayoutTests/inspector/model/remote-object-api-expected.txt 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/LayoutTests/inspector/model/remote-object-api-expected.txt 2019-09-04 02:26:37 UTC (rev 249450)
@@ -33,7 +33,7 @@
-- Running test case: RemoteObject.getProperty.FailureWithPromise
PASS: Should produce an exception.
-[object Object]
+RemoteObject
-- Running test case: RemoteObject.fetchProperties.Success
PASS: Result object should contain three keys.
Modified: trunk/Source/_javascript_Core/ChangeLog (249449 => 249450)
--- trunk/Source/_javascript_Core/ChangeLog 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-09-04 02:26:37 UTC (rev 249450)
@@ -1,3 +1,49 @@
+2019-09-03 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: implement blackboxing of script resources
+ https://bugs.webkit.org/show_bug.cgi?id=17240
+ <rdar://problem/5732847>
+
+ Reviewed by Joseph Pecoraro.
+
+ When a script is blackboxed and the debugger attempts to pause in that script, the pause
+ reason/data will be saved and execution will continue until it has left the blackboxed
+ script. Once outside, execution is paused with the saved reason/data.
+
+ This is especially useful when debugging issues using libraries/frameworks, as it allows the
+ developer to "skip" the internal logic of the library/framework and instead focus only on
+ how they're using it.
+
+ * inspector/protocol/Debugger.json:
+ Add `setShouldBlackboxURL` command.
+
+ * inspector/agents/InspectorDebuggerAgent.h:
+ * inspector/agents/InspectorDebuggerAgent.cpp:
+ (Inspector::InspectorDebuggerAgent):
+ (Inspector::InspectorDebuggerAgent::enable):
+ (Inspector::InspectorDebuggerAgent::updatePauseReasonAndData): Added.
+ (Inspector::InspectorDebuggerAgent::schedulePauseOnNextStatement):
+ (Inspector::InspectorDebuggerAgent::cancelPauseOnNextStatement):
+ (Inspector::InspectorDebuggerAgent::setShouldBlackboxURL): Added.
+ (Inspector::InspectorDebuggerAgent::setPauseForInternalScripts):
+ (Inspector::InspectorDebuggerAgent::didParseSource):
+ (Inspector::InspectorDebuggerAgent::didPause):
+ (Inspector::InspectorDebuggerAgent::didContinue):
+ (Inspector::InspectorDebuggerAgent::breakProgram):
+ (Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState):
+ (Inspector::InspectorDebuggerAgent::clearPauseDetails): Added.
+ (Inspector::InspectorDebuggerAgent::clearBreakDetails): Deleted.
+ Renamed "break" to "pause" to match `Debugger` naming.
+
+ * debugger/Debugger.h:
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::pauseIfNeeded):
+ (JSC::Debugger::setBlackboxType): Added.
+ (JSC::Debugger::clearBlackbox): Added.
+ (JSC::Debugger::isBlacklisted const): Deleted.
+ (JSC::Debugger::addToBlacklist): Deleted.
+ (JSC::Debugger::clearBlacklist): Deleted.
+
2019-09-03 Mark Lam <mark....@apple.com>
Remove the need to pass performJITMemcpy as a pointer.
Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (249449 => 249450)
--- trunk/Source/_javascript_Core/debugger/Debugger.cpp 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp 2019-09-04 02:26:37 UTC (rev 249450)
@@ -695,7 +695,9 @@
return;
intptr_t sourceID = DebuggerCallFrame::sourceIDForCallFrame(m_currentCallFrame);
- if (isBlacklisted(sourceID))
+
+ auto blackboxTypeIterator = m_blackboxedScripts.find(sourceID);
+ if (blackboxTypeIterator != m_blackboxedScripts.end() && blackboxTypeIterator->value == BlackboxType::Ignored)
return;
DebuggerPausedScope debuggerPausedScope(*this);
@@ -713,6 +715,7 @@
if (!pauseNow)
return;
+ bool afterBlackboxedScript = m_afterBlackboxedScript;
clearNextPauseState();
// Make sure we are not going to pause again on breakpoint actions by
@@ -736,8 +739,20 @@
m_pausingBreakpointID = breakpoint.id;
}
+ if (blackboxTypeIterator != m_blackboxedScripts.end() && blackboxTypeIterator->value == BlackboxType::Deferred) {
+ m_afterBlackboxedScript = true;
+ setPauseOnNextStatement(true);
+ return;
+ }
+
{
- PauseReasonDeclaration reason(*this, didHitBreakpoint ? PausedForBreakpoint : m_reasonForPause);
+ auto reason = m_reasonForPause;
+ if (afterBlackboxedScript)
+ reason = PausedAfterBlackboxedScript;
+ else if (didHitBreakpoint)
+ reason = PausedForBreakpoint;
+ PauseReasonDeclaration rauseReasonDeclaration(*this, reason);
+
handlePause(vmEntryGlobalObject, m_reasonForPause);
scope.releaseAssertNoException();
}
@@ -908,6 +923,7 @@
m_pauseOnCallFrame = nullptr;
m_pauseAtNextOpportunity = false;
m_pauseOnStepOut = false;
+ m_afterBlackboxedScript = false;
}
void Debugger::didReachBreakpoint(CallFrame* callFrame)
@@ -928,19 +944,17 @@
return *m_currentDebuggerCallFrame;
}
-bool Debugger::isBlacklisted(SourceID sourceID) const
+void Debugger::setBlackboxType(SourceID sourceID, Optional<BlackboxType> type)
{
- return m_blacklistedScripts.contains(sourceID);
+ if (type)
+ m_blackboxedScripts.set(sourceID, type.value());
+ else
+ m_blackboxedScripts.remove(sourceID);
}
-void Debugger::addToBlacklist(SourceID sourceID)
+void Debugger::clearBlackbox()
{
- m_blacklistedScripts.add(sourceID);
+ m_blackboxedScripts.clear();
}
-void Debugger::clearBlacklist()
-{
- m_blacklistedScripts.clear();
-}
-
} // namespace JSC
Modified: trunk/Source/_javascript_Core/debugger/Debugger.h (249449 => 249450)
--- trunk/Source/_javascript_Core/debugger/Debugger.h 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/_javascript_Core/debugger/Debugger.h 2019-09-04 02:26:37 UTC (rev 249450)
@@ -100,6 +100,7 @@
PausedAtEndOfProgram,
PausedForBreakpoint,
PausedForDebuggerStatement,
+ PausedAfterBlackboxedScript,
};
ReasonForPause reasonForPause() const { return m_reasonForPause; }
BreakpointID pausingBreakpointID() const { return m_pausingBreakpointID; }
@@ -111,9 +112,9 @@
void stepOverStatement();
void stepOutOfFunction();
- bool isBlacklisted(SourceID) const;
- void addToBlacklist(SourceID);
- void clearBlacklist();
+ enum class BlackboxType { Deferred, Ignored };
+ void setBlackboxType(SourceID, Optional<BlackboxType>);
+ void clearBlackbox();
bool isPaused() const { return m_isPaused; }
bool isStepping() const { return m_steppingMode == SteppingModeEnabled; }
@@ -224,7 +225,7 @@
VM& m_vm;
HashSet<JSGlobalObject*> m_globalObjects;
HashMap<SourceID, DebuggerParseData, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> m_parseDataMap;
- HashSet<SourceID, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> m_blacklistedScripts;
+ HashMap<SourceID, BlackboxType, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> m_blackboxedScripts;
PauseOnExceptionsState m_pauseOnExceptionsState;
bool m_pauseAtNextOpportunity : 1;
@@ -242,6 +243,7 @@
CallFrame* m_currentCallFrame { nullptr };
unsigned m_lastExecutedLine;
SourceID m_lastExecutedSourceID;
+ bool m_afterBlackboxedScript { false };
BreakpointID m_topBreakpointID;
BreakpointID m_pausingBreakpointID;
Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (249449 => 249450)
--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp 2019-09-04 02:26:37 UTC (rev 249450)
@@ -41,6 +41,7 @@
#include "ScriptCallStackFactory.h"
#include "ScriptDebugServer.h"
#include "ScriptObject.h"
+#include <wtf/Function.h>
#include <wtf/JSONValues.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/Stopwatch.h>
@@ -60,6 +61,11 @@
return makeString("breakpoint-action-", action.identifier);
}
+static bool isWebKitInjectedScript(const String& sourceURL)
+{
+ return sourceURL.startsWith("__InjectedScript_") && sourceURL.endsWith(".js");
+}
+
InspectorDebuggerAgent::InspectorDebuggerAgent(AgentContext& context)
: InspectorAgentBase("Debugger"_s)
, m_frontendDispatcher(makeUnique<DebuggerFrontendDispatcher>(context.frontendRouter))
@@ -67,8 +73,8 @@
, m_scriptDebugServer(context.environment.scriptDebugServer())
, m_injectedScriptManager(context.injectedScriptManager)
{
- // FIXME: make breakReason optional so that there was no need to init it with "other".
- clearBreakDetails();
+ // FIXME: make pauseReason optional so that there was no need to init it with "other".
+ clearPauseDetails();
}
InspectorDebuggerAgent::~InspectorDebuggerAgent() = default;
@@ -91,6 +97,16 @@
for (auto* listener : copyToVector(m_listeners))
listener->debuggerWasEnabled();
+
+ for (auto& [sourceID, script] : m_scripts) {
+ Optional<JSC::Debugger::BlackboxType> blackboxType;
+ if (isWebKitInjectedScript(script.sourceURL)) {
+ if (!m_pauseForInternalScripts)
+ blackboxType = JSC::Debugger::BlackboxType::Ignored;
+ } else if ((!script.sourceURL.isEmpty() && m_blackboxedURLs.contains(script.sourceURL)) || (!script.url.isEmpty() && m_blackboxedURLs.contains(script.url)))
+ blackboxType = JSC::Debugger::BlackboxType::Deferred;
+ m_scriptDebugServer.setBlackboxType(sourceID, blackboxType);
+ }
}
void InspectorDebuggerAgent::disable(bool isBeingDestroyed)
@@ -169,6 +185,17 @@
m_scriptDebugServer.setSuppressAllPauses(suppress);
}
+void InspectorDebuggerAgent::updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason reason, RefPtr<JSON::Object>&& data)
+{
+ if (m_pauseReason != DebuggerFrontendDispatcher::Reason::BlackboxedScript) {
+ m_preBlackboxPauseReason = m_pauseReason;
+ m_preBlackboxPauseData = WTFMove(m_pauseData);
+ }
+
+ m_pauseReason = reason;
+ m_pauseData = WTFMove(data);
+}
+
static RefPtr<JSON::Object> buildAssertPauseReason(const String& message)
{
auto reason = Protocol::Debugger::AssertPauseReason::create().release();
@@ -698,7 +725,7 @@
injectedScript.getFunctionDetails(errorString, functionId, details);
}
-void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<JSON::Object>&& data)
+void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerFrontendDispatcher::Reason reason, RefPtr<JSON::Object>&& data)
{
if (m_javaScriptPauseScheduled)
return;
@@ -705,8 +732,7 @@
m_javaScriptPauseScheduled = true;
- m_breakReason = breakReason;
- m_breakData = WTFMove(data);
+ updatePauseReasonAndData(reason, WTFMove(data));
JSC::JSLockHolder locker(m_scriptDebugServer.vm());
m_scriptDebugServer.setPauseOnNextStatement(true);
@@ -719,7 +745,7 @@
m_javaScriptPauseScheduled = false;
- clearBreakDetails();
+ clearPauseDetails();
m_scriptDebugServer.setPauseOnNextStatement(false);
m_enablePauseWhenIdle = false;
}
@@ -864,6 +890,33 @@
}
}
+void InspectorDebuggerAgent::setShouldBlackboxURL(ErrorString& errorString, const String& url, bool shouldBlackbox)
+{
+ if (url.isEmpty()) {
+ errorString = "URL must not be empty"_s;
+ return;
+ }
+
+ if (isWebKitInjectedScript(url)) {
+ errorString = "Blackboxing of internal scripts is controlled by 'Debugger.setPauseForInternalScripts'"_s;
+ return;
+ }
+
+ if (shouldBlackbox)
+ m_blackboxedURLs.add(url);
+ else
+ m_blackboxedURLs.remove(url);
+
+ auto blackboxType = shouldBlackbox ? Optional<JSC::Debugger::BlackboxType>(JSC::Debugger::BlackboxType::Deferred) : WTF::nullopt;
+ for (auto& [sourceID, script] : m_scripts) {
+ if (isWebKitInjectedScript(script.sourceURL))
+ continue;
+ if (script.sourceURL != url && script.url != url)
+ continue;
+ m_scriptDebugServer.setBlackboxType(sourceID, blackboxType);
+ }
+}
+
void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directiveText)
{
if (m_scriptDebugServer.pauseOnExceptionsState() != JSC::Debugger::DontPauseOnExceptions)
@@ -891,15 +944,14 @@
m_pauseForInternalScripts = shouldPause;
- if (m_pauseForInternalScripts)
- m_scriptDebugServer.clearBlacklist();
+ auto blackboxType = !m_pauseForInternalScripts ? Optional<JSC::Debugger::BlackboxType>(JSC::Debugger::BlackboxType::Ignored) : WTF::nullopt;
+ for (auto& [sourceID, script] : m_scripts) {
+ if (!isWebKitInjectedScript(script.sourceURL))
+ continue;
+ m_scriptDebugServer.setBlackboxType(sourceID, blackboxType);
+ }
}
-static bool isWebKitInjectedScript(const String& sourceURL)
-{
- return sourceURL.startsWith("__InjectedScript_") && sourceURL.endsWith(".js");
-}
-
void InspectorDebuggerAgent::didParseSource(JSC::SourceID sourceID, const Script& script)
{
String scriptIDStr = String::number(sourceID);
@@ -916,8 +968,11 @@
m_scripts.set(sourceID, script);
- if (hasSourceURL && isWebKitInjectedScript(sourceURL) && !m_pauseForInternalScripts)
- m_scriptDebugServer.addToBlacklist(sourceID);
+ if (isWebKitInjectedScript(sourceURL)) {
+ if (!m_pauseForInternalScripts)
+ m_scriptDebugServer.setBlackboxType(sourceID, JSC::Debugger::BlackboxType::Ignored);
+ } else if ((hasSourceURL && m_blackboxedURLs.contains(sourceURL)) || (!script.url.isEmpty() && m_blackboxedURLs.contains(script.url)))
+ m_scriptDebugServer.setBlackboxType(sourceID, JSC::Debugger::BlackboxType::Deferred);
String scriptURLForBreakpoints = hasSourceURL ? script.sourceURL : script.url;
if (scriptURLForBreakpoints.isEmpty())
@@ -996,24 +1051,30 @@
InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(&scriptState);
// If a high level pause pause reason is not already set, try to infer a reason from the debugger.
- if (m_breakReason == DebuggerFrontendDispatcher::Reason::Other) {
+ if (m_pauseReason == DebuggerFrontendDispatcher::Reason::Other) {
switch (m_scriptDebugServer.reasonForPause()) {
case JSC::Debugger::PausedForBreakpoint: {
- JSC::BreakpointID debuggerBreakpointId = m_scriptDebugServer.pausingBreakpointID();
- if (debuggerBreakpointId != m_continueToLocationBreakpointID) {
- m_breakReason = DebuggerFrontendDispatcher::Reason::Breakpoint;
- m_breakData = buildBreakpointPauseReason(debuggerBreakpointId);
- }
+ auto debuggerBreakpointId = m_scriptDebugServer.pausingBreakpointID();
+ if (debuggerBreakpointId != m_continueToLocationBreakpointID)
+ updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason::Breakpoint, buildBreakpointPauseReason(debuggerBreakpointId));
break;
}
case JSC::Debugger::PausedForDebuggerStatement:
- m_breakReason = DebuggerFrontendDispatcher::Reason::DebuggerStatement;
- m_breakData = nullptr;
+ updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason::DebuggerStatement, nullptr);
break;
case JSC::Debugger::PausedForException:
- m_breakReason = DebuggerFrontendDispatcher::Reason::Exception;
- m_breakData = buildExceptionPauseReason(exceptionOrCaughtValue, injectedScript);
+ updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason::Exception, buildExceptionPauseReason(exceptionOrCaughtValue, injectedScript));
break;
+ case JSC::Debugger::PausedAfterBlackboxedScript: {
+ // There should be no break data, as we would've already continued past the breakpoint.
+ ASSERT(!m_pauseData);
+
+ // Don't call `updatePauseReasonAndData` so as to not override `m_preBlackboxPauseData`.
+ if (m_pauseReason != DebuggerFrontendDispatcher::Reason::BlackboxedScript)
+ m_preBlackboxPauseReason = m_pauseReason;
+ m_pauseReason = DebuggerFrontendDispatcher::Reason::BlackboxedScript;
+ break;
+ }
case JSC::Debugger::PausedAtStatement:
case JSC::Debugger::PausedAtExpression:
case JSC::Debugger::PausedBeforeReturn:
@@ -1026,6 +1087,24 @@
}
}
+ if (m_scriptDebugServer.reasonForPause() == JSC::Debugger::PausedAfterBlackboxedScript) {
+ // Ensure that `m_preBlackboxPauseReason` is populated with the most recent data.
+ updatePauseReasonAndData(m_pauseReason, nullptr);
+
+ RefPtr<JSON::Object> data;
+ if (auto debuggerBreakpointId = m_scriptDebugServer.pausingBreakpointID()) {
+ ASSERT(debuggerBreakpointId != m_continueToLocationBreakpointID);
+ data = ""
+ data->setString("originalReason"_s, Protocol::InspectorHelpers::getEnumConstantValue(DebuggerFrontendDispatcher::Reason::Breakpoint));
+ data->setValue("originalData"_s, buildBreakpointPauseReason(debuggerBreakpointId));
+ } else if (m_preBlackboxPauseData) {
+ data = ""
+ data->setString("originalReason"_s, Protocol::InspectorHelpers::getEnumConstantValue(m_preBlackboxPauseReason));
+ data->setValue("originalData"_s, m_preBlackboxPauseData);
+ }
+ updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason::BlackboxedScript, WTFMove(data));
+ }
+
// Set $exception to the exception or caught value.
if (exceptionOrCaughtValue && !injectedScript.hasNoValue()) {
injectedScript.setExceptionValue(exceptionOrCaughtValue);
@@ -1042,7 +1121,7 @@
asyncStackTrace = it->value->buildInspectorObject();
}
- m_frontendDispatcher->paused(currentCallFrames(injectedScript), m_breakReason, m_breakData, asyncStackTrace);
+ m_frontendDispatcher->paused(currentCallFrames(injectedScript), m_pauseReason, m_pauseData, asyncStackTrace);
m_javaScriptPauseScheduled = false;
@@ -1087,7 +1166,7 @@
m_pausedScriptState = nullptr;
m_currentCallStack = { };
m_injectedScriptManager.releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
- clearBreakDetails();
+ clearPauseDetails();
clearExceptionValue();
if (m_conditionToDispatchResumed == ShouldDispatchResumed::WhenContinued)
@@ -1094,10 +1173,10 @@
m_frontendDispatcher->resumed();
}
-void InspectorDebuggerAgent::breakProgram(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<JSON::Object>&& data)
+void InspectorDebuggerAgent::breakProgram(DebuggerFrontendDispatcher::Reason reason, RefPtr<JSON::Object>&& data)
{
- m_breakReason = breakReason;
- m_breakData = WTFMove(data);
+ updatePauseReasonAndData(reason, WTFMove(data));
+
m_scriptDebugServer.breakProgram();
}
@@ -1118,7 +1197,7 @@
JSC::JSLockHolder holder(m_scriptDebugServer.vm());
m_scriptDebugServer.clearBreakpointActions();
m_scriptDebugServer.clearBreakpoints();
- m_scriptDebugServer.clearBlacklist();
+ m_scriptDebugServer.clearBlackbox();
}
m_pausedScriptState = nullptr;
@@ -1127,7 +1206,7 @@
m_breakpointIdentifierToDebugServerBreakpointIDs.clear();
m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.clear();
m_continueToLocationBreakpointID = JSC::noBreakpointID;
- clearBreakDetails();
+ clearPauseDetails();
m_javaScriptPauseScheduled = false;
m_hasExceptionValue = false;
@@ -1158,10 +1237,9 @@
return true;
}
-void InspectorDebuggerAgent::clearBreakDetails()
+void InspectorDebuggerAgent::clearPauseDetails()
{
- m_breakReason = DebuggerFrontendDispatcher::Reason::Other;
- m_breakData = nullptr;
+ updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason::Other, nullptr);
}
void InspectorDebuggerAgent::clearExceptionValue()
Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h (249449 => 249450)
--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h 2019-09-04 02:26:37 UTC (rev 249450)
@@ -85,6 +85,7 @@
void setPauseOnMicrotasks(ErrorString&, bool enabled) final;
void setPauseForInternalScripts(ErrorString&, bool shouldPause) final;
void evaluateOnCallFrame(ErrorString&, const String& callFrameId, const String& _expression_, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, const bool* saveResult, const bool* emulateUserGesture, RefPtr<Protocol::Runtime::RemoteObject>& result, Optional<bool>& wasThrown, Optional<int>& savedResultIndex) override;
+ void setShouldBlackboxURL(ErrorString&, const String& url, bool shouldBlackbox) final;
// ScriptDebugListener
void didParseSource(JSC::SourceID, const Script&) final;
@@ -115,11 +116,11 @@
void willDispatchAsyncCall(AsyncCallType, int callbackId);
void didDispatchAsyncCall();
- void schedulePauseOnNextStatement(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<JSON::Object>&& data);
+ void schedulePauseOnNextStatement(DebuggerFrontendDispatcher::Reason, RefPtr<JSON::Object>&& data);
void cancelPauseOnNextStatement();
bool pauseOnNextStatementEnabled() const { return m_javaScriptPauseScheduled; }
- void breakProgram(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<JSON::Object>&& data);
+ void breakProgram(DebuggerFrontendDispatcher::Reason, RefPtr<JSON::Object>&& data);
void scriptExecutionBlockedByCSP(const String& directiveText);
class Listener {
@@ -159,7 +160,7 @@
bool assertPaused(ErrorString&);
void clearDebuggerBreakpointState();
void clearInspectorBreakpointState();
- void clearBreakDetails();
+ void clearPauseDetails();
void clearExceptionValue();
void clearAsyncStackTraceData();
@@ -168,6 +169,8 @@
void willStepAndMayBecomeIdle();
void didBecomeIdle();
+ void updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason, RefPtr<JSON::Object>&& data);
+
RefPtr<JSON::Object> buildBreakpointPauseReason(JSC::BreakpointID);
RefPtr<JSON::Object> buildExceptionPauseReason(JSC::JSValue exception, const InjectedScript&);
@@ -182,6 +185,7 @@
ScriptDebugServer& m_scriptDebugServer;
InjectedScriptManager& m_injectedScriptManager;
HashMap<JSC::SourceID, Script> m_scripts;
+ HashSet<String> m_blackboxedURLs;
HashSet<Listener*> m_listeners;
@@ -192,10 +196,14 @@
HashMap<String, RefPtr<JSON::Object>> m_javaScriptBreakpoints;
HashMap<JSC::BreakpointID, String> m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier;
JSC::BreakpointID m_continueToLocationBreakpointID { JSC::noBreakpointID };
- DebuggerFrontendDispatcher::Reason m_breakReason;
- RefPtr<JSON::Object> m_breakData;
ShouldDispatchResumed m_conditionToDispatchResumed { ShouldDispatchResumed::No };
+ DebuggerFrontendDispatcher::Reason m_pauseReason;
+ RefPtr<JSON::Object> m_pauseData;
+
+ DebuggerFrontendDispatcher::Reason m_preBlackboxPauseReason;
+ RefPtr<JSON::Object> m_preBlackboxPauseData;
+
HashMap<AsyncCallIdentifier, RefPtr<AsyncStackTrace>> m_pendingAsyncCalls;
Optional<AsyncCallIdentifier> m_currentAsyncCallIdentifier;
int m_asyncStackTraceDepth { 0 };
Modified: trunk/Source/_javascript_Core/inspector/protocol/Debugger.json (249449 => 249450)
--- trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2019-09-04 02:26:37 UTC (rev 249450)
@@ -294,6 +294,14 @@
{ "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." },
{ "name": "savedResultIndex", "type": "integer", "optional": true, "description": "If the result was saved, this is the $n index that can be used to access the value." }
]
+ },
+ {
+ "name": "setShouldBlackboxURL",
+ "description": "Sets whether the given URL should be in the list of blackboxed scripts, which are ignored when pausing/stepping/debugging.",
+ "parameters": [
+ { "name": "url", "type": "string" },
+ { "name": "shouldBlackbox", "type": "boolean" }
+ ]
}
],
"events": [
@@ -341,7 +349,7 @@
"description": "Fired when the virtual machine stopped on breakpoint or exception or any other stop criteria.",
"parameters": [
{ "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." },
- { "name": "reason", "type": "string", "enum": ["XHR", "Fetch", "DOM", "AnimationFrame", "Interval", "Listener", "Timeout", "exception", "assert", "CSPViolation", "DebuggerStatement", "Breakpoint", "PauseOnNextStatement", "Microtask", "other"], "description": "Pause reason." },
+ { "name": "reason", "type": "string", "enum": ["XHR", "Fetch", "DOM", "AnimationFrame", "Interval", "Listener", "Timeout", "exception", "assert", "CSPViolation", "DebuggerStatement", "Breakpoint", "PauseOnNextStatement", "Microtask", "BlackboxedScript", "other"], "description": "Pause reason." },
{ "name": "data", "type": "object", "optional": true, "description": "Object containing break-specific auxiliary properties." },
{ "name": "asyncStackTrace", "$ref": "Console.StackTrace", "optional": true, "description": "Linked list of asynchronous StackTraces." }
]
Modified: trunk/Source/WebInspectorUI/ChangeLog (249449 => 249450)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-09-04 02:26:37 UTC (rev 249450)
@@ -1,3 +1,80 @@
+2019-09-03 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: implement blackboxing of script resources
+ https://bugs.webkit.org/show_bug.cgi?id=17240
+ <rdar://problem/5732847>
+
+ Reviewed by Joseph Pecoraro.
+
+ When a script is blackboxed and the debugger attempts to pause in that script, the pause
+ reason/data will be saved and execution will continue until it has left the blackboxed
+ script. Once outside, execution is paused with the saved reason/data.
+
+ This is especially useful when debugging issues using libraries/frameworks, as it allows the
+ developer to "skip" the internal logic of the library/framework and instead focus only on
+ how they're using it.
+
+ * UserInterface/Controllers/DebuggerManager.js:
+ (WI.DebuggerManager):
+ (WI.DebuggerManager.prototype.initializeTarget):
+ (WI.DebuggerManager.supportsBlackboxingScripts): Added.
+ (WI.DebuggerManager.pauseReasonFromPayload): Added.
+ (WI.DebuggerManager.prototype.isScriptBlackboxed): Added.
+ (WI.DebuggerManager.prototype.setShouldBlackboxScript): Added.
+ (WI.DebuggerManager.prototype._pauseReasonFromPayload):
+ (WI.DebuggerManager.prototype._pauseReasonFromPayload): Deleted.
+
+ * UserInterface/Models/SourceCode.js:
+ (WI.SourceCode.prototype.get isScript): Added.
+ (WI.SourceCode.prototype.get supportsScriptBlackboxing): Added.
+ * UserInterface/Models/Script.js:
+ (WI.Script.prototype.get isScript): Added.
+ * UserInterface/Models/Resource.js:
+ (WI.Resource.prototype.get isScript): Added.
+ Provide a more straightforward way of determining if a `WI.SourceCode` is a script.
+
+ * UserInterface/Views/DebuggerSidebarPanel.js:
+ (WI.DebuggerSidebarPanel.prototype._updatePauseReason):
+ (WI.DebuggerSidebarPanel.prototype._updatePauseReasonSection):
+ * UserInterface/Views/SourcesNavigationSidebarPanel.js:
+ (WI.SourcesNavigationSidebarPanel.prototype._updatePauseReason):
+ (WI.SourcesNavigationSidebarPanel.prototype._updatePauseReasonSection):
+ Display the original pause reason and breakpoint (if applicable) when pausing after leaving
+ a blackboxed script.
+
+ * UserInterface/Views/SourceCodeTreeElement.js:
+ (WI.SourceCodeTreeElement.prototype.canSelectOnMouseDown): Added.
+ (WI.SourceCodeTreeElement.prototype.updateStatus): Added.
+ (WI.SourceCodeTreeElement.prototype._updateSourceCode):
+ (WI.SourceCodeTreeElement.prototype._updateToggleBlackboxImageElementState): Added.
+ (WI.SourceCodeTreeElement.prototype._handleToggleBlackboxedImageElementClick): Added.
+ * UserInterface/Views/SourceCodeTreeElement.css: Added.
+ (.tree-outline .item .status > .toggle-script-blackboxed):
+ (.tree-outline:not(.navigation-sidebar-panel-content-tree-outline) .item .status > .toggle-script-blackboxed,):
+ (.tree-outline:focus .item.selected .status > .toggle-script-blackboxed):
+ (.tree-outline .item .status > .toggle-script-blackboxed.blackboxed):
+ (@media (prefers-color-scheme: dark) .tree-outline .item .status > .toggle-script-blackboxed):
+
+ * UserInterface/Views/ResourceTreeElement.js:
+ (WI.ResourceTreeElement.prototype._updateResource):
+ (WI.ResourceTreeElement.prototype.updateStatus): Added.
+ (WI.ResourceTreeElement.prototype._updateStatus): Deleted.
+ Make sure that the loading indicator doesn't override the blackbox toggle.
+
+ * UserInterface/Base/Setting.js:
+ (WI.Setting.prototype.set value):
+ (WI.Setting.prototype.save): Added.
+ When modifying an array value, that doesn't go through `WI.Setting.prototype.set value`, so
+ we need a more "manual" way of saving the new value.
+
+ * UserInterface/Main.html:
+ * Localizations/en.lproj/localizedStrings.js:
+
+ * UserInterface/Test/TestHarness.js:
+ (TestHarness.prototype.newline): Added.
+ (TestHarness.prototype.expectException):
+ Add a special case for logging error message objects when running protocol tests.
+
2019-08-29 Keith Rollin <krol...@apple.com>
Update .xcconfig symbols to reflect the current set of past and future product versions.
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -335,6 +335,7 @@
localizedStrings["Debugs"] = "Debugs";
localizedStrings["Decoded"] = "Decoded";
localizedStrings["Default"] = "Default";
+localizedStrings["Deferred pause from blackboxed script"] = "Deferred pause from blackboxed script";
localizedStrings["Delete"] = "Delete";
localizedStrings["Delete Breakpoint"] = "Delete Breakpoint";
localizedStrings["Delete Breakpoints"] = "Delete Breakpoints";
@@ -587,6 +588,7 @@
localizedStrings["Identity"] = "Identity";
localizedStrings["Idle"] = "Idle";
localizedStrings["Ignore"] = "Ignore";
+localizedStrings["Ignore script when debugging"] = "Ignore script when debugging";
localizedStrings["Ignore the resource cache when loading resources"] = "Ignore the resource cache when loading resources";
localizedStrings["Ignored"] = "Ignored";
localizedStrings["Image"] = "Image";
@@ -597,6 +599,7 @@
localizedStrings["Imported"] = "Imported";
localizedStrings["Imported - %s"] = "Imported - %s";
localizedStrings["Imported \u2014 %s"] = "Imported \u2014 %s";
+localizedStrings["Include script when debugging"] = "Include script when debugging";
localizedStrings["Incomplete"] = "Incomplete";
localizedStrings["Indent width:"] = "Indent width:";
localizedStrings["Index"] = "Index";
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -113,9 +113,13 @@
this._value = value;
+ this.save();
+ }
+
+ save()
+ {
if (!window.InspectorTest && window.localStorage) {
try {
- // Use Object.shallowEqual to properly compare objects.
if (Object.shallowEqual(this._value, this._defaultValue))
delete window.localStorage[this._localStorageKey];
else
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -89,6 +89,8 @@
this._nextBreakpointActionIdentifier = 1;
+ this._blackboxURLsSetting = new WI.Setting("debugger-blackbox-urls", []);
+
this._activeCallFrame = null;
this._internalWebKitScripts = [];
@@ -157,6 +159,12 @@
if (target.DebuggerAgent.setAsyncStackTraceDepth)
target.DebuggerAgent.setAsyncStackTraceDepth(this._asyncStackTraceDepthSetting.value);
+ // COMPATIBILITY (iOS 13): Debugger.setShouldBlackboxURL did not exist yet.
+ if (target.DebuggerAgent.setShouldBlackboxURL) {
+ for (let url of this._blackboxURLsSetting.value)
+ target.DebuggerAgent.setShouldBlackboxURL(url, true);
+ }
+
if (WI.isEngineeringBuild) {
// COMPATIBILITY (iOS 12): DebuggerAgent.setPauseForInternalScripts did not exist yet.
if (target.DebuggerAgent.setPauseForInternalScripts)
@@ -178,6 +186,55 @@
this._restoringBreakpoints = false;
}
+ // Static
+
+ static supportsBlackboxingScripts()
+ {
+ return !!InspectorBackend.domains.Debugger.setShouldBlackboxURL;
+ }
+
+ static pauseReasonFromPayload(payload)
+ {
+ switch (payload) {
+ case InspectorBackend.domains.Debugger.PausedReason.AnimationFrame:
+ return WI.DebuggerManager.PauseReason.AnimationFrame;
+ case InspectorBackend.domains.Debugger.PausedReason.Assert:
+ return WI.DebuggerManager.PauseReason.Assertion;
+ case InspectorBackend.domains.Debugger.PausedReason.BlackboxedScript:
+ return WI.DebuggerManager.PauseReason.BlackboxedScript;
+ case InspectorBackend.domains.Debugger.PausedReason.Breakpoint:
+ return WI.DebuggerManager.PauseReason.Breakpoint;
+ case InspectorBackend.domains.Debugger.PausedReason.CSPViolation:
+ return WI.DebuggerManager.PauseReason.CSPViolation;
+ case InspectorBackend.domains.Debugger.PausedReason.DOM:
+ return WI.DebuggerManager.PauseReason.DOM;
+ case InspectorBackend.domains.Debugger.PausedReason.DebuggerStatement:
+ return WI.DebuggerManager.PauseReason.DebuggerStatement;
+ case InspectorBackend.domains.Debugger.PausedReason.EventListener:
+ return WI.DebuggerManager.PauseReason.EventListener;
+ case InspectorBackend.domains.Debugger.PausedReason.Exception:
+ return WI.DebuggerManager.PauseReason.Exception;
+ case InspectorBackend.domains.Debugger.PausedReason.Fetch:
+ return WI.DebuggerManager.PauseReason.Fetch;
+ case InspectorBackend.domains.Debugger.PausedReason.Interval:
+ return WI.DebuggerManager.PauseReason.Interval;
+ case InspectorBackend.domains.Debugger.PausedReason.Listener:
+ return WI.DebuggerManager.PauseReason.Listener;
+ case InspectorBackend.domains.Debugger.PausedReason.Microtask:
+ return WI.DebuggerManager.PauseReason.Microtask;
+ case InspectorBackend.domains.Debugger.PausedReason.PauseOnNextStatement:
+ return WI.DebuggerManager.PauseReason.PauseOnNextStatement;
+ case InspectorBackend.domains.Debugger.PausedReason.Timeout:
+ return WI.DebuggerManager.PauseReason.Timeout;
+ case InspectorBackend.domains.Debugger.PausedReason.Timer:
+ return WI.DebuggerManager.PauseReason.Timer;
+ case InspectorBackend.domains.Debugger.PausedReason.XHR:
+ return WI.DebuggerManager.PauseReason.XHR;
+ default:
+ return WI.DebuggerManager.PauseReason.Other;
+ }
+ }
+
// Public
get paused()
@@ -349,6 +406,30 @@
return knownScripts;
}
+ isScriptBlackboxed(sourceCode)
+ {
+ return this._blackboxURLsSetting.value.includes(sourceCode.contentIdentifier);
+ }
+
+ setShouldBlackboxScript(sourceCode, shouldBlackbox)
+ {
+ console.assert(DebuggerManager.supportsBlackboxingScripts());
+ console.assert(sourceCode instanceof WI.SourceCode);
+ console.assert(sourceCode.contentIdentifier);
+ console.assert(!isWebKitInjectedScript(sourceCode.contentIdentifier));
+
+ this._blackboxURLsSetting.value.toggleIncludes(sourceCode.contentIdentifier, shouldBlackbox);
+ this._blackboxURLsSetting.save();
+
+ for (let target of WI.targets) {
+ // COMPATIBILITY (iOS 13): Debugger.setShouldBlackboxURL did not exist yet.
+ if (target.DebuggerAgent.setShouldBlackboxURL)
+ target.DebuggerAgent.setShouldBlackboxURL(sourceCode.contentIdentifier, !!shouldBlackbox);
+ }
+
+ this.dispatchEventToListeners(DebuggerManager.Event.BlackboxedURLsChanged);
+ }
+
get asyncStackTraceDepth()
{
return this._asyncStackTraceDepthSetting.value;
@@ -617,7 +698,7 @@
let targetData = this._targetDebuggerDataMap.get(target);
let callFrames = [];
- let pauseReason = this._pauseReasonFromPayload(reason);
+ let pauseReason = DebuggerManager.pauseReasonFromPayload(reason);
let pauseData = data || null;
for (var i = 0; i < callFramesPayload.length; ++i) {
@@ -843,47 +924,6 @@
return new WI.ScopeChainNode(type, [object], payload.name, payload.location, payload.empty);
}
- _pauseReasonFromPayload(payload)
- {
- // FIXME: Handle other backend pause reasons.
- switch (payload) {
- case DebuggerAgent.PausedReason.AnimationFrame:
- return WI.DebuggerManager.PauseReason.AnimationFrame;
- case DebuggerAgent.PausedReason.Assert:
- return WI.DebuggerManager.PauseReason.Assertion;
- case DebuggerAgent.PausedReason.Breakpoint:
- return WI.DebuggerManager.PauseReason.Breakpoint;
- case DebuggerAgent.PausedReason.CSPViolation:
- return WI.DebuggerManager.PauseReason.CSPViolation;
- case DebuggerAgent.PausedReason.DOM:
- return WI.DebuggerManager.PauseReason.DOM;
- case DebuggerAgent.PausedReason.DebuggerStatement:
- return WI.DebuggerManager.PauseReason.DebuggerStatement;
- case DebuggerAgent.PausedReason.EventListener:
- return WI.DebuggerManager.PauseReason.EventListener;
- case DebuggerAgent.PausedReason.Exception:
- return WI.DebuggerManager.PauseReason.Exception;
- case DebuggerAgent.PausedReason.Fetch:
- return WI.DebuggerManager.PauseReason.Fetch;
- case DebuggerAgent.PausedReason.Interval:
- return WI.DebuggerManager.PauseReason.Interval;
- case DebuggerAgent.PausedReason.Listener:
- return WI.DebuggerManager.PauseReason.Listener;
- case DebuggerAgent.PausedReason.Microtask:
- return WI.DebuggerManager.PauseReason.Microtask;
- case DebuggerAgent.PausedReason.PauseOnNextStatement:
- return WI.DebuggerManager.PauseReason.PauseOnNextStatement;
- case DebuggerAgent.PausedReason.Timeout:
- return WI.DebuggerManager.PauseReason.Timeout;
- case DebuggerAgent.PausedReason.Timer:
- return WI.DebuggerManager.PauseReason.Timer;
- case DebuggerAgent.PausedReason.XHR:
- return WI.DebuggerManager.PauseReason.XHR;
- default:
- return WI.DebuggerManager.PauseReason.Other;
- }
- }
-
_debuggerBreakpointActionType(type)
{
switch (type) {
@@ -1390,11 +1430,13 @@
BreakpointsEnabledDidChange: "debugger-manager-breakpoints-enabled-did-change",
ProbeSetAdded: "debugger-manager-probe-set-added",
ProbeSetRemoved: "debugger-manager-probe-set-removed",
+ BlackboxedURLsChanged: "blackboxed-urls-changed",
};
WI.DebuggerManager.PauseReason = {
AnimationFrame: "animation-frame",
Assertion: "assertion",
+ BlackboxedScript: "blackboxed-script",
Breakpoint: "breakpoint",
CSPViolation: "CSP-violation",
DebuggerStatement: "debugger-statement",
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2019-09-04 02:26:37 UTC (rev 249450)
@@ -197,6 +197,7 @@
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
+ <link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -352,6 +352,11 @@
return true;
}
+ get isScript()
+ {
+ return this._type === Resource.Type.Script;
+ }
+
get displayName()
{
return WI.displayNameForURL(this._url, this.urlComponents);
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Script.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Script.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Script.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -120,6 +120,11 @@
return this._resource.mimeType;
}
+ get isScript()
+ {
+ return true;
+ }
+
get displayName()
{
if (this._url && !this._dynamicallyAddedScriptElement)
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/SourceCode.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Models/SourceCode.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/SourceCode.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -103,6 +103,22 @@
return this.url;
}
+ get isScript()
+ {
+ // Implemented by subclasses if needed.
+ return false;
+ }
+
+ get supportsScriptBlackboxing()
+ {
+ if (!this.isScript)
+ return false;
+ if (!WI.DebuggerManager.supportsBlackboxingScripts())
+ return false;
+ let contentIdentifier = this.contentIdentifier;
+ return contentIdentifier && !isWebKitInjectedScript(contentIdentifier);
+ }
+
get sourceMaps()
{
return this._sourceMaps || [];
Modified: trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -219,8 +219,18 @@
let expectAndDumpError = (e) => {
this.expectNotNull(e, "Should produce an exception.");
- if (e)
+ if (!e)
+ return;
+
+ if (e instanceof Error || !(e instanceof Object))
this.log(e.toString());
+ else {
+ try {
+ this.json(e);
+ } catch {
+ this.log(e.constructor.name);
+ }
+ }
}
let error = null;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -1166,15 +1166,13 @@
this._pauseReasonTreeOutline = null;
this._updatePauseReasonGotoArrow();
- return this._updatePauseReasonSection();
+ let target = WI.debuggerManager.activeCallFrame.target;
+ let targetData = WI.debuggerManager.dataForTarget(target);
+ return this._updatePauseReasonSection(target, targetData.pauseReason, targetData.pauseData);
}
- _updatePauseReasonSection()
+ _updatePauseReasonSection(target, pauseReason, pauseData)
{
- let target = WI.debuggerManager.activeCallFrame.target;
- let targetData = WI.debuggerManager.dataForTarget(target);
- let {pauseReason, pauseData} = targetData;
-
switch (pauseReason) {
case WI.DebuggerManager.PauseReason.AnimationFrame:
this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});
@@ -1203,6 +1201,20 @@
this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
return true;
+ case WI.DebuggerManager.PauseReason.BlackboxedScript: {
+ console.assert(pauseData);
+ if (pauseData)
+ this._updatePauseReasonSection(target, WI.DebuggerManager.pauseReasonFromPayload(pauseData.originalReason), pauseData.originalData);
+
+ // Don't use `_pauseReasonTextRow` as it may have already been set.
+ let blackboxReasonTextRow = new WI.DetailsSectionTextRow(WI.UIString("Deferred pause from blackboxed script"));
+ blackboxReasonTextRow.__blackboxReason = true;
+
+ let existingRows = this._pauseReasonGroup.rows.filter((row) => !row.__blackboxReason);
+ this._pauseReasonGroup.rows = [blackboxReasonTextRow, ...existingRows];
+ return true;
+ }
+
case WI.DebuggerManager.PauseReason.Breakpoint:
console.assert(pauseData, "Expected breakpoint identifier, but found none.");
if (pauseData && pauseData.breakpointId) {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -118,8 +118,8 @@
if (this._resource) {
this._resource.removeEventListener(WI.Resource.Event.URLDidChange, this._urlDidChange, this);
this._resource.removeEventListener(WI.Resource.Event.TypeDidChange, this._typeDidChange, this);
- this._resource.removeEventListener(WI.Resource.Event.LoadingDidFinish, this._updateStatus, this);
- this._resource.removeEventListener(WI.Resource.Event.LoadingDidFail, this._updateStatus, this);
+ this._resource.removeEventListener(WI.Resource.Event.LoadingDidFinish, this.updateStatus, this);
+ this._resource.removeEventListener(WI.Resource.Event.LoadingDidFail, this.updateStatus, this);
}
this._updateSourceCode(resource);
@@ -128,11 +128,11 @@
resource.addEventListener(WI.Resource.Event.URLDidChange, this._urlDidChange, this);
resource.addEventListener(WI.Resource.Event.TypeDidChange, this._typeDidChange, this);
- resource.addEventListener(WI.Resource.Event.LoadingDidFinish, this._updateStatus, this);
- resource.addEventListener(WI.Resource.Event.LoadingDidFail, this._updateStatus, this);
+ resource.addEventListener(WI.Resource.Event.LoadingDidFinish, this.updateStatus, this);
+ resource.addEventListener(WI.Resource.Event.LoadingDidFail, this.updateStatus, this);
this._updateTitles();
- this._updateStatus();
+ this.updateStatus();
this._updateToolTip();
}
@@ -175,17 +175,13 @@
this.callFirstAncestorFunction("descendantResourceTreeElementMainTitleDidChange", [this, oldMainTitle]);
}
- populateContextMenu(contextMenu, event)
+ updateStatus()
{
- WI.appendContextMenuItemsForSourceCode(contextMenu, this._resource);
+ super.updateStatus();
- super.populateContextMenu(contextMenu, event);
- }
+ if (!this._resource)
+ return;
- // Private
-
- _updateStatus()
- {
if (this._resource.hadLoadingError())
this.addClassName(WI.ResourceTreeElement.FailedStyleClassName);
else
@@ -194,15 +190,33 @@
if (this._resource.isLoading()) {
if (!this.status || !this.status[WI.ResourceTreeElement.SpinnerSymbol]) {
let spinner = new WI.IndeterminateProgressSpinner;
- this.status = spinner.element;
- this.status[WI.ResourceTreeElement.SpinnerSymbol] = true;
+ if (this.status)
+ this.statusElement.insertAdjacentElement("afterbegin", spinner.element);
+ else
+ this.status = spinner.element;
+ this.status[WI.ResourceTreeElement.SpinnerSymbol] = spinner.element;
}
} else {
- if (this.status && this.status[WI.ResourceTreeElement.SpinnerSymbol])
- this.status = "";
+ if (this.status && this.status[WI.ResourceTreeElement.SpinnerSymbol]) {
+ if (this.status === this.status[WI.ResourceTreeElement.SpinnerSymbol])
+ this.status = null;
+ else {
+ this.status[WI.ResourceTreeElement.SpinnerSymbol].remove();
+ this.status[WI.ResourceTreeElement.SpinnerSymbol] = null;
+ }
+ }
}
}
+ populateContextMenu(contextMenu, event)
+ {
+ WI.appendContextMenuItemsForSourceCode(contextMenu, this._resource);
+
+ super.populateContextMenu(contextMenu, event);
+ }
+
+ // Private
+
_updateToolTip()
{
this.tooltip = this._resource.displayURL;
Added: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.css (0 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.css 2019-09-04 02:26:37 UTC (rev 249450)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.tree-outline .item .status > .toggle-script-blackboxed {
+ width: 18px;
+ margin-top: 2px;
+ content: url(../Images/Hide.svg);
+}
+
+.tree-outline:not(.navigation-sidebar-panel-content-tree-outline) .item .status > .toggle-script-blackboxed,
+.tree-outline .item:not(:hover, .selected) .status > .toggle-script-blackboxed:not(.blackboxed) {
+ display: none;
+}
+
+.tree-outline:focus .item.selected .status > .toggle-script-blackboxed {
+ filter: invert();
+}
+
+.tree-outline .item .status > .toggle-script-blackboxed.blackboxed {
+ opacity: 0.5;
+}
+
+@media (prefers-color-scheme: dark) {
+ .tree-outline .item .status > .toggle-script-blackboxed {
+ filter: invert();
+ }
+}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -128,6 +128,13 @@
findAndCombineFolderChains(this.children[i], null);
}
+ canSelectOnMouseDown(event)
+ {
+ if (this._toggleBlackboxedImageElement && this._toggleBlackboxedImageElement.contains(event.target))
+ return false;
+ return super.canSelectOnMouseDown(event);
+ }
+
// Protected
descendantResourceTreeElementTypeDidChange(childTreeElement, oldType)
@@ -150,6 +157,20 @@
childTreeElement.revealAndSelect(true, false, true);
}
+ updateStatus()
+ {
+ if (this._sourceCode.supportsScriptBlackboxing) {
+ if (!this._toggleBlackboxedImageElement) {
+ this._toggleBlackboxedImageElement = document.createElement("img");
+ this._toggleBlackboxedImageElement.classList.add("toggle-script-blackboxed");
+ this._toggleBlackboxedImageElement.addEventListener("click", this._handleToggleBlackboxedImageElementClicked.bind(this));
+ }
+
+ this.status = this._toggleBlackboxedImageElement;
+ this._updateToggleBlackboxImageElementState();
+ }
+ }
+
// Protected (ResourceTreeElement calls this when its Resource changes dynamically for Frames)
_updateSourceCode(sourceCode)
@@ -159,12 +180,44 @@
if (this._sourceCode === sourceCode)
return;
- if (this._sourceCode)
+ let oldSupportsScriptBlackboxing = false;
+
+ if (this._sourceCode) {
+ oldSupportsScriptBlackboxing = this._sourceCode.supportsScriptBlackboxing;
+
this._sourceCode.removeEventListener(WI.SourceCode.Event.SourceMapAdded, this.updateSourceMapResources, this);
+ }
this._sourceCode = sourceCode;
this._sourceCode.addEventListener(WI.SourceCode.Event.SourceMapAdded, this.updateSourceMapResources, this);
+ let newSupportsScriptBlackboxing = this._sourceCode.supportsScriptBlackboxing;
+ if (oldSupportsScriptBlackboxing !== newSupportsScriptBlackboxing) {
+ if (newSupportsScriptBlackboxing)
+ WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BlackboxedURLsChanged, this._updateToggleBlackboxImageElementState, this);
+ else
+ WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.BlackboxedURLsChanged, this._updateToggleBlackboxImageElementState, this);
+ }
+
this.updateSourceMapResources();
+
+ this.updateStatus();
}
+
+ // Private
+
+ _updateToggleBlackboxImageElementState()
+ {
+ let isBlackboxed = WI.debuggerManager.isScriptBlackboxed(this._sourceCode);
+ this._toggleBlackboxedImageElement.classList.toggle("blackboxed", isBlackboxed);
+ this._toggleBlackboxedImageElement.title = isBlackboxed ? WI.UIString("Include script when debugging") : WI.UIString("Ignore script when debugging");
+ }
+
+ _handleToggleBlackboxedImageElementClicked(event)
+ {
+ let isBlackboxed = WI.debuggerManager.isScriptBlackboxed(this._sourceCode);
+ WI.debuggerManager.setShouldBlackboxScript(this._sourceCode, !isBlackboxed);
+
+ this._updateToggleBlackboxImageElementState();
+ }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js (249449 => 249450)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js 2019-09-04 01:47:02 UTC (rev 249449)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js 2019-09-04 02:26:37 UTC (rev 249450)
@@ -1172,7 +1172,10 @@
this._pauseReasonTreeOutline = null;
this._updatePauseReasonGotoArrow();
- return this._updatePauseReasonSection();
+
+ let target = WI.debuggerManager.activeCallFrame.target;
+ let targetData = WI.debuggerManager.dataForTarget(target);
+ return this._updatePauseReasonSection(target, targetData.pauseReason, targetData.pauseData);
}
_updatePauseReasonGotoArrow()
@@ -1194,12 +1197,8 @@
this._pauseReasonLinkContainerElement.appendChild(linkElement);
}
- _updatePauseReasonSection()
+ _updatePauseReasonSection(target, pauseReason, pauseData)
{
- let target = WI.debuggerManager.activeCallFrame.target;
- let targetData = WI.debuggerManager.dataForTarget(target);
- let {pauseReason, pauseData} = targetData;
-
switch (pauseReason) {
case WI.DebuggerManager.PauseReason.AnimationFrame: {
this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});
@@ -1227,6 +1226,20 @@
this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
return true;
+ case WI.DebuggerManager.PauseReason.BlackboxedScript: {
+ console.assert(pauseData);
+ if (pauseData)
+ this._updatePauseReasonSection(target, WI.DebuggerManager.pauseReasonFromPayload(pauseData.originalReason), pauseData.originalData);
+
+ // Don't use `_pauseReasonTextRow` as it may have already been set.
+ let blackboxReasonTextRow = new WI.DetailsSectionTextRow(WI.UIString("Deferred pause from blackboxed script"));
+ blackboxReasonTextRow.__blackboxReason = true;
+
+ let existingRows = this._pauseReasonGroup.rows.filter((row) => !row.__blackboxReason);
+ this._pauseReasonGroup.rows = [blackboxReasonTextRow, ...existingRows];
+ return true;
+ }
+
case WI.DebuggerManager.PauseReason.Breakpoint: {
console.assert(pauseData, "Expected breakpoint identifier, but found none.");
if (!pauseData || !pauseData.breakpointId)