Diff
Modified: trunk/LayoutTests/ChangeLog (290719 => 290720)
--- trunk/LayoutTests/ChangeLog 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/LayoutTests/ChangeLog 2022-03-02 06:42:27 UTC (rev 290720)
@@ -1,3 +1,13 @@
+2022-03-01 Devin Rousso <[email protected]>
+
+ Web Inspector: add a switch to control whether breakpoint evaluations (condition, ignore count, actions) are also affected by script blackboxing
+ https://bugs.webkit.org/show_bug.cgi?id=235274
+
+ Reviewed by Patrick Angle.
+
+ * inspector/debugger/setBlackboxBreakpointEvaluations.html: Added.
+ * inspector/debugger/setBlackboxBreakpointEvaluations-expected.txt: Added.
+
2022-03-01 Matteo Flores <[email protected]>
[ iOS ] pointerevents/mouse/* 10 pointer event tests are constant timeouts or failures on iOS.
Added: trunk/LayoutTests/inspector/debugger/setBlackboxBreakpointEvaluations-expected.txt (0 => 290720)
--- trunk/LayoutTests/inspector/debugger/setBlackboxBreakpointEvaluations-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/debugger/setBlackboxBreakpointEvaluations-expected.txt 2022-03-02 06:42:27 UTC (rev 290720)
@@ -0,0 +1,124 @@
+Tests Debugger.setBlackboxBreakpointEvaluations.
+
+
+== Running test suite: Debugger.setBlackboxBreakpointEvaluations
+-- Running test case: Debugger.setBlackboxBreakpointEvaluations.UnblackboxBreakpointEvaluations.BreakpointCondition.False
+Evaluating 'createScripts("UnblackboxBreakpointEvaluations_BreakpointCondition_False")'...
+Blackboxing 'unblackboxbreakpointevaluations_breakpointcondition_false_inner.js'...
+Setting breakpoint in 'UnblackboxBreakpointEvaluations_BreakpointCondition_False_Inner.js'...
+Unblackboxing preakpoing evaluations...
+Evaluating 'UnblackboxBreakpointEvaluations_BreakpointCondition_False_Outer(2)'...
+PASS: Should change value of 'x' inside 'UnblackboxBreakpointEvaluations_BreakpointCondition_False_Inner.js'
+PASS: Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointCondition_False_Inner'.
+PASS: Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointCondition_False_Outer'.
+
+-- Running test case: Debugger.setBlackboxBreakpointEvaluations.UnblackboxBreakpointEvaluations.BreakpointCondition.True
+Evaluating 'createScripts("UnblackboxBreakpointEvaluations_BreakpointCondition_True")'...
+Blackboxing 'unblackboxbreakpointevaluations_breakpointcondition_true_inner.js'...
+Setting breakpoint in 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Inner.js'...
+Unblackboxing preakpoing evaluations...
+Evaluating 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Outer(2)'...
+
+PAUSED: 'BlackboxedScript' at 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Outer:3:4'.
+{
+ "originalReason": "Breakpoint",
+ "originalData": {
+ "breakpointId": "UnblackboxBreakpointEvaluations_BreakpointCondition_True_Inner.js:2:0"
+ }
+}
+Resuming...
+PASS: Resumed.
+PASS: Should change value of 'x' inside 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Inner.js'
+PASS: Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Inner'.
+PASS: Should pause in 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Outer'.
+
+-- Running test case: Debugger.setBlackboxBreakpointEvaluations.UnblackboxBreakpointEvaluations.BreakpointAction.Pause
+Evaluating 'createScripts("UnblackboxBreakpointEvaluations_BreakpointAction_Pause")'...
+Blackboxing 'unblackboxbreakpointevaluations_breakpointaction_pause_inner.js'...
+Setting breakpoint in 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Inner.js'...
+Unblackboxing preakpoing evaluations...
+Evaluating 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Outer(2)'...
+
+PAUSED: 'BlackboxedScript' at 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Outer:3:4'.
+{
+ "originalReason": "Breakpoint",
+ "originalData": {
+ "breakpointId": "UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Inner.js:2:0"
+ }
+}
+Resuming...
+PASS: Resumed.
+PASS: Should change value of 'x' inside 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Inner.js'
+PASS: Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Inner'.
+PASS: Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Outer'.
+
+-- Running test case: Debugger.setBlackboxBreakpointEvaluations.UnblackboxBreakpointEvaluations.BreakpointAction.AutoContinue
+Evaluating 'createScripts("UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue")'...
+Blackboxing 'unblackboxbreakpointevaluations_breakpointaction_autocontinue_inner.js'...
+Setting breakpoint in 'UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner.js'...
+Unblackboxing preakpoing evaluations...
+Evaluating 'UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer(2)'...
+PASS: Should change value of 'x' inside 'UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner.js'
+PASS: Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner'.
+PASS: Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer'.
+
+-- Running test case: Debugger.setBlackboxBreakpointEvaluations.BlackboxBreakpointEvaluations.BreakpointCondition.False
+Evaluating 'createScripts("BlackboxBreakpointEvaluations_BreakpointCondition_False")'...
+Blackboxing 'blackboxbreakpointevaluations_breakpointcondition_false_inner.js'...
+Setting breakpoint in 'BlackboxBreakpointEvaluations_BreakpointCondition_False_Inner.js'...
+Blackboxing preakpoing evaluations...
+Evaluating 'BlackboxBreakpointEvaluations_BreakpointCondition_False_Outer(2)'...
+PASS: Should change value of 'x' inside 'BlackboxBreakpointEvaluations_BreakpointCondition_False_Outer.js'
+PASS: Should not pause in 'BlackboxBreakpointEvaluations_BreakpointCondition_False_Inner'.
+PASS: Should not pause in 'BlackboxBreakpointEvaluations_BreakpointCondition_False_Outer'.
+
+-- Running test case: Debugger.setBlackboxBreakpointEvaluations.BlackboxBreakpointEvaluations.BreakpointCondition.True
+Evaluating 'createScripts("BlackboxBreakpointEvaluations_BreakpointCondition_True")'...
+Blackboxing 'blackboxbreakpointevaluations_breakpointcondition_true_inner.js'...
+Setting breakpoint in 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Inner.js'...
+Blackboxing preakpoing evaluations...
+Evaluating 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer(2)'...
+
+PAUSED: 'BlackboxedScript' at 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer:3:4'.
+{
+ "originalReason": "Breakpoint",
+ "originalData": {
+ "breakpointId": "BlackboxBreakpointEvaluations_BreakpointCondition_True_Inner.js:2:0"
+ }
+}
+Resuming...
+PASS: Resumed.
+PASS: Should change value of 'x' inside 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer.js'
+PASS: Should not pause in 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Inner'.
+PASS: Should pause in 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer'.
+
+-- Running test case: Debugger.setBlackboxBreakpointEvaluations.BlackboxBreakpointEvaluations.BreakpointAction.Pause
+Evaluating 'createScripts("BlackboxBreakpointEvaluations_BreakpointAction_Pause")'...
+Blackboxing 'blackboxbreakpointevaluations_breakpointaction_pause_inner.js'...
+Setting breakpoint in 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Inner.js'...
+Blackboxing preakpoing evaluations...
+Evaluating 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer(2)'...
+
+PAUSED: 'BlackboxedScript' at 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer:3:4'.
+{
+ "originalReason": "Breakpoint",
+ "originalData": {
+ "breakpointId": "BlackboxBreakpointEvaluations_BreakpointAction_Pause_Inner.js:2:0"
+ }
+}
+Resuming...
+PASS: Resumed.
+PASS: Should change value of 'x' inside 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer.js'
+PASS: Should not pause in 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Inner'.
+PASS: Should not pause in 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer'.
+
+-- Running test case: Debugger.setBlackboxBreakpointEvaluations.BlackboxBreakpointEvaluations.BreakpointAction.AutoContinue
+Evaluating 'createScripts("BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue")'...
+Blackboxing 'blackboxbreakpointevaluations_breakpointaction_autocontinue_inner.js'...
+Setting breakpoint in 'BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner.js'...
+Blackboxing preakpoing evaluations...
+Evaluating 'BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer(2)'...
+PASS: Should change value of 'x' inside 'BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer.js'
+PASS: Should not pause in 'BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner'.
+PASS: Should not pause in 'BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer'.
+
Added: trunk/LayoutTests/inspector/debugger/setBlackboxBreakpointEvaluations.html (0 => 290720)
--- trunk/LayoutTests/inspector/debugger/setBlackboxBreakpointEvaluations.html (rev 0)
+++ trunk/LayoutTests/inspector/debugger/setBlackboxBreakpointEvaluations.html 2022-03-02 06:42:27 UTC (rev 290720)
@@ -0,0 +1,319 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function createScripts(id) {
+ eval(
+`
+window.${id}_Inner = function ${id}_Inner(x) {
+ return x * x;
+};
+//# sourceURL=${id}_Inner.js
+`
+ );
+
+ eval(
+`
+window.${id}_Outer = function ${id}_Outer(x) {
+ let innerResult = ${id}_Inner(x);
+ return innerResult * x;
+};
+//# sourceURL=${id}_Outer.js
+`
+ );
+}
+
+function test()
+{
+ ProtocolTest.debug();
+ let suite = ProtocolTest.createAsyncSuite("Debugger.setBlackboxBreakpointEvaluations");
+
+ let sourceURLRegExpQueries = new Map;
+ let pausedFunctionNames = [];
+
+ 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) {
+ ProtocolTest.newline();
+
+ let topCallFrame = message.params.callFrames[0];
+ let functionName = topCallFrame.functionName;
+ if (functionName !== "global code") {
+ ProtocolTest.log(`PAUSED: '${message.params.reason}' at '${functionName}:${topCallFrame.location.lineNumber}:${topCallFrame.location.columnNumber}'.`);
+ if (message.params.data)
+ ProtocolTest.json(message.params.data);
+ pausedFunctionNames.push(functionName);
+ }
+
+ ProtocolTest.log("Resuming...");
+ InspectorProtocol.sendCommand(`Debugger.resume`, {}, InspectorProtocol.checkForError);
+ };
+
+ InspectorProtocol.eventHandler["Debugger.resumed"] = function(message) {
+ ProtocolTest.pass("Resumed.");
+ };
+
+ async function setBlackbox(url, options = {}) {
+ if (!options.caseSensitive)
+ url = ""
+
+ ProtocolTest.log(`Blackboxing ${options.caseSensitive ? "(case sensitive) " : ""}${options.isRegex ? "(regex) " : ""}'${url}'...`);
+ await InspectorProtocol.awaitCommand({
+ method: "Debugger.setShouldBlackboxURL",
+ params: {url, shouldBlackbox: true, ...options},
+ });
+ }
+
+ async function setBreakpoint(url, lineNumber, options) {
+ ProtocolTest.log(`Setting breakpoint in '${url}'...`);
+ await InspectorProtocol.awaitCommand({
+ method: "Debugger.setBreakpointByUrl",
+ params: {url, lineNumber, options},
+ });
+ }
+
+ async function setBlackboxBreakpointEvaluations(blackboxBreakpointEvaluations) {
+ ProtocolTest.log(`${blackboxBreakpointEvaluations ? "Blackboxing" : "Unblackboxing"} preakpoing evaluations...`);
+ return InspectorProtocol.awaitCommand({
+ method: "Debugger.setBlackboxBreakpointEvaluations",
+ params: {blackboxBreakpointEvaluations},
+ });
+ }
+
+ 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.setBlackboxBreakpointEvaluations.UnblackboxBreakpointEvaluations.BreakpointCondition.False",
+ async test() {
+ let [innerSourceURL, outerSourceURL] = await Promise.all([
+ listenForSourceParsed(/UnblackboxBreakpointEvaluations_BreakpointCondition_False_Inner\.js$/),
+ listenForSourceParsed(/UnblackboxBreakpointEvaluations_BreakpointCondition_False_Outer\.js$/),
+ evaluate(`createScripts("UnblackboxBreakpointEvaluations_BreakpointCondition_False")`),
+ ]);
+
+ await setBlackbox(innerSourceURL);
+ await setBreakpoint(innerSourceURL, 2, {
+ condition: "!(x = 3)",
+ });
+ await setBlackboxBreakpointEvaluations(false);
+
+ let result = await evaluate(`UnblackboxBreakpointEvaluations_BreakpointCondition_False_Outer(2)`);
+ InspectorProtocol.checkForError(result);
+ ProtocolTest.expectEqual(result.result.value, (3 * 3) * 2, "Should change value of 'x' inside 'UnblackboxBreakpointEvaluations_BreakpointCondition_False_Inner.js'");
+
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("UnblackboxBreakpointEvaluations_BreakpointCondition_False_Inner"), "Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointCondition_False_Inner'.");
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("UnblackboxBreakpointEvaluations_BreakpointCondition_False_Outer"), "Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointCondition_False_Outer'.");
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setBlackboxBreakpointEvaluations.UnblackboxBreakpointEvaluations.BreakpointCondition.True",
+ async test() {
+ let [innerSourceURL, outerSourceURL] = await Promise.all([
+ listenForSourceParsed(/UnblackboxBreakpointEvaluations_BreakpointCondition_True_Inner\.js$/),
+ listenForSourceParsed(/UnblackboxBreakpointEvaluations_BreakpointCondition_True_Outer\.js$/),
+ evaluate(`createScripts("UnblackboxBreakpointEvaluations_BreakpointCondition_True")`),
+ ]);
+
+ await setBlackbox(innerSourceURL);
+ await setBreakpoint(innerSourceURL, 2, {
+ condition: "(x = 3)",
+ });
+ await setBlackboxBreakpointEvaluations(false);
+
+ let result = await evaluate(`UnblackboxBreakpointEvaluations_BreakpointCondition_True_Outer(2)`);
+ InspectorProtocol.checkForError(result);
+ ProtocolTest.expectEqual(result.result.value, (3 * 3) * 2, "Should change value of 'x' inside 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Inner.js'");
+
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("UnblackboxBreakpointEvaluations_BreakpointCondition_True_Inner"), "Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Inner'.");
+ ProtocolTest.expectTrue(pausedFunctionNames.includes("UnblackboxBreakpointEvaluations_BreakpointCondition_True_Outer"), "Should pause in 'UnblackboxBreakpointEvaluations_BreakpointCondition_True_Outer'.");
+
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setBlackboxBreakpointEvaluations.UnblackboxBreakpointEvaluations.BreakpointAction.Pause",
+ async test() {
+ let [innerSourceURL, outerSourceURL] = await Promise.all([
+ listenForSourceParsed(/UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Inner\.js$/),
+ listenForSourceParsed(/UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Outer\.js$/),
+ evaluate(`createScripts("UnblackboxBreakpointEvaluations_BreakpointAction_Pause")`),
+ ]);
+
+ await setBlackbox(innerSourceURL);
+ await setBreakpoint(innerSourceURL, 2, {
+ actions: [
+ {type: "evaluate", data: "x = 3"},
+ ],
+ });
+ await setBlackboxBreakpointEvaluations(false);
+
+ let result = await evaluate(`UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Outer(2)`);
+ InspectorProtocol.checkForError(result);
+ ProtocolTest.expectEqual(result.result.value, (3 * 3) * 2, "Should change value of 'x' inside 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Inner.js'");
+
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Inner"), "Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Inner'.");
+ ProtocolTest.expectTrue(pausedFunctionNames.includes("UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Outer"), "Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointAction_Pause_Outer'.");
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setBlackboxBreakpointEvaluations.UnblackboxBreakpointEvaluations.BreakpointAction.AutoContinue",
+ async test() {
+ let [innerSourceURL, outerSourceURL] = await Promise.all([
+ listenForSourceParsed(/UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner\.js$/),
+ listenForSourceParsed(/UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer\.js$/),
+ evaluate(`createScripts("UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue")`),
+ ]);
+
+ await setBlackbox(innerSourceURL);
+ await setBreakpoint(innerSourceURL, 2, {
+ actions: [
+ {type: "evaluate", data: "x = 3"},
+ ],
+ autoContinue: true,
+ });
+ await setBlackboxBreakpointEvaluations(false);
+
+ let result = await evaluate(`UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer(2)`);
+ InspectorProtocol.checkForError(result);
+ ProtocolTest.expectEqual(result.result.value, (3 * 3) * 2, "Should change value of 'x' inside 'UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner.js'");
+
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner"), "Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner'.");
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer"), "Should not pause in 'UnblackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer'.");
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setBlackboxBreakpointEvaluations.BlackboxBreakpointEvaluations.BreakpointCondition.False",
+ async test() {
+ let [innerSourceURL, outerSourceURL] = await Promise.all([
+ listenForSourceParsed(/BlackboxBreakpointEvaluations_BreakpointCondition_False_Inner\.js$/),
+ listenForSourceParsed(/BlackboxBreakpointEvaluations_BreakpointCondition_False_Outer\.js$/),
+ evaluate(`createScripts("BlackboxBreakpointEvaluations_BreakpointCondition_False")`),
+ ]);
+
+ await setBlackbox(innerSourceURL);
+ await setBreakpoint(innerSourceURL, 2, {
+ condition: "!(x = 3)",
+ });
+ await setBlackboxBreakpointEvaluations(true);
+
+ let result = await evaluate(`BlackboxBreakpointEvaluations_BreakpointCondition_False_Outer(2)`);
+ InspectorProtocol.checkForError(result);
+ ProtocolTest.expectEqual(result.result.value, (2 * 2) * 3, "Should change value of 'x' inside 'BlackboxBreakpointEvaluations_BreakpointCondition_False_Outer.js'");
+
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("BlackboxBreakpointEvaluations_BreakpointCondition_False_Inner"), "Should not pause in 'BlackboxBreakpointEvaluations_BreakpointCondition_False_Inner'.");
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("BlackboxBreakpointEvaluations_BreakpointCondition_False_Outer"), "Should not pause in 'BlackboxBreakpointEvaluations_BreakpointCondition_False_Outer'.");
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setBlackboxBreakpointEvaluations.BlackboxBreakpointEvaluations.BreakpointCondition.True",
+ async test() {
+ let [innerSourceURL, outerSourceURL] = await Promise.all([
+ listenForSourceParsed(/BlackboxBreakpointEvaluations_BreakpointCondition_True_Inner\.js$/),
+ listenForSourceParsed(/BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer\.js$/),
+ evaluate(`createScripts("BlackboxBreakpointEvaluations_BreakpointCondition_True")`),
+ ]);
+
+ await setBlackbox(innerSourceURL);
+ await setBreakpoint(innerSourceURL, 2, {
+ condition: "(x = 3)",
+ });
+ await setBlackboxBreakpointEvaluations(true);
+
+ let result = await evaluate(`BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer(2)`);
+ InspectorProtocol.checkForError(result);
+ ProtocolTest.expectEqual(result.result.value, (2 * 2) * 3, "Should change value of 'x' inside 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer.js'");
+
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("BlackboxBreakpointEvaluations_BreakpointCondition_True_Inner"), "Should not pause in 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Inner'.");
+ ProtocolTest.expectTrue(pausedFunctionNames.includes("BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer"), "Should pause in 'BlackboxBreakpointEvaluations_BreakpointCondition_True_Outer'.");
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setBlackboxBreakpointEvaluations.BlackboxBreakpointEvaluations.BreakpointAction.Pause",
+ async test() {
+ let [innerSourceURL, outerSourceURL] = await Promise.all([
+ listenForSourceParsed(/BlackboxBreakpointEvaluations_BreakpointAction_Pause_Inner\.js$/),
+ listenForSourceParsed(/BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer\.js$/),
+ evaluate(`createScripts("BlackboxBreakpointEvaluations_BreakpointAction_Pause")`),
+ ]);
+
+ await setBlackbox(innerSourceURL);
+ await setBreakpoint(innerSourceURL, 2, {
+ actions: [
+ {type: "evaluate", data: "x = 3"},
+ ],
+ });
+ await setBlackboxBreakpointEvaluations(true);
+
+ let result = await evaluate(`BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer(2)`);
+ InspectorProtocol.checkForError(result);
+ ProtocolTest.expectEqual(result.result.value, (2 * 2) * 3, "Should change value of 'x' inside 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer.js'");
+
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("BlackboxBreakpointEvaluations_BreakpointAction_Pause_Inner"), "Should not pause in 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Inner'.");
+ ProtocolTest.expectTrue(pausedFunctionNames.includes("BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer"), "Should not pause in 'BlackboxBreakpointEvaluations_BreakpointAction_Pause_Outer'.");
+ },
+ });
+
+ suite.addTestCase({
+ name: "Debugger.setBlackboxBreakpointEvaluations.BlackboxBreakpointEvaluations.BreakpointAction.AutoContinue",
+ async test() {
+ let [innerSourceURL, outerSourceURL] = await Promise.all([
+ listenForSourceParsed(/BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner\.js$/),
+ listenForSourceParsed(/BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer\.js$/),
+ evaluate(`createScripts("BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue")`),
+ ]);
+
+ await setBlackbox(innerSourceURL);
+ await setBreakpoint(innerSourceURL, 2, {
+ actions: [
+ {type: "evaluate", data: "x = 3"},
+ ],
+ autoContinue: true,
+ });
+ await setBlackboxBreakpointEvaluations(true);
+
+ let result = await evaluate(`BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer(2)`);
+ InspectorProtocol.checkForError(result);
+ ProtocolTest.expectEqual(result.result.value, (2 * 2) * 3, "Should change value of 'x' inside 'BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer.js'");
+
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner"), "Should not pause in 'BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Inner'.");
+ ProtocolTest.expectFalse(pausedFunctionNames.includes("BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer"), "Should not pause in 'BlackboxBreakpointEvaluations_BreakpointAction_AutoContinue_Outer'.");
+ },
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests Debugger.setBlackboxBreakpointEvaluations.</p>
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (290719 => 290720)
--- trunk/Source/_javascript_Core/ChangeLog 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/_javascript_Core/ChangeLog 2022-03-02 06:42:27 UTC (rev 290720)
@@ -1,3 +1,53 @@
+2022-03-01 Devin Rousso <[email protected]>
+
+ Web Inspector: add a switch to control whether breakpoint evaluations (condition, ignore count, actions) are also affected by script blackboxing
+ https://bugs.webkit.org/show_bug.cgi?id=235274
+
+ Reviewed by Patrick Angle.
+
+ Being able to defer breakpoint evaluations until the next actual pause can sometimes be far
+ more useful than doing the breakpoint evaluations at the breakpoint's original location.
+
+ As an example, configuring the All Events breakpoint with a `console.trace()` action and
+ auto-continue enabled would not provide much useful information without also blackboxing
+ breakpoint evaluations as the original pause location of the All Events breakpoint is on the
+ first line of the event handler, meaning that if the script containing the event handler is
+ blackboxed then the `console.trace()` would still only show that location even though the
+ Sources Tab would show the first line of code outside of that script (due to the blackbox).
+ Being able to also blackbox breakpoint evaluations would instead cause the `console.trace()`
+ action to have the same output as the Sources Tab, since it's evaluation would be deferred
+ until execution actually paused, which is further inside the event handler.
+
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::Debugger):
+ (JSC::Debugger::didHitBreakpoint):
+ (JSC::Debugger::evaluateBreakpointCondition):
+ (JSC::Debugger::continueProgram):
+ (JSC::Debugger::pauseIfNeeded):
+ (JSC::Debugger::didExecuteProgram):
+ (JSC::Debugger::setBlackboxBreakpointEvaluations): Added.
+ Keep track of every `Breakpoint` wants to pause but is deferred due to blackboxing.
+ Depending on whether breakpoint evaluations are also blackboxed (based on the flag set via
+ the piping code/logic below), check if the script attempting to be paused in is blackboxed
+ before or after handling breakpoint evaluations.
+ Side effects of this change are:
+ - breakpoint conditions are now evaluated right before that breakpoint's actions, instead of
+ evaluating all breakpoint conditions before all breakpoint actions
+ - if breakpoint evaluations are blackboxed, more than two breakpoints can now be evaluated
+ during a single pause attempt depending on how may deferrals (with breakpoints) happened
+
+ * debugger/Debugger.h:
+ (JSC::Debugger::Observer::didDeferBreakpointPause): Added.
+ Add a way to notify `InspectorDebuggerAgent` of deferred breakpoint pauses so that the
+ correct `originalReason` will be used after a deferred pause.
+
+ * inspector/protocol/Debugger.json:
+ * inspector/agents/InspectorDebuggerAgent.h:
+ * inspector/agents/InspectorDebuggerAgent.cpp:
+ (Inspector::InspectorDebuggerAgent::setBlackboxBreakpointEvaluations): Added.
+ (Inspector::InspectorDebuggerAgent::didDeferBreakpointPause): Added.
+ Add a `setBlackboxBreakpointEvaluations` command that passes directly to `Debugger`.
+
2022-03-01 Saam Barati <[email protected]>
Add a DeferTraps scope
Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (290719 => 290720)
--- trunk/Source/_javascript_Core/debugger/Debugger.cpp 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp 2022-03-02 06:42:27 UTC (rev 290720)
@@ -113,6 +113,7 @@
Debugger::Debugger(VM& vm)
: m_vm(vm)
+ , m_blackboxBreakpointEvaluations(false)
, m_pauseAtNextOpportunity(false)
, m_pastFirstExpressionInStatement(false)
, m_isPaused(false)
@@ -543,7 +544,7 @@
return removed;
}
-RefPtr<Breakpoint> Debugger::didHitBreakpoint(JSGlobalObject* globalObject, SourceID sourceID, const TextPosition& position)
+RefPtr<Breakpoint> Debugger::didHitBreakpoint(SourceID sourceID, const TextPosition& position)
{
if (!m_breakpointsActivated)
return nullptr;
@@ -565,11 +566,8 @@
// Since frontend truncates the indent, the first statement in a line must match the breakpoint (line,0).
ASSERT(this == m_currentCallFrame->codeBlock()->globalObject()->debugger());
- if ((line != m_lastExecutedLine && line == breakLine && !breakColumn) || (line == breakLine && column == breakColumn)) {
- if (breakpoint->shouldPause(*this, globalObject))
- return breakpoint.copyRef();
- break;
- }
+ if ((line != m_lastExecutedLine && line == breakLine && !breakColumn) || (line == breakLine && column == breakColumn))
+ return breakpoint.copyRef();
}
return nullptr;
@@ -606,14 +604,13 @@
bool Debugger::evaluateBreakpointCondition(Breakpoint& breakpoint, JSGlobalObject* globalObject)
{
+ ASSERT(m_isPaused);
+ ASSERT(isAttached(globalObject));
+
const String& condition = breakpoint.condition();
if (condition.isEmpty())
return true;
- // We cannot stop in the debugger while executing condition code,
- // so make it looks like the debugger is already paused.
- TemporaryPausedState pausedState(*this);
-
NakedPtr<Exception> exception;
DebuggerCallFrame& debuggerCallFrame = currentDebuggerCallFrame();
JSObject* scopeExtensionObject = m_client ? m_client->debuggerScopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
@@ -781,6 +778,7 @@
void Debugger::continueProgram()
{
clearNextPauseState();
+ m_deferredBreakpoints.clear();
if (!m_isPaused)
return;
@@ -883,27 +881,34 @@
DebuggerPausedScope debuggerPausedScope(*this);
- bool pauseNow = m_pauseAtNextOpportunity;
- pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame);
+ bool afterBlackboxedScript = m_afterBlackboxedScript;
+ bool pauseNow = false;
+ bool didPauseForStep = false;
+ if (m_pauseAtNextOpportunity) {
+ pauseNow = true;
+ didPauseForStep = !afterBlackboxedScript;
+ } else if (m_pauseOnStepNext || m_pauseOnStepOut || (m_pauseOnCallFrame == m_currentCallFrame)) {
+ pauseNow = true;
+ didPauseForStep = true;
+ }
- bool didPauseForStep = pauseNow;
-
TextPosition position = DebuggerCallFrame::positionForCallFrame(vm, m_currentCallFrame);
- auto breakpoint = didHitBreakpoint(globalObject, sourceID, position);
- if (breakpoint)
+ if (auto breakpoint = didHitBreakpoint(sourceID, position)) {
pauseNow = true;
+ m_deferredBreakpoints.add(breakpoint.releaseNonNull());
+ }
// Special breakpoints are only given one opportunity to pause.
- auto specialBreakpoint = WTFMove(m_specialBreakpoint);
- if (specialBreakpoint && specialBreakpoint->shouldPause(*this, globalObject))
+ if (m_specialBreakpoint) {
pauseNow = true;
+ m_deferredBreakpoints.add(m_specialBreakpoint.releaseNonNull());
+ }
m_lastExecutedLine = position.m_line.zeroBasedInt();
if (!pauseNow)
return;
- bool afterBlackboxedScript = m_afterBlackboxedScript;
clearNextPauseState();
// Make sure we are not going to pause again on breakpoint actions by
@@ -910,53 +915,78 @@
// reseting the pause state before executing any breakpoint actions.
TemporaryPausedState pausedState(*this);
- if (breakpoint || specialBreakpoint) {
- // Note that the actions can potentially stop the debugger, so we need to check that
- // we still have a current call frame when we get back.
+ auto shouldDeferPause = [&] () {
+ if (blackboxTypeIterator == m_blackboxedScripts.end())
+ return false;
- bool autoContinue = false;
+ if (blackboxTypeIterator->value != BlackboxType::Deferred)
+ return false;
- if (breakpoint) {
- evaluateBreakpointActions(*breakpoint, globalObject);
+ m_afterBlackboxedScript = true;
- if (!m_currentCallFrame)
- return;
+ if (m_pausingBreakpointID != noBreakpointID) {
+ dispatchFunctionToObservers([&] (Observer& observer) {
+ observer.didDeferBreakpointPause(m_pausingBreakpointID);
+ });
- if (breakpoint->isAutoContinue())
- autoContinue = true;
+ m_pausingBreakpointID = noBreakpointID;
}
- if (specialBreakpoint) {
- evaluateBreakpointActions(*specialBreakpoint, globalObject);
+ schedulePauseAtNextOpportunity();
+ return true;
+ };
+ if (m_blackboxBreakpointEvaluations && shouldDeferPause())
+ return;
+
+ if (!m_deferredBreakpoints.isEmpty()) {
+ std::optional<BreakpointID> pausingBreakpointID;
+ bool hasEvaluatedSpecialBreakpoint = false;
+ bool shouldContinue = true;
+
+ for (auto&& deferredBreakpoint : std::exchange(m_deferredBreakpoints, { })) {
+ // Note that breakpoint evaluations can potentially stop the debugger, so we need to
+ // check that we still have a current call frame after evaluating them.
+
+ bool shouldPause = deferredBreakpoint->shouldPause(*this, globalObject);
if (!m_currentCallFrame)
return;
+ if (!shouldPause)
+ continue;
- if (specialBreakpoint->isAutoContinue())
- autoContinue = true;
+ evaluateBreakpointActions(deferredBreakpoint, globalObject);
+ if (!m_currentCallFrame)
+ return;
+
+ if (deferredBreakpoint->isAutoContinue())
+ continue;
+
+ shouldContinue = false;
+
+ // Only propagate `PausedForBreakpoint` to the `InspectorDebuggerAgent` if the first
+ // line:column breakpoint hit was before the first special breakpoint, as the latter
+ // would already have set a unique reason before attempting to pause.
+ if (!deferredBreakpoint->isLinked())
+ hasEvaluatedSpecialBreakpoint = true;
+ else if (!hasEvaluatedSpecialBreakpoint && !pausingBreakpointID)
+ pausingBreakpointID = deferredBreakpoint->id();
}
- if (autoContinue) {
+ if (shouldContinue) {
if (!didPauseForStep)
return;
-
- breakpoint = nullptr;
- specialBreakpoint = nullptr;
- } else if (breakpoint)
- m_pausingBreakpointID = breakpoint->id();
+ } else if (pausingBreakpointID)
+ m_pausingBreakpointID = *pausingBreakpointID;
}
- if (blackboxTypeIterator != m_blackboxedScripts.end() && blackboxTypeIterator->value == BlackboxType::Deferred) {
- m_afterBlackboxedScript = true;
- schedulePauseAtNextOpportunity();
+ if (!m_blackboxBreakpointEvaluations && shouldDeferPause())
return;
- }
{
auto reason = m_reasonForPause;
if (afterBlackboxedScript)
reason = PausedAfterBlackboxedScript;
- else if (breakpoint)
+ else if (m_pausingBreakpointID)
reason = PausedForBreakpoint;
PauseReasonDeclaration rauseReasonDeclaration(*this, reason);
@@ -1154,8 +1184,10 @@
updateCallFrame(lexicalGlobalObjectForCallFrame(m_vm, callerFrame), callerFrame, NoPause);
// Do not continue stepping into an unknown future program.
- if (!m_currentCallFrame)
+ if (!m_currentCallFrame) {
clearNextPauseState();
+ m_deferredBreakpoints.clear();
+ }
}
void Debugger::clearNextPauseState()
@@ -1211,6 +1243,11 @@
m_blackboxedScripts.remove(sourceID);
}
+void Debugger::setBlackboxBreakpointEvaluations(bool blackboxBreakpointEvaluations)
+{
+ m_blackboxBreakpointEvaluations = blackboxBreakpointEvaluations;
+}
+
void Debugger::clearBlackbox()
{
m_blackboxedScripts.clear();
Modified: trunk/Source/_javascript_Core/debugger/Debugger.h (290719 => 290720)
--- trunk/Source/_javascript_Core/debugger/Debugger.h 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/_javascript_Core/debugger/Debugger.h 2022-03-02 06:42:27 UTC (rev 290720)
@@ -28,6 +28,7 @@
#include "DebuggerPrimitives.h"
#include "JSCJSValue.h"
#include <wtf/Forward.h>
+#include <wtf/ListHashSet.h>
namespace JSC {
@@ -115,6 +116,7 @@
enum class BlackboxType { Deferred, Ignored };
void setBlackboxType(SourceID, std::optional<BlackboxType>);
+ void setBlackboxBreakpointEvaluations(bool);
void clearBlackbox();
bool isPaused() const { return m_isPaused; }
@@ -181,6 +183,7 @@
virtual void breakpointActionLog(JSGlobalObject*, const String& /* data */) { }
virtual void breakpointActionSound(BreakpointActionID) { }
virtual void breakpointActionProbe(JSGlobalObject*, BreakpointActionID, unsigned /* batchId */, unsigned /* sampleId */, JSValue /* result */) { }
+ virtual void didDeferBreakpointPause(BreakpointID) { }
};
JS_EXPORT_PRIVATE void addObserver(Observer&);
@@ -257,7 +260,7 @@
Debugger& m_debugger;
};
- RefPtr<Breakpoint> didHitBreakpoint(JSGlobalObject*, SourceID, const TextPosition&);
+ RefPtr<Breakpoint> didHitBreakpoint(SourceID, const TextPosition&);
DebuggerParseData& debuggerParseData(SourceID, SourceProvider*);
@@ -299,6 +302,7 @@
HashSet<JSGlobalObject*> m_globalObjects;
HashMap<SourceID, DebuggerParseData, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> m_parseDataMap;
HashMap<SourceID, BlackboxType, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> m_blackboxedScripts;
+ bool m_blackboxBreakpointEvaluations : 1;
bool m_pauseAtNextOpportunity : 1;
bool m_pauseOnStepNext : 1;
@@ -322,6 +326,7 @@
HashMap<SourceID, LineToBreakpointsMap, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> m_breakpointsForSourceID;
HashSet<Ref<Breakpoint>> m_breakpoints;
RefPtr<Breakpoint> m_specialBreakpoint;
+ ListHashSet<Ref<Breakpoint>> m_deferredBreakpoints;
BreakpointID m_pausingBreakpointID;
RefPtr<Breakpoint> m_pauseOnAllExceptionsBreakpoint;
Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (290719 => 290720)
--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp 2022-03-02 06:42:27 UTC (rev 290720)
@@ -1069,6 +1069,13 @@
return false;
}
+Protocol::ErrorStringOr<void> InspectorDebuggerAgent::setBlackboxBreakpointEvaluations(bool blackboxBreakpointEvaluations)
+{
+ m_debugger.setBlackboxBreakpointEvaluations(blackboxBreakpointEvaluations);
+
+ return { };
+}
+
void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directiveText)
{
if (m_debugger.needsExceptionCallbacks())
@@ -1321,6 +1328,11 @@
m_frontendDispatcher->resumed();
}
+void InspectorDebuggerAgent::didDeferBreakpointPause(JSC::BreakpointID breakpointId)
+{
+ updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason::Breakpoint, buildBreakpointPauseReason(breakpointId));
+}
+
void InspectorDebuggerAgent::breakProgram(DebuggerFrontendDispatcher::Reason reason, RefPtr<JSON::Object>&& data, RefPtr<JSC::Breakpoint>&& specialBreakpoint)
{
updatePauseReasonAndData(reason, WTFMove(data));
Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h (290719 => 290720)
--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h 2022-03-02 06:42:27 UTC (rev 290720)
@@ -93,6 +93,7 @@
Protocol::ErrorStringOr<void> setPauseForInternalScripts(bool shouldPause) final;
Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluateOnCallFrame(const Protocol::Debugger::CallFrameId&, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture) override;
Protocol::ErrorStringOr<void> setShouldBlackboxURL(const String& url, bool shouldBlackbox, std::optional<bool>&& caseSensitive, std::optional<bool>&& isRegex) final;
+ Protocol::ErrorStringOr<void> setBlackboxBreakpointEvaluations(bool) final;
// JSC::Debugger::Client
JSC::JSObject* debuggerScopeExtensionObject(JSC::Debugger&, JSC::JSGlobalObject*, JSC::DebuggerCallFrame&) final;
@@ -106,6 +107,7 @@
void didContinue() final;
void breakpointActionSound(JSC::BreakpointActionID) final;
void breakpointActionProbe(JSC::JSGlobalObject*, JSC::BreakpointActionID, unsigned batchId, unsigned sampleId, JSC::JSValue sample) final;
+ void didDeferBreakpointPause(JSC::BreakpointID) final;
bool isPaused() const;
bool breakpointsActive() const;
Modified: trunk/Source/_javascript_Core/inspector/protocol/Debugger.json (290719 => 290720)
--- trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2022-03-02 06:42:27 UTC (rev 290720)
@@ -322,6 +322,13 @@
{ "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If true, <code>url</code> is case sensitive." },
{ "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treat <code>url</code> as regular _expression_." }
]
+ },
+ {
+ "name": "setBlackboxBreakpointEvaluations",
+ "description": "Sets whether evaluation of breakpoint conditions, ignore counts, and actions happen at the location of the breakpoint or are deferred due to blackboxing.",
+ "parameters": [
+ { "name": "blackboxBreakpointEvaluations", "type": "boolean" }
+ ]
}
],
"events": [
Modified: trunk/Source/WebInspectorUI/ChangeLog (290719 => 290720)
--- trunk/Source/WebInspectorUI/ChangeLog 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/WebInspectorUI/ChangeLog 2022-03-02 06:42:27 UTC (rev 290720)
@@ -1,3 +1,41 @@
+2022-03-01 Devin Rousso <[email protected]>
+
+ Web Inspector: add a switch to control whether breakpoint evaluations (condition, ignore count, actions) are also affected by script blackboxing
+ https://bugs.webkit.org/show_bug.cgi?id=235274
+
+ Reviewed by Patrick Angle.
+
+ Being able to defer breakpoint evaluations until the next actual pause can sometimes be far
+ more useful than doing the breakpoint evaluations at the breakpoint's original location.
+
+ As an example, configuring the All Events breakpoint with a `console.trace()` action and
+ auto-continue enabled would not provide much useful information without also blackboxing
+ breakpoint evaluations as the original pause location of the All Events breakpoint is on the
+ first line of the event handler, meaning that if the script containing the event handler is
+ blackboxed then the `console.trace()` would still only show that location even though the
+ Sources Tab would show the first line of code outside of that script (due to the blackbox).
+ Being able to also blackbox breakpoint evaluations would instead cause the `console.trace()`
+ action to have the same output as the Sources Tab, since it's evaluation would be deferred
+ until execution actually paused, which is further inside the event handler
+
+ * UserInterface/Base/Setting.js:
+ * UserInterface/Controllers/DebuggerManager.js:
+ (WI.DebuggerManager.supportsBlackboxingBreakpointEvaluations): Added.
+ (WI.DebuggerManager.prototype.async initializeTarget):
+ (WI.DebuggerManager.prototype._setBlackboxBreakpointEvaluations): Added.
+ (WI.DebuggerManager.prototype._handleBlackboxBreakpointEvaluationsChange): Added.
+ Create a global `WI.Setting` for this feature and handle changes from the code below.
+
+ * UserInterface/Views/BlackboxSettingsView.js:
+ (WI.BlackboxSettingsView.prototype.initialLayout):
+ * UserInterface/Views/BlackboxSettingsView.css:
+ (.settings-view.blackbox > p > label): Added.
+ (.settings-view.blackbox > p > label > input): Added.
+ (.settings-view.blackbox > p > label > span): Added.
+ Add a checkbox and explanation of this new feature in the Blackbox pane of the Settings Tab.
+
+ * Localizations/en.lproj/localizedStrings.js:
+
2022-02-28 Devin Rousso <[email protected]>
Web Inspector: [Flexbox] Add options to show each area's CSS `order` and/or DOM index in the parent flex container
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (290719 => 290720)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2022-03-02 06:42:27 UTC (rev 290720)
@@ -160,6 +160,7 @@
/* Label for setting that allows the user to inspect the Web Inspector user interface. */
localizedStrings["Allow Inspecting Web Inspector @ Experimental Settings"] = "Allow Inspecting Web Inspector";
localizedStrings["Allow Media Capture on Insecure Sites"] = "Allow Media Capture on Insecure Sites";
+localizedStrings["Also defer evaluating breakpoint conditions, ignore counts, and actions until execution has continued outside of the related script instead of at the breakpoint's location."] = "Also defer evaluating breakpoint conditions, ignore counts, and actions until execution has continued outside of the related script instead of at the breakpoint's location.";
/* Property title for `font-variant-alternates`. */
localizedStrings["Alternate Glyphs @ Font Details Sidebar Property"] = "Alternate Glyphs";
localizedStrings["An error occurred trying to load the resource."] = "An error occurred trying to load the resource.";
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (290719 => 290720)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2022-03-02 06:42:27 UTC (rev 290720)
@@ -184,6 +184,7 @@
};
WI.settings = {
+ blackboxBreakpointEvaluations: new WI.Setting("blackbox-breakpoint-evaluations", false),
canvasRecordingAutoCaptureEnabled: new WI.Setting("canvas-recording-auto-capture-enabled", false),
canvasRecordingAutoCaptureFrameCount: new WI.Setting("canvas-recording-auto-capture-frame-count", 1),
consoleAutoExpandTrace: new WI.Setting("console-auto-expand-trace", true),
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js (290719 => 290720)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2022-03-02 06:42:27 UTC (rev 290720)
@@ -43,6 +43,8 @@
WI.targetManager.addEventListener(WI.TargetManager.Event.TargetRemoved, this._targetRemoved, this);
+ WI.settings.blackboxBreakpointEvaluations.addEventListener(WI.Setting.Event.Changed, this._handleBlackboxBreakpointEvaluationsChange, this);
+
if (WI.isEngineeringBuild) {
WI.settings.engineeringShowInternalScripts.addEventListener(WI.Setting.Event.Changed, this._handleEngineeringShowInternalScriptsSettingChanged, this);
WI.settings.engineeringPauseForInternalScripts.addEventListener(WI.Setting.Event.Changed, this._handleEngineeringPauseForInternalScriptsSettingChanged, this);
@@ -223,6 +225,8 @@
}
}
+ this._setBlackboxBreakpointEvaluations(target);
+
if (WI.isEngineeringBuild) {
// COMPATIBILITY (iOS 12): DebuggerAgent.setPauseForInternalScripts did not exist yet.
if (target.hasCommand("Debugger.setPauseForInternalScripts"))
@@ -248,9 +252,16 @@
static supportsBlackboxingScripts()
{
+ // COMPATIBILITY (iOS 13): Debugger.setShouldBlackboxURL did not exist yet.
return InspectorBackend.hasCommand("Debugger.setShouldBlackboxURL");
}
+ static supportsBlackboxingBreakpointEvaluations()
+ {
+ // COMPATIBILITY (iOS 15.4): Debugger.setBlackboxBreakpointEvaluations did not exist yet.
+ return InspectorBackend.hasCommand("Debugger.setBlackboxBreakpointEvaluations");
+ }
+
static pauseReasonFromPayload(payload)
{
switch (payload) {
@@ -1255,6 +1266,13 @@
}
}
+ _setBlackboxBreakpointEvaluations(target)
+ {
+ // COMPATIBILITY (iOS 15.4): Debugger.setBlackboxBreakpointEvaluations did not exist yet.
+ if (target.hasCommand("Debugger.setBlackboxBreakpointEvaluations"))
+ target.DebuggerAgent.setBlackboxBreakpointEvaluations(WI.settings.blackboxBreakpointEvaluations.value);
+ }
+
_breakpointDisplayLocationDidChange(event)
{
if (this._ignoreBreakpointDisplayLocationDidChangeEvent)
@@ -1399,6 +1417,12 @@
this.dispatchEventToListeners(WI.DebuggerManager.Event.Resumed);
}
+ _handleBlackboxBreakpointEvaluationsChange(event)
+ {
+ for (let target of WI.targets)
+ this._setBlackboxBreakpointEvaluations(target);
+ }
+
_handleEngineeringShowInternalScriptsSettingChanged(event)
{
let eventType = WI.settings.engineeringShowInternalScripts.value ? WI.DebuggerManager.Event.ScriptAdded : WI.DebuggerManager.Event.ScriptRemoved;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/BlackboxSettingsView.css (290719 => 290720)
--- trunk/Source/WebInspectorUI/UserInterface/Views/BlackboxSettingsView.css 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/BlackboxSettingsView.css 2022-03-02 06:42:27 UTC (rev 290720)
@@ -48,6 +48,19 @@
vertical-align: middle;
}
+.settings-view.blackbox > p > label {
+ display: flex;
+}
+
+.settings-view.blackbox > p > label > input {
+ flex-shrink: 0;
+ margin-inline: 0.5px 4px;
+}
+
+.settings-view.blackbox > p > label > span {
+ margin-top: 1.5px;
+}
+
.settings-view.blackbox > table {
border-collapse: collapse;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/BlackboxSettingsView.js (290719 => 290720)
--- trunk/Source/WebInspectorUI/UserInterface/Views/BlackboxSettingsView.js 2022-03-02 06:05:31 UTC (rev 290719)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/BlackboxSettingsView.js 2022-03-02 06:42:27 UTC (rev 290720)
@@ -106,6 +106,20 @@
a.append(b);
return a;
});
+
+ if (WI.DebuggerManager.supportsBlackboxingBreakpointEvaluations()) {
+ let blackboxBreakpointEvaluationsExplanationElement = this.element.insertBefore(document.createElement("p"), this.element.lastChild);
+ let blackboxBreakpointEvaluationsExplanationLabel = blackboxBreakpointEvaluationsExplanationElement.appendChild(document.createElement("label"));
+
+ let blackboxBreakpointEvaluationsExplanationCheckbox = blackboxBreakpointEvaluationsExplanationLabel.appendChild(document.createElement("input"));
+ blackboxBreakpointEvaluationsExplanationCheckbox.type = "checkbox";
+ blackboxBreakpointEvaluationsExplanationCheckbox.checked = WI.settings.blackboxBreakpointEvaluations.value;
+ blackboxBreakpointEvaluationsExplanationCheckbox.addEventListener("change", (event) => {
+ WI.settings.blackboxBreakpointEvaluations.value = blackboxBreakpointEvaluationsExplanationCheckbox.checked;
+ });
+
+ blackboxBreakpointEvaluationsExplanationLabel.append(WI.UIString("Also defer evaluating breakpoint conditions, ignore counts, and actions until execution has continued outside of the related script instead of at the breakpoint's location."));
+ }
}
// Private