Changeset 266074 in webkit
- Timestamp:
- Aug 24, 2020, 10:34:12 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 4 deleted
- 107 edited
- 1 copied
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/tests/inspector/debugger/debugger-test.js (modified) (1 diff)
-
LayoutTests/http/tests/inspector/resources/probe-test.js (modified) (1 diff)
-
LayoutTests/inspector/debugger/breakpoint-action-eval.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/breakpoint-action-log.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/breakpoint-columns.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/breakpoint-scope.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/debugger-stack-overflow.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/pause-reason.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/probe-manager-add-remove-actions.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/stepping/stepping-through-autoContinue-breakpoint.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/tail-deleted-frames-this-value.html (modified) (1 diff)
-
LayoutTests/inspector/debugger/tail-recursion.html (modified) (1 diff)
-
LayoutTests/inspector/dom-debugger/event-animation-frame-breakpoints-expected.txt (modified) (6 diffs)
-
LayoutTests/inspector/dom-debugger/event-animation-frame-breakpoints.html (modified) (5 diffs)
-
LayoutTests/inspector/dom-debugger/event-interval-breakpoints-expected.txt (modified) (6 diffs)
-
LayoutTests/inspector/dom-debugger/event-interval-breakpoints.html (modified) (10 diffs)
-
LayoutTests/inspector/dom-debugger/event-listener-breakpoints-expected.txt (modified) (3 diffs)
-
LayoutTests/inspector/dom-debugger/event-listener-breakpoints.html (modified) (8 diffs)
-
LayoutTests/inspector/dom-debugger/event-timeout-breakpoints-expected.txt (modified) (6 diffs)
-
LayoutTests/inspector/dom-debugger/event-timeout-breakpoints.html (modified) (6 diffs)
-
LayoutTests/inspector/dom-debugger/resources/event-breakpoint-utilities.js (modified) (3 diffs)
-
LayoutTests/inspector/dom/breakpoint-for-event-listener-expected.txt (modified) (2 diffs)
-
LayoutTests/inspector/dom/breakpoint-for-event-listener.html (modified) (6 diffs)
-
LayoutTests/inspector/worker/debugger-pause.html (modified) (1 diff)
-
LayoutTests/inspector/worker/debugger-shared-breakpoint.html (modified) (1 diff)
-
Source/JavaScriptCore/CMakeLists.txt (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (modified) (7 diffs)
-
Source/JavaScriptCore/Sources.txt (modified) (2 diffs)
-
Source/JavaScriptCore/debugger/Breakpoint.cpp (added)
-
Source/JavaScriptCore/debugger/Breakpoint.h (modified) (1 diff)
-
Source/JavaScriptCore/debugger/Debugger.cpp (modified) (24 diffs)
-
Source/JavaScriptCore/debugger/Debugger.h (modified) (13 diffs)
-
Source/JavaScriptCore/debugger/DebuggerPrimitives.h (modified) (1 diff)
-
Source/JavaScriptCore/inspector/InspectorEnvironment.h (modified) (3 diffs)
-
Source/JavaScriptCore/inspector/JSGlobalObjectScriptDebugServer.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/inspector/JSGlobalObjectScriptDebugServer.h (modified) (2 diffs)
-
Source/JavaScriptCore/inspector/ScriptBreakpoint.h (deleted)
-
Source/JavaScriptCore/inspector/ScriptDebugListener.h (deleted)
-
Source/JavaScriptCore/inspector/ScriptDebugServer.cpp (deleted)
-
Source/JavaScriptCore/inspector/ScriptDebugServer.h (deleted)
-
Source/JavaScriptCore/inspector/agents/InspectorAuditAgent.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/inspector/agents/InspectorAuditAgent.h (modified) (2 diffs)
-
Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp (modified) (34 diffs)
-
Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h (modified) (10 diffs)
-
Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp (modified) (8 diffs)
-
Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h (modified) (3 diffs)
-
Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp (modified) (1 diff)
-
Source/JavaScriptCore/inspector/agents/JSGlobalObjectDebuggerAgent.h (modified) (1 diff)
-
Source/JavaScriptCore/inspector/protocol/DOM.json (modified) (1 diff)
-
Source/JavaScriptCore/inspector/protocol/DOMDebugger.json (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSMicrotask.cpp (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/dom/EventTarget.cpp (modified) (1 diff)
-
Source/WebCore/inspector/InspectorInstrumentation.cpp (modified) (5 diffs)
-
Source/WebCore/inspector/InspectorInstrumentation.h (modified) (6 diffs)
-
Source/WebCore/inspector/PageScriptDebugServer.cpp (modified) (7 diffs)
-
Source/WebCore/inspector/PageScriptDebugServer.h (modified) (3 diffs)
-
Source/WebCore/inspector/TimelineRecordFactory.cpp (modified) (2 diffs)
-
Source/WebCore/inspector/TimelineRecordFactory.h (modified) (2 diffs)
-
Source/WebCore/inspector/WorkerScriptDebugServer.cpp (modified) (5 diffs)
-
Source/WebCore/inspector/WorkerScriptDebugServer.h (modified) (3 diffs)
-
Source/WebCore/inspector/agents/InspectorDOMAgent.cpp (modified) (10 diffs)
-
Source/WebCore/inspector/agents/InspectorDOMAgent.h (modified) (5 diffs)
-
Source/WebCore/inspector/agents/InspectorDOMDebuggerAgent.cpp (modified) (10 diffs)
-
Source/WebCore/inspector/agents/InspectorDOMDebuggerAgent.h (modified) (5 diffs)
-
Source/WebCore/inspector/agents/InspectorTimelineAgent.cpp (modified) (4 diffs)
-
Source/WebCore/inspector/agents/InspectorTimelineAgent.h (modified) (3 diffs)
-
Source/WebCore/inspector/agents/page/PageDOMDebuggerAgent.cpp (modified) (4 diffs)
-
Source/WebCore/inspector/agents/page/PageDOMDebuggerAgent.h (modified) (5 diffs)
-
Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp (modified) (1 diff)
-
Source/WebCore/inspector/agents/page/PageDebuggerAgent.h (modified) (2 diffs)
-
Source/WebCore/inspector/agents/worker/WorkerDOMDebuggerAgent.cpp (modified) (1 diff)
-
Source/WebCore/inspector/agents/worker/WorkerDOMDebuggerAgent.h (modified) (2 diffs)
-
Source/WebCore/inspector/agents/worker/WorkerDebuggerAgent.h (modified) (1 diff)
-
Source/WebCore/page/DOMTimer.cpp (modified) (5 diffs)
-
Source/WebInspectorUI/ChangeLog (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Base/Setting.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Controllers/DOMDebuggerManager.js (modified) (18 diffs)
-
Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js (modified) (6 diffs)
-
Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js (modified) (21 diffs)
-
Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Main.html (modified) (5 diffs)
-
Source/WebInspectorUI/UserInterface/Models/Breakpoint.js (modified) (19 diffs)
-
Source/WebInspectorUI/UserInterface/Models/BreakpointAction.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Models/DOMBreakpoint.js (modified) (7 diffs)
-
Source/WebInspectorUI/UserInterface/Models/EventBreakpoint.js (modified) (4 diffs)
-
Source/WebInspectorUI/UserInterface/Models/JavaScriptBreakpoint.js (added)
-
Source/WebInspectorUI/UserInterface/Models/ProbeSet.js (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Models/URLBreakpoint.js (modified) (5 diffs)
-
Source/WebInspectorUI/UserInterface/Test.html (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.css (modified) (2 diffs)
-
Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.js (modified) (9 diffs)
-
Source/WebInspectorUI/UserInterface/Views/CallFrameTreeElement.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/ContentView.js (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/DOMBreakpointTreeElement.css (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/DOMBreakpointTreeElement.js (modified) (2 diffs)
-
Source/WebInspectorUI/UserInterface/Views/DOMTreeContentView.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/EventBreakpointTreeElement.css (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/EventBreakpointTreeElement.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/EventListenerSectionGroup.css (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/EventListenerSectionGroup.js (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Views/JavaScriptBreakpointTreeElement.css (copied) (copied from trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.css ) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Views/JavaScriptBreakpointTreeElement.js (added)
-
Source/WebInspectorUI/UserInterface/Views/ProbeDetailsSidebarPanel.js (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/ProbeSetDetailsSection.js (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js (modified) (3 diffs)
-
Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js (modified) (25 diffs)
-
Source/WebInspectorUI/UserInterface/Views/TextResourceContentView.js (modified) (2 diffs)
-
Source/WebInspectorUI/UserInterface/Views/URLBreakpointTreeElement.css (modified) (1 diff)
-
Source/WebInspectorUI/UserInterface/Views/URLBreakpointTreeElement.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r266073 r266074 1 2020-08-24 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: allow event breakpoints to be configured 4 https://bugs.webkit.org/show_bug.cgi?id=215362 5 <rdar://problem/66932921> 6 7 Reviewed by Brian Burg. 8 9 * inspector/dom-debugger/resources/event-breakpoint-utilities.js: 10 (TestPage.registerInitializer.InspectorTest.EventBreakpoint.addBreakpointOptionsTestCases): Added. 11 (TestPage.registerInitializer.InspectorTest.EventBreakpoint.async teardown): 12 (TestPage.registerInitializer.InspectorTest.EventBreakpoint.createBreakpoint): 13 (TestPage.registerInitializer.InspectorTest.EventBreakpoint.removeBreakpoint): 14 * inspector/dom/breakpoint-for-event-listener.html: 15 * inspector/dom/breakpoint-for-event-listener-expected.txt: 16 * inspector/dom-debugger/event-animation-frame-breakpoints.html: 17 * inspector/dom-debugger/event-animation-frame-breakpoints-expected.txt: 18 * inspector/dom-debugger/event-interval-breakpoints.html: 19 * inspector/dom-debugger/event-interval-breakpoints-expected.txt: 20 * inspector/dom-debugger/event-listener-breakpoints.html: 21 * inspector/dom-debugger/event-listener-breakpoints-expected.txt: 22 * inspector/dom-debugger/event-timeout-breakpoints.html: 23 * inspector/dom-debugger/event-timeout-breakpoints-expected.txt: 24 Add tests for new event breakpoint configuration options. 25 26 * http/tests/inspector/debugger/debugger-test.js: 27 (TestPage.registerInitializer.InspectorTest.startTracingBreakpoints): 28 * http/tests/inspector/resources/probe-test.js: 29 (TestPage.registerInitializer.ProtocolTest.Probe.installTracingListeners): 30 * inspector/debugger/breakpoint-action-eval.html: 31 * inspector/debugger/breakpoint-action-log.html: 32 * inspector/debugger/breakpoint-columns.html: 33 * inspector/debugger/breakpoint-scope.html: 34 * inspector/debugger/debugger-stack-overflow.html: 35 * inspector/debugger/pause-reason.html: 36 * inspector/debugger/probe-manager-add-remove-actions.html: 37 * inspector/debugger/stepping/stepping-through-autoContinue-breakpoint.html: 38 * inspector/debugger/tail-deleted-frames-this-value.html: 39 * inspector/debugger/tail-recursion.html: 40 * inspector/worker/debugger-pause.html: 41 * inspector/worker/debugger-shared-breakpoint.html: 42 Update existing breakpoint tests to use new model objects. 43 1 44 2020-08-24 Hector Lopez <hector_i_lopez@apple.com> 2 45 -
trunk/LayoutTests/http/tests/inspector/debugger/debugger-test.js
r236845 r266074 14 14 }); 15 15 16 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, function(event) {16 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, function(event) { 17 17 var breakpoint = event.target; 18 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");18 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 19 19 20 20 InspectorTest.log("Breakpoint disabled state changed: " + breakpoint.disabled); 21 21 }); 22 22 23 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ResolvedStateDidChange, function(event) {23 WI.JavaScriptBreakpoint.addEventListener(WI.JavaScriptBreakpoint.Event.ResolvedStateDidChange, function(event) { 24 24 var breakpoint = event.target; 25 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");25 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 26 26 27 27 InspectorTest.log("Breakpoint resolved state changed: " + breakpoint.resolved); 28 28 }); 29 29 30 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, function(event) {30 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, function(event) { 31 31 var breakpoint = event.target; 32 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");32 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 33 33 34 34 InspectorTest.log("Breakpoint autocontinue state changed: " + breakpoint.autoContinue); 35 35 }); 36 36 37 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, function(event) {37 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, function(event) { 38 38 var breakpoint = event.target; 39 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");39 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 40 40 41 41 InspectorTest.log("Breakpoint condition changed: " + breakpoint.condition); 42 42 }); 43 43 44 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, function(event) {44 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, function(event) { 45 45 var breakpoint = event.target; 46 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");46 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 47 47 48 48 InspectorTest.log("Breakpoint actions changed. New count: " + breakpoint.actions.length); -
trunk/LayoutTests/http/tests/inspector/resources/probe-test.js
r236845 r266074 61 61 }); 62 62 63 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, function(event) {63 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, function(event) { 64 64 var breakpoint = event.target; 65 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");65 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 66 66 67 67 InspectorTest.log("Breakpoint disabled state changed: " + breakpoint.disabled); 68 68 }); 69 69 70 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ResolvedStateDidChange, function(event) {70 WI.JavaScriptBreakpoint.addEventListener(WI.JavaScriptBreakpoint.Event.ResolvedStateDidChange, function(event) { 71 71 var breakpoint = event.target; 72 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");72 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 73 73 74 74 InspectorTest.log("Breakpoint resolved state changed: " + breakpoint.resolved); 75 75 }); 76 76 77 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, function(event) {77 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, function(event) { 78 78 var breakpoint = event.target; 79 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");79 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 80 80 81 81 InspectorTest.log("Breakpoint autocontinue state changed: " + breakpoint.autoContinue); 82 82 }); 83 83 84 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, function(event) {84 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, function(event) { 85 85 var breakpoint = event.target; 86 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");86 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 87 87 88 88 InspectorTest.log("Breakpoint condition changed: " + breakpoint.condition); 89 89 }); 90 90 91 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, function(event) {91 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, function(event) { 92 92 var breakpoint = event.target; 93 console.assert(breakpoint instanceof WI. Breakpoint, "Unexpected object type!");93 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint, "Unexpected object type!"); 94 94 95 95 InspectorTest.log("Breakpoint actions changed. New count: " + breakpoint.actions.length); -
trunk/LayoutTests/inspector/debugger/breakpoint-action-eval.html
r251485 r266074 29 29 var location = scriptObject.createSourceCodeLocation(4, 0); 30 30 // Create the breakpoint and its actions before sending anything to the backend. 31 var breakpoint = new WI. Breakpoint(location);31 var breakpoint = new WI.JavaScriptBreakpoint(location); 32 32 breakpoint.autoContinue = true; 33 breakpoint.createAction(WI.BreakpointAction.Type.Evaluate, null, "action(a, b)");33 breakpoint.createAction(WI.BreakpointAction.Type.Evaluate, {data: "action(a, b)"}); 34 34 35 35 WI.debuggerManager.addBreakpoint(breakpoint); -
trunk/LayoutTests/inspector/debugger/breakpoint-action-log.html
r251485 r266074 25 25 26 26 let location = scriptObject.createSourceCodeLocation(4, 0); 27 let breakpoint = new WI. Breakpoint(location);27 let breakpoint = new WI.JavaScriptBreakpoint(location); 28 28 breakpoint.autoContinue = true; 29 29 30 30 function addLogAction(data) { 31 breakpoint.createAction(WI.BreakpointAction.Type.Log, breakpoint.actions.lastValue, data);31 breakpoint.createAction(WI.BreakpointAction.Type.Log, {data}); 32 32 } 33 33 -
trunk/LayoutTests/inspector/debugger/breakpoint-columns.html
r220119 r266074 39 39 40 40 var location = currentScripts[testInfo.scriptIndex].createSourceCodeLocation(testInfo.line, testInfo.column); 41 var breakpoint = new WI. Breakpoint(location);41 var breakpoint = new WI.JavaScriptBreakpoint(location); 42 42 43 43 WI.debuggerManager.addBreakpoint(breakpoint); -
trunk/LayoutTests/inspector/debugger/breakpoint-scope.html
r237571 r266074 30 30 var testInfo = testInfoList[currentTestIndex]; 31 31 var location = scriptObject.createSourceCodeLocation(testInfo.line, testInfo.column); 32 var breakpoint = new WI. Breakpoint(location);32 var breakpoint = new WI.JavaScriptBreakpoint(location); 33 33 34 34 WI.debuggerManager.addBreakpoint(breakpoint); -
trunk/LayoutTests/inspector/debugger/debugger-stack-overflow.html
r220119 r266074 16 16 let testInfo = {line: 8, column: 8}; 17 17 let location = scriptObject.createSourceCodeLocation(testInfo.line, testInfo.column); 18 let breakpoint = new WI. Breakpoint(location);18 let breakpoint = new WI.JavaScriptBreakpoint(location); 19 19 WI.debuggerManager.addBreakpoint(breakpoint); 20 20 InspectorTest.evaluateInPage("start()"); -
trunk/LayoutTests/inspector/debugger/pause-reason.html
r236540 r266074 17 17 continue; 18 18 let sourceCodeLocation = script.createSourceCodeLocation(3, 0); 19 let breakpoint = new WI. Breakpoint(sourceCodeLocation);19 let breakpoint = new WI.JavaScriptBreakpoint(sourceCodeLocation); 20 20 WI.debuggerManager.addBreakpoint(breakpoint); 21 21 break; -
trunk/LayoutTests/inspector/debugger/probe-manager-add-remove-actions.html
r251485 r266074 34 34 var location = scriptObject.createSourceCodeLocation(4, 0); 35 35 // Create the breakpoint and its actions before sending anything to the backend. 36 var breakpoint = new WI. Breakpoint(location);36 var breakpoint = new WI.JavaScriptBreakpoint(location); 37 37 breakpoint.autoContinue = true; 38 38 for (var i of [0, 1]) 39 breakpoint.createAction(WI.BreakpointAction.Type.Probe, null, "a");39 breakpoint.createAction(WI.BreakpointAction.Type.Probe, {data: "a"}); 40 40 41 41 WI.debuggerManager.addBreakpoint(breakpoint); 42 42 43 breakpoint.addEventListener(WI. Breakpoint.Event.ResolvedStateDidChange, function() {43 breakpoint.addEventListener(WI.JavaScriptBreakpoint.Event.ResolvedStateDidChange, function() { 44 44 InspectorTest.expectThat(breakpoint.resolved, "Breakpoint should be resolved."); 45 45 }); -
trunk/LayoutTests/inspector/debugger/stepping/stepping-through-autoContinue-breakpoint.html
r236766 r266074 25 25 let script = WI.networkManager.mainFrame.mainResource.scripts[0]; 26 26 var location = script.createSourceCodeLocation(8, 0); 27 var breakpoint = new WI. Breakpoint(location);27 var breakpoint = new WI.JavaScriptBreakpoint(location); 28 28 breakpoint.autoContinue = true; 29 breakpoint.createAction(WI.BreakpointAction.Type.Evaluate, null, "alert(1.5);");29 breakpoint.createAction(WI.BreakpointAction.Type.Evaluate, {data: "alert(1.5);"}); 30 30 WI.debuggerManager.addBreakpoint(breakpoint); 31 31 -
trunk/LayoutTests/inspector/debugger/tail-deleted-frames-this-value.html
r249445 r266074 16 16 let testInfo = {line: 3, column: 4}; 17 17 let location = scriptObject.createSourceCodeLocation(testInfo.line, testInfo.column); 18 let breakpoint = new WI. Breakpoint(location);18 let breakpoint = new WI.JavaScriptBreakpoint(location); 19 19 WI.debuggerManager.addBreakpoint(breakpoint); 20 20 InspectorTest.evaluateInPage("startABC()"); -
trunk/LayoutTests/inspector/debugger/tail-recursion.html
r237571 r266074 25 25 for (let testInfo of testInfos) { 26 26 let location = scriptObject.createSourceCodeLocation(testInfo.line, testInfo.column); 27 let breakpoint = new WI. Breakpoint(location);27 let breakpoint = new WI.JavaScriptBreakpoint(location); 28 28 WI.debuggerManager.addBreakpoint(breakpoint); 29 29 } -
trunk/LayoutTests/inspector/dom-debugger/event-animation-frame-breakpoints-expected.txt
r248201 r266074 1 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 1 2 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 2 3 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 3 4 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 4 1 5 Tests for Event AnimationFrame breakpoints. 2 6 … … 4 8 == Running test suite: DOMDebugger.Event.AnimationFrame 5 9 -- Running test case: DOMDebugger.Event.AnimationFrame.AddBreakpoint 10 Creating "animation-frame" Event Breakpoint... 6 11 Adding "animation-frame" Event Breakpoint... 7 12 Firing "requestAnimationFrame" on window... … … 16 21 17 22 -- Running test case: DOMDebugger.Event.AnimationFrame.AddDisabledBreakpoint 23 Creating "animation-frame" Event Breakpoint... 18 24 Adding "animation-frame" Event Breakpoint... 19 25 Disabling "animation-frame" Event Breakpoint... … … 23 29 24 30 -- Running test case: DOMDebugger.Event.AnimationFrame.RemoveBreakpoint 31 Creating "animation-frame" Event Breakpoint... 25 32 Adding "animation-frame" Event Breakpoint... 26 33 Removing "animation-frame" Event Breakpoint... … … 30 37 31 38 -- Running test case: DOMDebugger.Event.AnimationFrame.RemoveDisabledBreakpoint 39 Creating "animation-frame" Event Breakpoint... 32 40 Adding "animation-frame" Event Breakpoint... 33 41 Disabling "animation-frame" Event Breakpoint... … … 37 45 -- Running test teardown. 38 46 47 -- Running test case: DOMDebugger.Event.AnimationFrame.Options.Condition 48 Creating "animation-frame" Event Breakpoint... 49 Adding "animation-frame" Event Breakpoint... 50 51 Setting condition to 'false'... 52 53 Triggering breakpoint... 54 PASS: Should not pause. 55 56 Triggering breakpoint... 57 PASS: Should not pause. 58 59 Setting condition to 'true'... 60 61 Triggering breakpoint... 62 PASS: Should pause. 63 64 Triggering breakpoint... 65 PASS: Should pause. 66 -- Running test teardown. 67 68 -- Running test case: DOMDebugger.Event.AnimationFrame.Options.IgnoreCount 69 Creating "animation-frame" Event Breakpoint... 70 Adding "animation-frame" Event Breakpoint... 71 72 Setting ignoreCount to '2'... 73 74 Triggering breakpoint... 75 PASS: Should not pause. 76 77 Triggering breakpoint... 78 PASS: Should not pause. 79 80 Triggering breakpoint... 81 PASS: Should pause. 82 83 Triggering breakpoint... 84 PASS: Should pause. 85 -- Running test teardown. 86 87 -- Running test case: DOMDebugger.Event.AnimationFrame.Options.Action.Log 88 Creating "animation-frame" Event Breakpoint... 89 Adding "animation-frame" Event Breakpoint... 90 91 Adding log action... 92 93 Triggering breakpoint... 94 PASS: Should execute breakpoint action. 95 PASS: Should pause. 96 97 Editing log action... 98 99 Triggering breakpoint... 100 PASS: Should execute breakpoint action. 101 PASS: Should pause. 102 103 Editing log action... 104 Enabling auto-continue... 105 106 Triggering breakpoint... 107 PASS: Should execute breakpoint action. 108 PASS: Should not pause. 109 110 Editing log action... 111 112 Triggering breakpoint... 113 PASS: Should execute breakpoint action. 114 PASS: Should not pause. 115 -- Running test teardown. 116 117 -- Running test case: DOMDebugger.Event.AnimationFrame.Options.Actions.Evaluate 118 Creating "animation-frame" Event Breakpoint... 119 Adding "animation-frame" Event Breakpoint... 120 121 Adding evaluate action... 122 123 Triggering breakpoint... 124 PASS: Should execute breakpoint action. 125 PASS: Should pause. 126 127 Editing evaluate action... 128 129 Triggering breakpoint... 130 PASS: Should execute breakpoint action. 131 PASS: Should pause. 132 133 Editing evaluate action... 134 Enabling auto-continue... 135 136 Triggering breakpoint... 137 PASS: Should execute breakpoint action. 138 PASS: Should not pause. 139 140 Editing evaluate action... 141 142 Triggering breakpoint... 143 PASS: Should execute breakpoint action. 144 PASS: Should not pause. 145 -- Running test teardown. 146 -
trunk/LayoutTests/inspector/dom-debugger/event-animation-frame-breakpoints.html
r248201 r266074 46 46 }); 47 47 48 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint)48 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.AnimationFrame) 49 49 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) 50 50 .catch(reject); … … 59 59 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.AnimationFrame, eventName, "Should not pause for disabled breakpoint."); 60 60 61 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint)61 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.AnimationFrame) 62 62 .then(InspectorTest.EventBreakpoint.disableBreakpoint) 63 63 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) … … 73 73 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.AnimationFrame, eventName, "Should not pause for removed breakpoint."); 74 74 75 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint)75 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.AnimationFrame) 76 76 .then(InspectorTest.EventBreakpoint.removeBreakpoint) 77 77 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) … … 87 87 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.AnimationFrame, eventName, "Should not pause for removed disabled breakpoint."); 88 88 89 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint)89 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.AnimationFrame) 90 90 .then(InspectorTest.EventBreakpoint.disableBreakpoint) 91 91 .then(InspectorTest.EventBreakpoint.removeBreakpoint) … … 95 95 teardown: InspectorTest.EventBreakpoint.teardown, 96 96 }); 97 98 InspectorTest.EventBreakpoint.addBreakpointOptionsTestCases(suite, WI.EventBreakpoint.Type.AnimationFrame, eventName); 97 99 98 100 suite.runTestCasesAndFinish(); -
trunk/LayoutTests/inspector/dom-debugger/event-interval-breakpoints-expected.txt
r248201 r266074 1 Tests for Event Timer breakpoints. 1 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 1 2 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 2 3 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 3 4 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 4 5 Tests for Event Interval breakpoints. 2 6 3 7 4 == Running test suite: DOMDebugger.Event. Timer8 == Running test suite: DOMDebugger.Event.Interval 5 9 -- Running test case: DOMDebugger.Event.Interval.AddBreakpoint 10 Creating "interval" Event Breakpoint... 6 11 Adding "interval" Event Breakpoint... 7 12 Firing "setInterval" on window... … … 16 21 17 22 -- Running test case: DOMDebugger.Event.Interval.AddDisabledBreakpoint 23 Creating "interval" Event Breakpoint... 18 24 Adding "interval" Event Breakpoint... 19 25 Disabling "interval" Event Breakpoint... … … 23 29 24 30 -- Running test case: DOMDebugger.Event.Interval.RemoveBreakpoint 31 Creating "interval" Event Breakpoint... 25 32 Adding "interval" Event Breakpoint... 26 33 Removing "interval" Event Breakpoint... … … 30 37 31 38 -- Running test case: DOMDebugger.Event.Interval.RemoveDisabledBreakpoint 39 Creating "interval" Event Breakpoint... 32 40 Adding "interval" Event Breakpoint... 33 41 Disabling "interval" Event Breakpoint... … … 38 46 39 47 -- Running test case: DOMDebugger.Event.Interval.RepeatFireBreakpoint 48 Creating "interval" Event Breakpoint... 40 49 Adding "interval" Event Breakpoint... 41 50 Firing "setInterval" on window... … … 56 65 -- Running test teardown. 57 66 67 -- Running test case: DOMDebugger.Event.Interval.Options.Condition 68 Creating "interval" Event Breakpoint... 69 Adding "interval" Event Breakpoint... 70 71 Setting condition to 'false'... 72 73 Triggering breakpoint... 74 PASS: Should not pause. 75 76 Triggering breakpoint... 77 PASS: Should not pause. 78 79 Setting condition to 'true'... 80 81 Triggering breakpoint... 82 PASS: Should pause. 83 84 Triggering breakpoint... 85 PASS: Should pause. 86 -- Running test teardown. 87 88 -- Running test case: DOMDebugger.Event.Interval.Options.IgnoreCount 89 Creating "interval" Event Breakpoint... 90 Adding "interval" Event Breakpoint... 91 92 Setting ignoreCount to '2'... 93 94 Triggering breakpoint... 95 PASS: Should not pause. 96 97 Triggering breakpoint... 98 PASS: Should not pause. 99 100 Triggering breakpoint... 101 PASS: Should pause. 102 103 Triggering breakpoint... 104 PASS: Should pause. 105 -- Running test teardown. 106 107 -- Running test case: DOMDebugger.Event.Interval.Options.Action.Log 108 Creating "interval" Event Breakpoint... 109 Adding "interval" Event Breakpoint... 110 111 Adding log action... 112 113 Triggering breakpoint... 114 PASS: Should execute breakpoint action. 115 PASS: Should pause. 116 117 Editing log action... 118 119 Triggering breakpoint... 120 PASS: Should execute breakpoint action. 121 PASS: Should pause. 122 123 Editing log action... 124 Enabling auto-continue... 125 126 Triggering breakpoint... 127 PASS: Should execute breakpoint action. 128 PASS: Should not pause. 129 130 Editing log action... 131 132 Triggering breakpoint... 133 PASS: Should execute breakpoint action. 134 PASS: Should not pause. 135 -- Running test teardown. 136 137 -- Running test case: DOMDebugger.Event.Interval.Options.Actions.Evaluate 138 Creating "interval" Event Breakpoint... 139 Adding "interval" Event Breakpoint... 140 141 Adding evaluate action... 142 143 Triggering breakpoint... 144 PASS: Should execute breakpoint action. 145 PASS: Should pause. 146 147 Editing evaluate action... 148 149 Triggering breakpoint... 150 PASS: Should execute breakpoint action. 151 PASS: Should pause. 152 153 Editing evaluate action... 154 Enabling auto-continue... 155 156 Triggering breakpoint... 157 PASS: Should execute breakpoint action. 158 PASS: Should not pause. 159 160 Editing evaluate action... 161 162 Triggering breakpoint... 163 PASS: Should execute breakpoint action. 164 PASS: Should not pause. 165 -- Running test teardown. 166 -
trunk/LayoutTests/inspector/dom-debugger/event-interval-breakpoints.html
r248201 r266074 10 10 11 11 function handleWindow_setInterval() { 12 repeatClearInterval(); 13 12 14 TestPage.dispatchEventToFrontend("TestPage-setInterval"); 13 14 repeatClearInterval();15 15 } 16 16 … … 19 19 20 20 function trigger_setInterval() { 21 intervalID = setInterval(handleWindow_setInterval, 10 0);21 intervalID = setInterval(handleWindow_setInterval, 10); 22 22 } 23 23 24 24 function repeatSetInterval() { 25 intervalID = setInterval(handleRepeat, 10 0);25 intervalID = setInterval(handleRepeat, 10); 26 26 } 27 27 … … 34 34 const eventName = "setInterval"; 35 35 36 let suite = InspectorTest.createAsyncSuite("DOMDebugger.Event. Timer");36 let suite = InspectorTest.createAsyncSuite("DOMDebugger.Event.Interval"); 37 37 38 38 suite.addTestCase({ … … 62 62 }); 63 63 64 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint)64 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Interval) 65 65 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) 66 66 .catch(reject); … … 75 75 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Interval, eventName, "Should not pause for disabled breakpoint."); 76 76 77 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint)77 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Interval) 78 78 .then(InspectorTest.EventBreakpoint.disableBreakpoint) 79 79 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) … … 89 89 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Interval, eventName, "Should not pause for removed breakpoint."); 90 90 91 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint)91 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Interval) 92 92 .then(InspectorTest.EventBreakpoint.removeBreakpoint) 93 93 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) … … 103 103 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Interval, eventName, "Should not pause for removed disabled breakpoint."); 104 104 105 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint)105 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Interval) 106 106 .then(InspectorTest.EventBreakpoint.disableBreakpoint) 107 107 .then(InspectorTest.EventBreakpoint.removeBreakpoint) … … 135 135 }); 136 136 137 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint)137 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Interval) 138 138 .then(() => { 139 139 InspectorTest.log("Firing \"setInterval\" on window..."); … … 145 145 }); 146 146 147 InspectorTest.EventBreakpoint.addBreakpointOptionsTestCases(suite, WI.EventBreakpoint.Type.Interval, eventName); 148 147 149 suite.runTestCasesAndFinish(); 148 150 } … … 150 152 </head> 151 153 <body onload="runTest()"> 152 <p>Tests for Event Timerbreakpoints.</p>154 <p>Tests for Event Interval breakpoints.</p> 153 155 </body> 154 156 </html> -
trunk/LayoutTests/inspector/dom-debugger/event-listener-breakpoints-expected.txt
r248201 r266074 1 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 1 2 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 2 3 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 3 4 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 4 1 5 Tests for Event Listener breakpoints. 2 6 … … 76 80 77 81 -- Running test case: DOMDebugger.Event.Listener.AllEventsBreakpoint 82 Creating "listener" Event Breakpoint... 78 83 Adding "listener" Event Breakpoint... 79 84 Firing "click" on body... … … 122 127 -- Running test teardown. 123 128 129 -- Running test case: DOMDebugger.Event.Listener.Options.Condition 130 Creating "click" Event Breakpoint... 131 Adding "listener:click" Event Breakpoint... 132 133 Setting condition to 'false'... 134 135 Triggering breakpoint... 136 PASS: Should not pause. 137 138 Triggering breakpoint... 139 PASS: Should not pause. 140 141 Setting condition to 'true'... 142 143 Triggering breakpoint... 144 PASS: Should pause. 145 146 Triggering breakpoint... 147 PASS: Should pause. 148 -- Running test teardown. 149 150 -- Running test case: DOMDebugger.Event.Listener.Options.IgnoreCount 151 Creating "click" Event Breakpoint... 152 Adding "listener:click" Event Breakpoint... 153 154 Setting ignoreCount to '2'... 155 156 Triggering breakpoint... 157 PASS: Should not pause. 158 159 Triggering breakpoint... 160 PASS: Should not pause. 161 162 Triggering breakpoint... 163 PASS: Should pause. 164 165 Triggering breakpoint... 166 PASS: Should pause. 167 -- Running test teardown. 168 169 -- Running test case: DOMDebugger.Event.Listener.Options.Action.Log 170 Creating "click" Event Breakpoint... 171 Adding "listener:click" Event Breakpoint... 172 173 Adding log action... 174 175 Triggering breakpoint... 176 PASS: Should execute breakpoint action. 177 PASS: Should pause. 178 179 Editing log action... 180 181 Triggering breakpoint... 182 PASS: Should execute breakpoint action. 183 PASS: Should pause. 184 185 Editing log action... 186 Enabling auto-continue... 187 188 Triggering breakpoint... 189 PASS: Should execute breakpoint action. 190 PASS: Should not pause. 191 192 Editing log action... 193 194 Triggering breakpoint... 195 PASS: Should execute breakpoint action. 196 PASS: Should not pause. 197 -- Running test teardown. 198 199 -- Running test case: DOMDebugger.Event.Listener.Options.Actions.Evaluate 200 Creating "click" Event Breakpoint... 201 Adding "listener:click" Event Breakpoint... 202 203 Adding evaluate action... 204 205 Triggering breakpoint... 206 PASS: Should execute breakpoint action. 207 PASS: Should pause. 208 209 Editing evaluate action... 210 211 Triggering breakpoint... 212 PASS: Should execute breakpoint action. 213 PASS: Should pause. 214 215 Editing evaluate action... 216 Enabling auto-continue... 217 218 Triggering breakpoint... 219 PASS: Should execute breakpoint action. 220 PASS: Should not pause. 221 222 Editing evaluate action... 223 224 Triggering breakpoint... 225 PASS: Should execute breakpoint action. 226 PASS: Should not pause. 227 -- Running test teardown. 228 -
trunk/LayoutTests/inspector/dom-debugger/event-listener-breakpoints.html
r248201 r266074 59 59 }); 60 60 61 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, eventName)61 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, {eventName}) 62 62 .then(InspectorTest.EventBreakpoint.awaitEvent("body", eventName)) 63 63 .catch(reject); … … 72 72 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Listener, eventName, "Should not pause for disabled breakpoint."); 73 73 74 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, eventName)74 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, {eventName}) 75 75 .then(InspectorTest.EventBreakpoint.disableBreakpoint) 76 76 .then(InspectorTest.EventBreakpoint.awaitEvent("body", eventName)) … … 86 86 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Listener, eventName, "Should not pause for removed breakpoint."); 87 87 88 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, eventName)88 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, {eventName}) 89 89 .then(InspectorTest.EventBreakpoint.removeBreakpoint) 90 90 .then(InspectorTest.EventBreakpoint.awaitEvent("body", eventName)) … … 100 100 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Listener, eventName, "Should not pause for removed disabled breakpoint."); 101 101 102 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, eventName)102 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, {eventName}) 103 103 .then(InspectorTest.EventBreakpoint.disableBreakpoint) 104 104 .then(InspectorTest.EventBreakpoint.removeBreakpoint) … … 129 129 }); 130 130 131 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allListenersBreakpoint)131 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener) 132 132 .then(() => { 133 133 InspectorTest.log("Firing \"click\" on body..."); … … 174 174 }); 175 175 176 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, "click")176 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, {eventName: "click"}) 177 177 .then(() => { 178 178 InspectorTest.log("Firing \"click\" on div#x..."); … … 212 212 }); 213 213 214 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, "click")214 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Listener, {eventName: "click"}) 215 215 .then(() => { 216 216 InspectorTest.log("Firing \"click\" on div#x..."); … … 221 221 teardown: InspectorTest.EventBreakpoint.teardown, 222 222 }); 223 224 InspectorTest.EventBreakpoint.addBreakpointOptionsTestCases(suite, WI.EventBreakpoint.Type.Listener, "click"); 223 225 224 226 suite.runTestCasesAndFinish(); -
trunk/LayoutTests/inspector/dom-debugger/event-timeout-breakpoints-expected.txt
r248201 r266074 1 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 1 2 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 2 3 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 3 4 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 4 1 5 Tests for Event Timer breakpoints. 2 6 … … 4 8 == Running test suite: DOMDebugger.Event.Timer 5 9 -- Running test case: DOMDebugger.Event.Timeout.AddBreakpoint 10 Creating "timeout" Event Breakpoint... 6 11 Adding "timeout" Event Breakpoint... 7 12 Firing "setTimeout" on window... … … 16 21 17 22 -- Running test case: DOMDebugger.Event.Timeout.AddDisabledBreakpoint 23 Creating "timeout" Event Breakpoint... 18 24 Adding "timeout" Event Breakpoint... 19 25 Disabling "timeout" Event Breakpoint... … … 23 29 24 30 -- Running test case: DOMDebugger.Event.Timeout.RemoveBreakpoint 31 Creating "timeout" Event Breakpoint... 25 32 Adding "timeout" Event Breakpoint... 26 33 Removing "timeout" Event Breakpoint... … … 30 37 31 38 -- Running test case: DOMDebugger.Event.Timeout.RemoveDisabledBreakpoint 39 Creating "timeout" Event Breakpoint... 32 40 Adding "timeout" Event Breakpoint... 33 41 Disabling "timeout" Event Breakpoint... … … 37 45 -- Running test teardown. 38 46 47 -- Running test case: DOMDebugger.Event.Timer.Options.Condition 48 Creating "timeout" Event Breakpoint... 49 Adding "timeout" Event Breakpoint... 50 51 Setting condition to 'false'... 52 53 Triggering breakpoint... 54 PASS: Should not pause. 55 56 Triggering breakpoint... 57 PASS: Should not pause. 58 59 Setting condition to 'true'... 60 61 Triggering breakpoint... 62 PASS: Should pause. 63 64 Triggering breakpoint... 65 PASS: Should pause. 66 -- Running test teardown. 67 68 -- Running test case: DOMDebugger.Event.Timer.Options.IgnoreCount 69 Creating "timeout" Event Breakpoint... 70 Adding "timeout" Event Breakpoint... 71 72 Setting ignoreCount to '2'... 73 74 Triggering breakpoint... 75 PASS: Should not pause. 76 77 Triggering breakpoint... 78 PASS: Should not pause. 79 80 Triggering breakpoint... 81 PASS: Should pause. 82 83 Triggering breakpoint... 84 PASS: Should pause. 85 -- Running test teardown. 86 87 -- Running test case: DOMDebugger.Event.Timer.Options.Action.Log 88 Creating "timeout" Event Breakpoint... 89 Adding "timeout" Event Breakpoint... 90 91 Adding log action... 92 93 Triggering breakpoint... 94 PASS: Should execute breakpoint action. 95 PASS: Should pause. 96 97 Editing log action... 98 99 Triggering breakpoint... 100 PASS: Should execute breakpoint action. 101 PASS: Should pause. 102 103 Editing log action... 104 Enabling auto-continue... 105 106 Triggering breakpoint... 107 PASS: Should execute breakpoint action. 108 PASS: Should not pause. 109 110 Editing log action... 111 112 Triggering breakpoint... 113 PASS: Should execute breakpoint action. 114 PASS: Should not pause. 115 -- Running test teardown. 116 117 -- Running test case: DOMDebugger.Event.Timer.Options.Actions.Evaluate 118 Creating "timeout" Event Breakpoint... 119 Adding "timeout" Event Breakpoint... 120 121 Adding evaluate action... 122 123 Triggering breakpoint... 124 PASS: Should execute breakpoint action. 125 PASS: Should pause. 126 127 Editing evaluate action... 128 129 Triggering breakpoint... 130 PASS: Should execute breakpoint action. 131 PASS: Should pause. 132 133 Editing evaluate action... 134 Enabling auto-continue... 135 136 Triggering breakpoint... 137 PASS: Should execute breakpoint action. 138 PASS: Should not pause. 139 140 Editing evaluate action... 141 142 Triggering breakpoint... 143 PASS: Should execute breakpoint action. 144 PASS: Should not pause. 145 -- Running test teardown. 146 -
trunk/LayoutTests/inspector/dom-debugger/event-timeout-breakpoints.html
r248201 r266074 12 12 13 13 function trigger_setTimeout() { 14 setTimeout(handleWindow_setTimeout, 10 0);14 setTimeout(handleWindow_setTimeout, 10); 15 15 } 16 16 … … 46 46 }); 47 47 48 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint)48 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Timeout) 49 49 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) 50 50 .catch(reject); … … 59 59 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Timeout, eventName, "Should not pause for disabled breakpoint."); 60 60 61 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint)61 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Timeout) 62 62 .then(InspectorTest.EventBreakpoint.disableBreakpoint) 63 63 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) … … 73 73 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Timeout, eventName, "Should not pause for removed breakpoint."); 74 74 75 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint)75 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Timeout) 76 76 .then(InspectorTest.EventBreakpoint.removeBreakpoint) 77 77 .then(InspectorTest.EventBreakpoint.awaitEvent("window", eventName)) … … 87 87 InspectorTest.EventBreakpoint.failOnPause(resolve, reject, WI.DebuggerManager.PauseReason.Timeout, eventName, "Should not pause for removed disabled breakpoint."); 88 88 89 InspectorTest.EventBreakpoint. addBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint)89 InspectorTest.EventBreakpoint.createBreakpoint(WI.EventBreakpoint.Type.Timeout) 90 90 .then(InspectorTest.EventBreakpoint.disableBreakpoint) 91 91 .then(InspectorTest.EventBreakpoint.removeBreakpoint) … … 95 95 teardown: InspectorTest.EventBreakpoint.teardown, 96 96 }); 97 98 InspectorTest.EventBreakpoint.addBreakpointOptionsTestCases(suite, WI.EventBreakpoint.Type.Timeout, eventName); 97 99 98 100 suite.runTestCasesAndFinish(); -
trunk/LayoutTests/inspector/dom-debugger/resources/event-breakpoint-utilities.js
r248201 r266074 2 2 InspectorTest.EventBreakpoint = {}; 3 3 4 InspectorTest.EventBreakpoint.addBreakpointOptionsTestCases = function(suite, type, eventName) { 5 async function triggerBreakpoint() { 6 InspectorTest.log("Triggering breakpoint..."); 7 return Promise.all([ 8 InspectorTest.awaitEvent("TestPage-" + eventName), 9 InspectorTest.evaluateInPage(`trigger_${eventName}()`), 10 ]); 11 } 12 13 suite.addTestCase({ 14 name: suite.name + ".Options.Condition", 15 description: "Check that the debugger will not pause unless the breakpoint has a truthy breakpoint condition.", 16 async test() { 17 let pauseCount = 0; 18 19 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => { 20 ++pauseCount; 21 WI.debuggerManager.resume(); 22 }); 23 24 let breakpoint = await InspectorTest.EventBreakpoint.createBreakpoint(type, {eventName}); 25 26 InspectorTest.newline(); 27 28 InspectorTest.log("Setting condition to 'false'..."); 29 breakpoint.condition = "false"; 30 31 for (let i = 1; i <= 4; ++i) { 32 if (i === 3) { 33 InspectorTest.newline(); 34 35 InspectorTest.log("Setting condition to 'true'..."); 36 breakpoint.condition = "true"; 37 } 38 39 InspectorTest.newline(); 40 41 await triggerBreakpoint(); 42 43 if (i <= 2) 44 InspectorTest.expectEqual(pauseCount, 0, "Should not pause."); 45 else 46 InspectorTest.expectEqual(pauseCount, i - 2, "Should pause."); 47 } 48 49 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener); 50 }, 51 teardown: InspectorTest.EventBreakpoint.teardown, 52 }); 53 54 suite.addTestCase({ 55 name: suite.name + ".Options.IgnoreCount", 56 description: "Check that the debugger will not pause unless the breakpoint is hit at least as many times as it's `ignoreCount`.", 57 async test() { 58 let pauseCount = 0; 59 60 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => { 61 ++pauseCount; 62 WI.debuggerManager.resume(); 63 }); 64 65 let breakpoint = await InspectorTest.EventBreakpoint.createBreakpoint(type, {eventName}); 66 67 InspectorTest.newline(); 68 69 InspectorTest.log("Setting ignoreCount to '2'..."); 70 breakpoint.ignoreCount = 2; 71 72 for (let i = 1; i <=4; ++i) { 73 InspectorTest.newline(); 74 75 await triggerBreakpoint(); 76 77 if (i <= 2) 78 InspectorTest.expectEqual(pauseCount, 0, "Should not pause."); 79 else 80 InspectorTest.expectEqual(pauseCount, i - 2, "Should pause."); 81 } 82 83 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener); 84 }, 85 teardown: InspectorTest.EventBreakpoint.teardown, 86 }); 87 88 suite.addTestCase({ 89 name: suite.name + ".Options.Action.Log", 90 description: "Check that log breakpoint actions execute when the breakpoint is hit.", 91 async test() { 92 let pauseCount = 0; 93 94 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => { 95 ++pauseCount; 96 WI.debuggerManager.resume(); 97 }); 98 99 let breakpoint = await InspectorTest.EventBreakpoint.createBreakpoint(type, {eventName}); 100 101 InspectorTest.newline(); 102 103 InspectorTest.log("Adding log action..."); 104 let action = breakpoint.createAction(WI.BreakpointAction.Type.Log, {data: "BREAKPOINT ACTION LOG 1"}); 105 106 for (let i = 1; i <= 4; ++i) { 107 if (i > 1) { 108 InspectorTest.newline(); 109 110 InspectorTest.log("Editing log action..."); 111 action.data = `BREAKPOINT ACTION LOG ${i}`; 112 113 if (i === 3) { 114 InspectorTest.log("Enabling auto-continue..."); 115 breakpoint.autoContinue = true; 116 } 117 } 118 119 InspectorTest.newline(); 120 121 let [messageAddedEvent] = await Promise.all([ 122 WI.consoleManager.awaitEvent(WI.ConsoleManager.Event.MessageAdded), 123 triggerBreakpoint(), 124 ]); 125 126 InspectorTest.expectEqual(messageAddedEvent.data.message.messageText, action.data, "Should execute breakpoint action."); 127 128 if (i <= 2) 129 InspectorTest.expectEqual(pauseCount, i, "Should pause."); 130 else 131 InspectorTest.expectEqual(pauseCount, 2, "Should not pause."); 132 } 133 134 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener); 135 }, 136 teardown: InspectorTest.EventBreakpoint.teardown, 137 }); 138 139 suite.addTestCase({ 140 name: suite.name + ".Options.Actions.Evaluate", 141 description: "Check that evaluate breakpoint actions execute when the breakpoint is hit.", 142 async test() { 143 let pauseCount = 0; 144 145 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => { 146 ++pauseCount; 147 WI.debuggerManager.resume(); 148 }); 149 150 let breakpoint = await InspectorTest.EventBreakpoint.createBreakpoint(type, {eventName}); 151 152 InspectorTest.newline(); 153 154 InspectorTest.log("Adding evaluate action..."); 155 let action = breakpoint.createAction(WI.BreakpointAction.Type.Evaluate, {data: "window.BREAKPOINT_ACTION_EVALUATE = 1;"}); 156 157 for (let i = 1; i <= 4; ++i) { 158 if (i > 1) { 159 InspectorTest.newline(); 160 161 InspectorTest.log("Editing evaluate action..."); 162 action.data = `window.BREAKPOINT_ACTION_EVALUATE = ${i};`; 163 164 if (i === 3) { 165 InspectorTest.log("Enabling auto-continue..."); 166 breakpoint.autoContinue = true; 167 } 168 } 169 170 InspectorTest.newline(); 171 172 await triggerBreakpoint(); 173 174 let breakpointActionEvaluateResult = await InspectorTest.evaluateInPage(`window.BREAKPOINT_ACTION_EVALUATE`); 175 InspectorTest.expectEqual(breakpointActionEvaluateResult, i, "Should execute breakpoint action."); 176 177 if (i <= 2) 178 InspectorTest.expectEqual(pauseCount, i, "Should pause."); 179 else 180 InspectorTest.expectEqual(pauseCount, 2, "Should not pause."); 181 } 182 183 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener); 184 }, 185 teardown: InspectorTest.EventBreakpoint.teardown, 186 }); 187 }; 188 4 189 InspectorTest.EventBreakpoint.teardown = function(resolve, reject) { 5 WI.domDebuggerManager. removeEventBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint);6 WI.domDebuggerManager. removeEventBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint);7 WI.domDebuggerManager. removeEventBreakpoint(WI.domDebuggerManager.allListenersBreakpoint);8 WI.domDebuggerManager. removeEventBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint);190 WI.domDebuggerManager.allAnimationFramesBreakpoint?.remove(); 191 WI.domDebuggerManager.allIntervalsBreakpoint?.remove(); 192 WI.domDebuggerManager.allListenersBreakpoint?.remove(); 193 WI.domDebuggerManager.allTimeoutsBreakpoint?.remove(); 9 194 10 195 for (let breakpoint of WI.domDebuggerManager.listenerBreakpoints) 11 WI.domDebuggerManager.removeEventBreakpoint(breakpoint);196 breakpoint.remove(); 12 197 13 198 resolve(); … … 43 228 }; 44 229 45 InspectorTest.EventBreakpoint.createBreakpoint = function(type, eventName) { 46 InspectorTest.log(`Creating "${eventName}" Event Breakpoint...`); 230 InspectorTest.EventBreakpoint.createBreakpoint = function(type, {eventName} = {}) { 231 if (type !== WI.EventBreakpoint.Type.Listener) 232 eventName = null; 233 234 InspectorTest.log(`Creating "${eventName || type}" Event Breakpoint...`); 47 235 return InspectorTest.EventBreakpoint.addBreakpoint(new WI.EventBreakpoint(type, {eventName})); 48 236 }; … … 75 263 }); 76 264 77 WI.domDebuggerManager.removeEventBreakpoint(breakpoint);265 breakpoint.remove(); 78 266 }); 79 267 }; -
trunk/LayoutTests/inspector/dom/breakpoint-for-event-listener-expected.txt
r249128 r266074 1 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 1 2 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 2 3 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 3 4 CONSOLE MESSAGE: BREAKPOINT ACTION LOG 4 1 5 Testing DOMAgent.setBreakpointForEventListener and DOMAgent.removeBreakpointForEventListener. 2 6 … … 20 24 PASS: Should not pause before button1 event handler is run. 21 25 26 -- Running test case: DOM.setBreakpointForEventListener.Options.Condition 27 28 Setting condition to 'false'... 29 30 Triggering breakpoint... 31 PASS: Should not pause. 32 33 Triggering breakpoint... 34 PASS: Should not pause. 35 36 Setting condition to 'true'... 37 38 Triggering breakpoint... 39 PASS: Should pause. 40 41 Triggering breakpoint... 42 PASS: Should pause. 43 44 -- Running test case: DOM.setBreakpointForEventListener.Options.IgnoreCount 45 46 Setting ignoreCount to '2'... 47 48 Triggering breakpoint... 49 PASS: Should not pause. 50 51 Triggering breakpoint... 52 PASS: Should not pause. 53 54 Triggering breakpoint... 55 PASS: Should pause. 56 57 Triggering breakpoint... 58 PASS: Should pause. 59 60 -- Running test case: DOM.setBreakpointForEventListener.Options.Action.Log 61 62 Adding log action... 63 64 Triggering breakpoint... 65 PASS: Should execute breakpoint action. 66 PASS: Should pause. 67 68 Editing log action... 69 70 Triggering breakpoint... 71 PASS: Should execute breakpoint action. 72 PASS: Should pause. 73 74 Editing log action... 75 Enabling auto-continue... 76 77 Triggering breakpoint... 78 PASS: Should execute breakpoint action. 79 PASS: Should not pause. 80 81 Editing log action... 82 83 Triggering breakpoint... 84 PASS: Should execute breakpoint action. 85 PASS: Should not pause. 86 87 -- Running test case: DOM.setBreakpointForEventListener.Options.Actions.Evaluate 88 89 Adding evaluate action... 90 91 Triggering breakpoint... 92 PASS: Should execute breakpoint action. 93 PASS: Should pause. 94 95 Editing evaluate action... 96 97 Triggering breakpoint... 98 PASS: Should execute breakpoint action. 99 PASS: Should pause. 100 101 Editing evaluate action... 102 Enabling auto-continue... 103 104 Triggering breakpoint... 105 PASS: Should execute breakpoint action. 106 PASS: Should not pause. 107 108 Editing evaluate action... 109 110 Triggering breakpoint... 111 PASS: Should execute breakpoint action. 112 PASS: Should not pause. 113 22 114 -- Running test case: DOM.setBreakpointForEventListener.Invalid 23 115 PASS: Should produce an error. -
trunk/LayoutTests/inspector/dom/breakpoint-for-event-listener.html
r253242 r266074 24 24 let button2Node = null; 25 25 26 function awaitGetClickEventListener(nodeId) { 27 return DOMAgent.getEventListenersForNode(nodeId) 28 .then(({listeners}) => listeners.find((eventListener) => eventListener.type === "click")); 26 async function getClickEventListener(nodeId) { 27 let {listeners} = await DOMAgent.getEventListenersForNode(nodeId); 28 return listeners.find((eventListener) => eventListener.type === "click"); 29 } 30 31 async function setBreakpointForClickEventListener(node) { 32 let clickEventListener = await getClickEventListener(node.id); 33 InspectorTest.assert(!clickEventListener.hasBreakpoint, "Click event listener for button1 should not have a breakpoint."); 34 35 return new Promise((resolve, reject) => { 36 WI.domDebuggerManager.singleFireEventListener(WI.DOMDebuggerManager.Event.EventBreakpointAdded, (event) => { 37 resolve(event.data.breakpoint); 38 }); 39 40 WI.domManager.setBreakpointForEventListener(clickEventListener); 41 }); 29 42 } 30 43 … … 50 63 InspectorTest.expectEqual(targetData.pauseData.eventName, "click", `Pause data eventName should be "click".`); 51 64 52 awaitGetClickEventListener(button1Node.id)65 getClickEventListener(button1Node.id) 53 66 .then((clickEventListener) => { 54 67 InspectorTest.assert(targetData.pauseData.eventListenerId === clickEventListener.eventListenerId, `Pause data eventListenerId should be "${clickEventListener.eventListenerId}".`); … … 78 91 }); 79 92 80 awaitGetClickEventListener(button1Node.id)93 getClickEventListener(button1Node.id) 81 94 .then((clickEventListener) => { 82 95 InspectorTest.assert(!clickEventListener.hasBreakpoint, "Click event listener for button1 should not have a breakpoint."); … … 112 125 InspectorTest.assert(targetData.pauseData.eventName, "click", `Pause data eventName should be "click".`); 113 126 114 awaitGetClickEventListener(button1Node.id)127 getClickEventListener(button1Node.id) 115 128 .then((clickEventListener) => { 116 129 InspectorTest.assert(targetData.pauseData.eventListenerId === clickEventListener.eventListenerId, `Pause data eventListenerId should be "${clickEventListener.eventListenerId}".`); … … 140 153 }); 141 154 142 awaitGetClickEventListener(button1Node.id)155 getClickEventListener(button1Node.id) 143 156 .then((clickEventListener) => { 144 157 InspectorTest.assert(clickEventListener.hasBreakpoint, "Click event listener for button1 should have a breakpoint."); … … 153 166 .catch(reject); 154 167 } 168 }); 169 170 suite.addTestCase({ 171 name: "DOM.setBreakpointForEventListener.Options.Condition", 172 description: "Check that the debugger will not pause unless the breakpoint has a truthy breakpoint condition.", 173 async test() { 174 let pauseCount = 0; 175 176 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => { 177 ++pauseCount; 178 WI.debuggerManager.resume(); 179 }); 180 181 let breakpoint = await setBreakpointForClickEventListener(button1Node); 182 183 InspectorTest.newline(); 184 185 InspectorTest.log("Setting condition to 'false'..."); 186 breakpoint.condition = "false"; 187 188 for (let i = 1; i <= 4; ++i) { 189 if (i === 3) { 190 InspectorTest.newline(); 191 192 InspectorTest.log("Setting condition to 'true'..."); 193 breakpoint.condition = "true"; 194 } 195 196 InspectorTest.newline(); 197 198 InspectorTest.log("Triggering breakpoint..."); 199 await Promise.all([ 200 InspectorTest.awaitEvent("TestPageButton1Click"), 201 InspectorTest.evaluateInPage(`clickButton1()`), 202 ]); 203 204 if (i <= 2) 205 InspectorTest.expectEqual(pauseCount, 0, "Should not pause."); 206 else 207 InspectorTest.expectEqual(pauseCount, i - 2, "Should pause."); 208 } 209 210 breakpoint.remove(); 211 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener); 212 }, 213 }); 214 215 suite.addTestCase({ 216 name: "DOM.setBreakpointForEventListener.Options.IgnoreCount", 217 description: "Check that the debugger will not pause unless the breakpoint is hit at least as many times as it's `ignoreCount`.", 218 async test() { 219 let pauseCount = 0; 220 221 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => { 222 ++pauseCount; 223 WI.debuggerManager.resume(); 224 }); 225 226 let breakpoint = await setBreakpointForClickEventListener(button1Node); 227 228 InspectorTest.newline(); 229 230 InspectorTest.log("Setting ignoreCount to '2'..."); 231 breakpoint.ignoreCount = 2; 232 233 for (let i = 1; i <=4; ++i) { 234 InspectorTest.newline(); 235 236 InspectorTest.log("Triggering breakpoint..."); 237 await Promise.all([ 238 InspectorTest.awaitEvent("TestPageButton1Click"), 239 InspectorTest.evaluateInPage(`clickButton1()`), 240 ]); 241 242 if (i <= 2) 243 InspectorTest.expectEqual(pauseCount, 0, "Should not pause."); 244 else 245 InspectorTest.expectEqual(pauseCount, i - 2, "Should pause."); 246 } 247 248 breakpoint.remove(); 249 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener); 250 }, 251 }); 252 253 suite.addTestCase({ 254 name: "DOM.setBreakpointForEventListener.Options.Action.Log", 255 description: "Check that log breakpoint actions execute when the breakpoint is hit.", 256 async test() { 257 let pauseCount = 0; 258 259 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => { 260 ++pauseCount; 261 WI.debuggerManager.resume(); 262 }); 263 264 let breakpoint = await setBreakpointForClickEventListener(button1Node); 265 266 InspectorTest.newline(); 267 268 InspectorTest.log("Adding log action..."); 269 let action = breakpoint.createAction(WI.BreakpointAction.Type.Log, {data: "BREAKPOINT ACTION LOG 1"}); 270 271 for (let i = 1; i <= 4; ++i) { 272 if (i > 1) { 273 InspectorTest.newline(); 274 275 InspectorTest.log("Editing log action..."); 276 action.data = `BREAKPOINT ACTION LOG ${i}`; 277 278 if (i === 3) { 279 InspectorTest.log("Enabling auto-continue..."); 280 breakpoint.autoContinue = true; 281 } 282 } 283 284 InspectorTest.newline(); 285 286 InspectorTest.log("Triggering breakpoint..."); 287 let [messageAddedEvent] = await Promise.all([ 288 WI.consoleManager.awaitEvent(WI.ConsoleManager.Event.MessageAdded), 289 InspectorTest.awaitEvent("TestPageButton1Click"), 290 InspectorTest.evaluateInPage(`clickButton1()`), 291 ]); 292 293 InspectorTest.expectEqual(messageAddedEvent.data.message.messageText, action.data, "Should execute breakpoint action."); 294 295 if (i <= 2) 296 InspectorTest.expectEqual(pauseCount, i, "Should pause."); 297 else 298 InspectorTest.expectEqual(pauseCount, 2, "Should not pause."); 299 } 300 301 breakpoint.remove(); 302 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener); 303 }, 304 }); 305 306 suite.addTestCase({ 307 name: "DOM.setBreakpointForEventListener.Options.Actions.Evaluate", 308 description: "Check that evaluate breakpoint actions execute when the breakpoint is hit.", 309 async test() { 310 let pauseCount = 0; 311 312 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => { 313 ++pauseCount; 314 WI.debuggerManager.resume(); 315 }); 316 317 let breakpoint = await setBreakpointForClickEventListener(button1Node); 318 319 InspectorTest.newline(); 320 321 InspectorTest.log("Adding evaluate action..."); 322 let action = breakpoint.createAction(WI.BreakpointAction.Type.Evaluate, {data: "window.BREAKPOINT_ACTION_EVALUATE = 1;"}); 323 324 for (let i = 1; i <= 4; ++i) { 325 if (i > 1) { 326 InspectorTest.newline(); 327 328 InspectorTest.log("Editing evaluate action..."); 329 action.data = `window.BREAKPOINT_ACTION_EVALUATE = ${i};`; 330 331 if (i === 3) { 332 InspectorTest.log("Enabling auto-continue..."); 333 breakpoint.autoContinue = true; 334 } 335 } 336 337 InspectorTest.newline(); 338 339 InspectorTest.log("Triggering breakpoint..."); 340 await Promise.all([ 341 InspectorTest.awaitEvent("TestPageButton1Click"), 342 InspectorTest.evaluateInPage(`clickButton1()`), 343 ]); 344 345 let breakpointActionEvaluateResult = await InspectorTest.evaluateInPage(`window.BREAKPOINT_ACTION_EVALUATE`); 346 InspectorTest.expectEqual(breakpointActionEvaluateResult, i, "Should execute breakpoint action."); 347 348 if (i <= 2) 349 InspectorTest.expectEqual(pauseCount, i, "Should pause."); 350 else 351 InspectorTest.expectEqual(pauseCount, 2, "Should not pause."); 352 } 353 354 breakpoint.remove(); 355 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener); 356 }, 155 357 }); 156 358 -
trunk/LayoutTests/inspector/worker/debugger-pause.html
r251227 r266074 64 64 test(resolve, reject) { 65 65 let location = workerTarget.mainResource.createSourceCodeLocation(8, 0); 66 let breakpoint = new WI. Breakpoint(location);66 let breakpoint = new WI.JavaScriptBreakpoint(location); 67 67 WI.debuggerManager.addBreakpoint(breakpoint); 68 68 InspectorTest.evaluateInPage(`worker.postMessage("triggerBreakpoint")`); -
trunk/LayoutTests/inspector/worker/debugger-shared-breakpoint.html
r251227 r266074 95 95 InspectorTest.assert(workerTarget1.mainResource instanceof WI.Script); 96 96 let location = workerTarget1.mainResource.createSourceCodeLocation(8, 0); 97 breakpoint = new WI. Breakpoint(location);97 breakpoint = new WI.JavaScriptBreakpoint(location); 98 98 WI.debuggerManager.addBreakpoint(breakpoint); 99 99 -
trunk/Source/JavaScriptCore/CMakeLists.txt
r266032 r266074 690 690 inspector/PerGlobalObjectWrapperWorld.h 691 691 inspector/ScriptArguments.h 692 inspector/ScriptBreakpoint.h693 692 inspector/ScriptCallFrame.h 694 693 inspector/ScriptCallStack.h 695 694 inspector/ScriptCallStackFactory.h 696 inspector/ScriptDebugListener.h697 inspector/ScriptDebugServer.h698 695 699 696 inspector/agents/InspectorAgent.h -
trunk/Source/JavaScriptCore/ChangeLog
r266072 r266074 1 2020-08-24 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: allow event breakpoints to be configured 4 https://bugs.webkit.org/show_bug.cgi?id=215362 5 <rdar://problem/66932921> 6 7 Reviewed by Brian Burg. 8 9 This allows developers to do things like: 10 - only pause when `window.event.type` is a certain value 11 - ignore the first N pauses 12 - evaluate JavaScript whenever an event listener is invoked without pausing 13 14 * inspector/protocol/DOM.json: 15 Add an `options` paramater to `DOM.setBreakpointForEventListener` to allow configuration. 16 17 * inspector/protocol/DOMDebugger.json: 18 Add an `options` paramater to `DOMDebugger.setEventBreakpoint` to allow configuration. 19 20 * debugger/Breakpoint.h: 21 (JSC::Breakpoint::id const): Added. 22 (JSC::Breakpoint::sourceID const): Added. 23 (JSC::Breakpoint::lineNumber const): Added. 24 (JSC::Breakpoint::columnNumber const): Added. 25 (JSC::Breakpoint::condition const): Added. 26 (JSC::Breakpoint::actions const): Added. 27 (JSC::Breakpoint::isAutoContinue const): Added. 28 (JSC::Breakpoint::resetHitCount): Added. 29 (JSC::Breakpoint::isLinked const): Added. 30 (JSC::Breakpoint::isResolved const): Added. 31 (JSC::BreakpointsList::~BreakpointsList): Deleted. 32 * debugger/Breakpoint.cpp: Added. 33 (JSC::Breakpoint::Action::Action): Added. 34 (JSC::Breakpoint::create): Added. 35 (JSC::Breakpoint::Breakpoint): Added. 36 (JSC::Breakpoint::link): Added. 37 (JSC::Breakpoint::resolve): Added. 38 (JSC::Breakpoint::shouldPause): Added. 39 Unify `JSC::Breakpoint` and `Inspector::ScriptBreakpoint`. 40 41 * debugger/DebuggerPrimitives.h: 42 * debugger/Debugger.h: 43 * debugger/Debugger.cpp: 44 (JSC::Debugger::Debugger): 45 (JSC::Debugger::addObserver): Added. 46 (JSC::Debugger::removeObserver): Added. 47 (JSC::Debugger::canDispatchFunctionToObservers const): Added. 48 (JSC::Debugger::dispatchFunctionToObservers): Added. 49 (JSC::Debugger::sourceParsed): Added. 50 (JSC::Debugger::toggleBreakpoint): 51 (JSC::Debugger::applyBreakpoints): 52 (JSC::Debugger::resolveBreakpoint): 53 (JSC::Debugger::setBreakpoint): 54 (JSC::Debugger::removeBreakpoint): 55 (JSC::Debugger::didHitBreakpoint): Added. 56 (JSC::Debugger::clearBreakpoints): 57 (JSC::Debugger::evaluateBreakpointCondition): Added. 58 (JSC::Debugger::evaluateBreakpointActions): Added. 59 (JSC::Debugger::schedulePauseAtNextOpportunity): Added. 60 (JSC::Debugger::cancelPauseAtNextOpportunity): Added. 61 (JSC::Debugger::schedulePauseForSpecialBreakpoint): Added. 62 (JSC::Debugger::cancelPauseForSpecialBreakpoint): Added. 63 (JSC::Debugger::continueProgram): 64 (JSC::Debugger::stepNextExpression): 65 (JSC::Debugger::stepIntoStatement): 66 (JSC::Debugger::stepOverStatement): 67 (JSC::Debugger::stepOutOfFunction): 68 (JSC::Debugger::pauseIfNeeded): 69 (JSC::Debugger::handlePause): Added. 70 (JSC::Debugger::exceptionOrCaughtValue): Added. 71 (JSC::Debugger::atExpression): 72 (JSC::Debugger::clearNextPauseState): 73 (JSC::Debugger::willRunMicrotask): Added. 74 (JSC::Debugger::didRunMicrotask): Added. 75 (JSC::Debugger::hasBreakpoint): Deleted. 76 (JSC::Debugger::setPauseOnNextStatement): Deleted. 77 Unify `JSC::Debugger` and `Inspector::ScriptDebugServer` to simplify breakpoint logic. 78 Introduce the concept of a "special breakpoint", which is essentially a `JSC::Breakpoint` 79 that is expected to pause at the next opportunity but isn't tied to a particular location. 80 As an example, whenever an event breakpoint is hit, instead of just pausing at the next 81 opportunity, the newly managed `JSC::Breakpoint` is used as a "special breakpoint", allowing 82 for it's configuration (ie.g. condition, ignore count, actions, auto-continue) to be used. 83 84 * inspector/agents/InspectorDebuggerAgent.h: 85 * inspector/agents/InspectorDebuggerAgent.cpp: 86 (Inspector::objectGroupForBreakpointAction): 87 (Inspector::breakpointActionTypeForString): Added. 88 (Inspector::parseBreakpointOptions): Added. 89 (Inspector::InspectorDebuggerAgent::ProtocolBreakpoint::fromPayload): Added. 90 (Inspector::InspectorDebuggerAgent::ProtocolBreakpoint::ProtocolBreakpoint): Added. 91 (Inspector::InspectorDebuggerAgent::ProtocolBreakpoint::createDebuggerBreakpoint const): Added. 92 (Inspector::InspectorDebuggerAgent::ProtocolBreakpoint::matchesScriptURL const): Added. 93 (Inspector::InspectorDebuggerAgent::debuggerBreakpointFromPayload): Added. 94 (Inspector::InspectorDebuggerAgent::enable): 95 (Inspector::InspectorDebuggerAgent::disable): 96 (Inspector::InspectorDebuggerAgent::buildBreakpointPauseReason): 97 (Inspector::InspectorDebuggerAgent::handleConsoleAssert): 98 (Inspector::InspectorDebuggerAgent::didScheduleAsyncCall): 99 (Inspector::buildDebuggerLocation): 100 (Inspector::InspectorDebuggerAgent::setBreakpointByUrl): 101 (Inspector::InspectorDebuggerAgent::setBreakpoint): 102 (Inspector::InspectorDebuggerAgent::didSetBreakpoint): 103 (Inspector::InspectorDebuggerAgent::resolveBreakpoint): 104 (Inspector::InspectorDebuggerAgent::removeBreakpoint): 105 (Inspector::InspectorDebuggerAgent::continueToLocation): 106 (Inspector::InspectorDebuggerAgent::schedulePauseAtNextOpportunity): Added. 107 (Inspector::InspectorDebuggerAgent::cancelPauseAtNextOpportunity): Added. 108 (Inspector::InspectorDebuggerAgent::schedulePauseForSpecialBreakpoint): Added. 109 (Inspector::InspectorDebuggerAgent::cancelPauseForSpecialBreakpoint): Added. 110 (Inspector::InspectorDebuggerAgent::pause): 111 (Inspector::InspectorDebuggerAgent::resume): 112 (Inspector::InspectorDebuggerAgent::didBecomeIdle): 113 (Inspector::InspectorDebuggerAgent::sourceMapURLForScript): 114 (Inspector::InspectorDebuggerAgent::didParseSource): 115 (Inspector::InspectorDebuggerAgent::willRunMicrotask): 116 (Inspector::InspectorDebuggerAgent::didRunMicrotask): 117 (Inspector::InspectorDebuggerAgent::didPause): 118 (Inspector::InspectorDebuggerAgent::breakpointActionSound): 119 (Inspector::InspectorDebuggerAgent::breakpointActionProbe): 120 (Inspector::InspectorDebuggerAgent::clearInspectorBreakpointState): 121 (Inspector::InspectorDebuggerAgent::clearDebuggerBreakpointState): 122 (Inspector::matches): Deleted. 123 (Inspector::buildObjectForBreakpointCookie): Deleted. 124 (Inspector::InspectorDebuggerAgent::breakpointActionsFromProtocol): Deleted. 125 (Inspector::InspectorDebuggerAgent::schedulePauseOnNextStatement): Deleted. 126 (Inspector::InspectorDebuggerAgent::cancelPauseOnNextStatement): Deleted. 127 Create a private `ProtocolBreakpoint` class that holds the data sent by the frontend. This 128 is necessary because breakpoints in the frontend have a potentially one-to-many relationship 129 with breakpoints in the backend, as the same script can be loaded many times on a page. Each 130 of those scripts is independent, however, and can execute differently, meaning that the same 131 breakpoint for each script also needs a different state (e.g. ignore count). As such, the 132 `ProtocolBreakpoint` is effectively a template that is actualized whenever a new script is 133 parsed that matches the URL of the `ProtocolBreakpoint` to create a `JSC::Breakpoint` that 134 is used by the `JSC::Debugger`. `ProtocolBreakpoint` also parses breakpoint configurations. 135 136 * inspector/InspectorEnvironment.h: 137 * inspector/JSGlobalObjectScriptDebugServer.h: 138 * inspector/JSGlobalObjectScriptDebugServer.cpp: 139 (Inspector::JSGlobalObjectScriptDebugServer::JSGlobalObjectScriptDebugServer): 140 (Inspector::JSGlobalObjectScriptDebugServer::attachDebugger): 141 (Inspector::JSGlobalObjectScriptDebugServer::detachDebugger): 142 (Inspector::JSGlobalObjectScriptDebugServer::runEventLoopWhilePaused): 143 * inspector/agents/InspectorAuditAgent.h: 144 * inspector/agents/InspectorAuditAgent.cpp: 145 (Inspector::InspectorAuditAgent::run): 146 * inspector/agents/InspectorRuntimeAgent.h: 147 * inspector/agents/InspectorRuntimeAgent.cpp: 148 (Inspector::setPauseOnExceptionsState): 149 (Inspector::InspectorRuntimeAgent::evaluate): 150 (Inspector::InspectorRuntimeAgent::callFunctionOn): 151 (Inspector::InspectorRuntimeAgent::getPreview): 152 (Inspector::InspectorRuntimeAgent::getProperties): 153 (Inspector::InspectorRuntimeAgent::getDisplayableProperties): 154 * inspector/agents/InspectorScriptProfilerAgent.cpp: 155 * inspector/agents/JSGlobalObjectDebuggerAgent.h: 156 Replace `Inspector::ScriptDebugServer` with `JSC::Debugger`. 157 158 * runtime/JSMicrotask.cpp: 159 (JSC::JSMicrotask::run): 160 Drive-by: r248894 mistakenly omitted the call to notify the debugger that the microtask ran. 161 162 * inspector/ScriptBreakpoint.h: Removed. 163 * inspector/ScriptDebugListener.h: Removed. 164 * inspector/ScriptDebugServer.h: Removed. 165 * inspector/ScriptDebugServer.cpp: Removed. 166 * CMakeLists.txt: 167 * JavaScriptCore.xcodeproj/project.pbxproj: 168 * Sources.txt: 169 1 170 2020-08-24 Devin Rousso <drousso@apple.com> 2 171 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r266032 r266074 1394 1394 A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */; }; 1395 1395 A503FA1E188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA18188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h */; }; 1396 A503FA21188EFF6800110F14 /* ScriptBreakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA1F188EFF6800110F14 /* ScriptBreakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };1397 A503FA22188EFF6800110F14 /* ScriptDebugListener.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA20188EFF6800110F14 /* ScriptDebugListener.h */; settings = {ATTRIBUTES = (Private, ); }; };1398 A503FA26188EFFFD00110F14 /* ScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA24188EFFFD00110F14 /* ScriptDebugServer.h */; settings = {ATTRIBUTES = (Private, ); }; };1399 1396 A503FA2A188F105900110F14 /* JSGlobalObjectScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA28188F105900110F14 /* JSGlobalObjectScriptDebugServer.h */; }; 1400 1397 A5098B041C16AA0200087797 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5098B031C16AA0200087797 /* Security.framework */; }; … … 4253 4250 918E15BE2447B22700447A56 /* AggregateErrorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AggregateErrorPrototype.cpp; sourceTree = "<group>"; }; 4254 4251 918E15BF2447B22700447A56 /* AggregateErrorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AggregateErrorConstructor.h; sourceTree = "<group>"; }; 4252 91D1578C24E0BE35001F4CED /* Breakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Breakpoint.cpp; sourceTree = "<group>"; }; 4255 4253 93052C320FB792190048FDC3 /* ParserArena.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParserArena.cpp; sourceTree = "<group>"; }; 4256 4254 93052C330FB792190048FDC3 /* ParserArena.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserArena.h; sourceTree = "<group>"; }; … … 4391 4389 A503FA17188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSJavaScriptCallFramePrototype.cpp; sourceTree = "<group>"; }; 4392 4390 A503FA18188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSJavaScriptCallFramePrototype.h; sourceTree = "<group>"; }; 4393 A503FA1F188EFF6800110F14 /* ScriptBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptBreakpoint.h; sourceTree = "<group>"; };4394 A503FA20188EFF6800110F14 /* ScriptDebugListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptDebugListener.h; sourceTree = "<group>"; };4395 A503FA23188EFFFD00110F14 /* ScriptDebugServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptDebugServer.cpp; sourceTree = "<group>"; };4396 A503FA24188EFFFD00110F14 /* ScriptDebugServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptDebugServer.h; sourceTree = "<group>"; };4397 4391 A503FA27188F105900110F14 /* JSGlobalObjectScriptDebugServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectScriptDebugServer.cpp; sourceTree = "<group>"; }; 4398 4392 A503FA28188F105900110F14 /* JSGlobalObjectScriptDebugServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectScriptDebugServer.h; sourceTree = "<group>"; }; … … 6550 6544 isa = PBXGroup; 6551 6545 children = ( 6546 91D1578C24E0BE35001F4CED /* Breakpoint.cpp */, 6552 6547 FEA0861E182B7A0400F6D851 /* Breakpoint.h */, 6553 6548 F692A8580255597D01FF60F7 /* Debugger.cpp */, … … 8710 8705 A5FD0065189AFE9C00633231 /* ScriptArguments.cpp */, 8711 8706 A5FD0066189AFE9C00633231 /* ScriptArguments.h */, 8712 A503FA1F188EFF6800110F14 /* ScriptBreakpoint.h */,8713 8707 A5FD0069189B00A900633231 /* ScriptCallFrame.cpp */, 8714 8708 A5FD006A189B00A900633231 /* ScriptCallFrame.h */, … … 8717 8711 A5FD007B189B0B4C00633231 /* ScriptCallStackFactory.cpp */, 8718 8712 A5FD007C189B0B4C00633231 /* ScriptCallStackFactory.h */, 8719 A503FA20188EFF6800110F14 /* ScriptDebugListener.h */,8720 A503FA23188EFFFD00110F14 /* ScriptDebugServer.cpp */,8721 A503FA24188EFFFD00110F14 /* ScriptDebugServer.h */,8722 8713 ); 8723 8714 path = inspector; … … 10328 10319 33111B8B2397256500AA34CE /* Scribble.h in Headers */, 10329 10320 A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */, 10330 A503FA21188EFF6800110F14 /* ScriptBreakpoint.h in Headers */,10331 10321 A5FD006E189B00AA00633231 /* ScriptCallFrame.h in Headers */, 10332 10322 A5FD0070189B00AA00633231 /* ScriptCallStack.h in Headers */, 10333 10323 A5FD007E189B0B4C00633231 /* ScriptCallStackFactory.h in Headers */, 10334 A503FA22188EFF6800110F14 /* ScriptDebugListener.h in Headers */,10335 A503FA26188EFFFD00110F14 /* ScriptDebugServer.h in Headers */,10336 10324 147341CE1DC02D7900AA29BA /* ScriptExecutable.h in Headers */, 10337 10325 CEAE7D7B889B477BA93ABA6C /* ScriptFetcher.h in Headers */, -
trunk/Source/JavaScriptCore/Sources.txt
r266032 r266074 301 301 bytecompiler/ProfileTypeBytecodeFlag.cpp 302 302 303 debugger/Breakpoint.cpp 303 304 debugger/Debugger.cpp 304 305 debugger/DebuggerCallFrame.cpp … … 594 595 inspector/ScriptCallStack.cpp 595 596 inspector/ScriptCallStackFactory.cpp 596 inspector/ScriptDebugServer.cpp597 597 598 598 // Derived Sources -
trunk/Source/JavaScriptCore/debugger/Breakpoint.h
r250655 r266074 27 27 28 28 #include "DebuggerPrimitives.h" 29 #include <wtf/DoublyLinkedList.h> 29 #include <wtf/FastMalloc.h> 30 #include <wtf/Noncopyable.h> 31 #include <wtf/Ref.h> 30 32 #include <wtf/RefCounted.h> 33 #include <wtf/Vector.h> 31 34 #include <wtf/text/WTFString.h> 32 35 33 36 namespace JSC { 34 37 35 struct Breakpoint : public DoublyLinkedListNode<Breakpoint> { 36 Breakpoint() 37 { 38 } 38 class Debugger; 39 class JSGlobalObject; 39 40 40 Breakpoint(SourceID sourceID, unsigned line, unsigned column, const String& condition, bool autoContinue, unsigned ignoreCount) 41 : sourceID(sourceID) 42 , line(line) 43 , column(column) 44 , condition(condition) 45 , autoContinue(autoContinue) 46 , ignoreCount(ignoreCount) 47 { 48 } 41 class Breakpoint : public RefCounted<Breakpoint> { 42 WTF_MAKE_NONCOPYABLE(Breakpoint); 43 WTF_MAKE_FAST_ALLOCATED; 44 public: 45 struct Action { 46 enum class Type : uint8_t { 47 Log, 48 Evaluate, 49 Sound, 50 Probe, 51 }; 49 52 50 BreakpointID id { noBreakpointID }; 51 SourceID sourceID { noSourceID }; 52 unsigned line { 0 }; 53 unsigned column { 0 }; 54 String condition; 55 bool autoContinue { false }; 56 unsigned ignoreCount { 0 }; 57 unsigned hitCount { 0 }; 58 bool resolved { false }; 53 Action(Type); 54 55 Type type; 56 String data; 57 BreakpointActionID id { noBreakpointActionID }; 58 }; 59 60 using ActionsVector = Vector<Action>; 61 62 static Ref<Breakpoint> create(BreakpointID, const String& condition = nullString(), ActionsVector&& = { }, bool autoContinue = false, size_t ignoreCount = 0); 63 64 BreakpointID id() const { return m_id; } 65 66 SourceID sourceID() const { return m_sourceID; } 67 unsigned lineNumber() const { return m_lineNumber; } 68 unsigned columnNumber() const { return m_columnNumber; } 69 70 const String& condition() const { return m_condition; } 71 const ActionsVector& actions() const { return m_actions; } 72 bool isAutoContinue() const { return m_autoContinue; } 73 74 void resetHitCount() { m_hitCount = 0; } 75 76 // Associates this breakpoint with a position in a specific source code. 77 bool link(SourceID, unsigned lineNumber, unsigned columnNumber); 78 bool isLinked() const { return m_sourceID != noSourceID; } 79 80 // Adjust the previously associated position to the next pause opportunity. 81 bool resolve(unsigned lineNumber, unsigned columnNumber); 82 bool isResolved() const { return m_resolved; } 83 84 bool shouldPause(Debugger&, JSGlobalObject*); 59 85 60 86 private: 61 Breakpoint* m_prev; 62 Breakpoint* m_next; 87 Breakpoint(BreakpointID, String condition = nullString(), ActionsVector&& = { }, bool autoContinue = false, size_t ignoreCount = 0); 63 88 64 friend class WTF::DoublyLinkedListNode<Breakpoint>; 89 BreakpointID m_id { noBreakpointID }; 90 91 SourceID m_sourceID { noSourceID }; 92 93 // FIXME: <https://webkit.org/b/162771> Web Inspector: Adopt TextPosition in Inspector to avoid oneBasedInt/zeroBasedInt ambiguity 94 unsigned m_lineNumber { 0 }; 95 unsigned m_columnNumber { 0 }; 96 97 bool m_resolved { false }; 98 99 String m_condition; 100 ActionsVector m_actions; 101 bool m_autoContinue { false }; 102 size_t m_ignoreCount { 0 }; 103 size_t m_hitCount { 0 }; 65 104 }; 66 105 67 class BreakpointsList : public DoublyLinkedList<Breakpoint>, 68 public RefCounted<BreakpointsList> { 69 public: 70 ~BreakpointsList() 71 { 72 Breakpoint* breakpoint; 73 while ((breakpoint = removeHead())) 74 delete breakpoint; 75 ASSERT(isEmpty()); 76 } 77 }; 106 using BreakpointsVector = Vector<Ref<JSC::Breakpoint>>; 78 107 79 108 } // namespace JSC -
trunk/Source/JavaScriptCore/debugger/Debugger.cpp
r261895 r266074 25 25 #include "CodeBlock.h" 26 26 #include "DebuggerCallFrame.h" 27 #include "DebuggerScope.h" 27 28 #include "HeapIterationScope.h" 28 29 #include "JSCInlines.h" 29 30 #include "MarkedSpaceInlines.h" 30 31 #include "VMEntryScope.h" 32 #include <wtf/HashMap.h> 33 #include <wtf/HashSet.h> 34 #include <wtf/RefPtr.h> 35 #include <wtf/Vector.h> 36 #include <wtf/text/TextPosition.h> 31 37 32 38 namespace JSC { … … 90 96 , m_lastExecutedLine(UINT_MAX) 91 97 , m_lastExecutedSourceID(noSourceID) 92 , m_topBreakpointID(noBreakpointID)93 98 , m_pausingBreakpointID(noBreakpointID) 94 99 { … … 206 211 } 207 212 213 void Debugger::addObserver(Observer& observer) 214 { 215 bool wasEmpty = m_observers.isEmpty(); 216 217 m_observers.add(&observer); 218 219 if (wasEmpty) 220 attachDebugger(); 221 } 222 223 void Debugger::removeObserver(Observer& observer, bool isBeingDestroyed) 224 { 225 m_observers.remove(&observer); 226 227 if (m_observers.isEmpty()) 228 detachDebugger(isBeingDestroyed); 229 } 230 231 bool Debugger::canDispatchFunctionToObservers() const 232 { 233 return !m_dispatchingFunctionToObservers && !m_observers.isEmpty(); 234 } 235 236 void Debugger::dispatchFunctionToObservers(Function<void(Observer&)> func) 237 { 238 if (!canDispatchFunctionToObservers()) 239 return; 240 241 SetForScope<bool> change(m_dispatchingFunctionToObservers, true); 242 243 for (auto* observer : copyToVector(m_observers)) 244 func(*observer); 245 } 246 208 247 void Debugger::setProfilingClient(ProfilingClient* client) 209 248 { … … 212 251 } 213 252 253 void Debugger::sourceParsed(JSGlobalObject* globalObject, SourceProvider* sourceProvider, int errorLine, const String& errorMessage) 254 { 255 // Preemptively check whether we can dispatch so that we don't do any unnecessary allocations. 256 if (!canDispatchFunctionToObservers()) 257 return; 258 259 if (errorLine != -1) { 260 auto sourceURL = sourceProvider->sourceURL(); 261 auto data = sourceProvider->source().toString(); 262 auto firstLine = sourceProvider->startPosition().m_line.oneBasedInt(); 263 dispatchFunctionToObservers([&] (Observer& observer) { 264 observer.failedToParseSource(sourceURL, data, firstLine, errorLine, errorMessage); 265 }); 266 return; 267 } 268 269 JSC::SourceID sourceID = sourceProvider->asID(); 270 271 // FIXME: <https://webkit.org/b/162773> Web Inspector: Simplify Debugger::Script to use SourceProvider 272 Debugger::Script script; 273 script.sourceProvider = sourceProvider; 274 script.url = sourceProvider->sourceURL(); 275 script.source = sourceProvider->source().toString(); 276 script.startLine = sourceProvider->startPosition().m_line.zeroBasedInt(); 277 script.startColumn = sourceProvider->startPosition().m_column.zeroBasedInt(); 278 script.isContentScript = isContentScript(globalObject); 279 script.sourceURL = sourceProvider->sourceURLDirective(); 280 script.sourceMappingURL = sourceProvider->sourceMappingURLDirective(); 281 282 int sourceLength = script.source.length(); 283 int lineCount = 1; 284 int lastLineStart = 0; 285 for (int i = 0; i < sourceLength; ++i) { 286 if (script.source[i] == '\n') { 287 lineCount += 1; 288 lastLineStart = i + 1; 289 } 290 } 291 292 script.endLine = script.startLine + lineCount - 1; 293 if (lineCount == 1) 294 script.endColumn = script.startColumn + sourceLength; 295 else 296 script.endColumn = sourceLength - lastLineStart; 297 298 dispatchFunctionToObservers([&] (Observer& observer) { 299 observer.didParseSource(sourceID, script); 300 }); 301 } 302 214 303 Seconds Debugger::willEvaluateScript() 215 304 { … … 224 313 void Debugger::toggleBreakpoint(CodeBlock* codeBlock, Breakpoint& breakpoint, BreakpointState enabledOrNot) 225 314 { 226 ASSERT(breakpoint. resolved);315 ASSERT(breakpoint.isResolved()); 227 316 228 317 ScriptExecutable* executable = codeBlock->ownerExecutable(); 229 318 230 319 SourceID sourceID = static_cast<SourceID>(executable->sourceID()); 231 if (breakpoint.sourceID != sourceID)320 if (breakpoint.sourceID() != sourceID) 232 321 return; 233 322 … … 239 328 // Inspector breakpoint line and column values are zero-based but the executable 240 329 // and CodeBlock line and column values are one-based. 241 unsigned line = breakpoint.line + 1;330 unsigned line = breakpoint.lineNumber() + 1; 242 331 Optional<unsigned> column; 243 if (breakpoint.column )244 column = breakpoint.column + 1;332 if (breakpoint.columnNumber()) 333 column = breakpoint.columnNumber() + 1; 245 334 246 335 if (line < startLine || line > endLine) … … 264 353 void Debugger::applyBreakpoints(CodeBlock* codeBlock) 265 354 { 266 BreakpointIDToBreakpointMap& breakpoints = m_breakpointIDToBreakpoint; 267 for (auto* breakpoint : breakpoints.values()) 268 toggleBreakpoint(codeBlock, *breakpoint, BreakpointEnabled); 355 for (auto& breakpoint : m_breakpoints) 356 toggleBreakpoint(codeBlock, breakpoint, BreakpointEnabled); 269 357 } 270 358 … … 315 403 } 316 404 317 voidDebugger::resolveBreakpoint(Breakpoint& breakpoint, SourceProvider* sourceProvider)318 { 319 RELEASE_ASSERT(!breakpoint. resolved);320 ASSERT(breakpoint. sourceID != noSourceID);405 bool Debugger::resolveBreakpoint(Breakpoint& breakpoint, SourceProvider* sourceProvider) 406 { 407 RELEASE_ASSERT(!breakpoint.isResolved()); 408 ASSERT(breakpoint.isLinked()); 321 409 322 410 // FIXME: <https://webkit.org/b/162771> Web Inspector: Adopt TextPosition in Inspector to avoid oneBasedInt/zeroBasedInt ambiguity 323 411 // Inspector breakpoint line and column values are zero-based but the executable 324 412 // and CodeBlock line values are one-based while column is zero-based. 325 int line = breakpoint.line + 1;326 int column = breakpoint.column ;413 int line = breakpoint.lineNumber() + 1; 414 int column = breakpoint.columnNumber(); 327 415 328 416 // Account for a <script>'s start position on the first line only. 329 417 int providerStartLine = sourceProvider->startPosition().m_line.oneBasedInt(); // One based to match the already adjusted line. 330 418 int providerStartColumn = sourceProvider->startPosition().m_column.zeroBasedInt(); // Zero based so column zero is zero. 331 if (line == providerStartLine && breakpoint.column ) {419 if (line == providerStartLine && breakpoint.columnNumber()) { 332 420 ASSERT(providerStartColumn <= column); 333 421 if (providerStartColumn) … … 335 423 } 336 424 337 DebuggerParseData& parseData = debuggerParseData(breakpoint.sourceID , sourceProvider);425 DebuggerParseData& parseData = debuggerParseData(breakpoint.sourceID(), sourceProvider); 338 426 Optional<JSTextPosition> resolvedPosition = parseData.pausePositions.breakpointLocationForLineColumn(line, column); 339 427 if (!resolvedPosition) 340 return ;428 return false; 341 429 342 430 int resolvedLine = resolvedPosition->line; … … 344 432 345 433 // Re-account for a <script>'s start position on the first line only. 346 if (resolvedLine == providerStartLine && breakpoint.column ) {434 if (resolvedLine == providerStartLine && breakpoint.columnNumber()) { 347 435 if (providerStartColumn) 348 436 resolvedColumn += providerStartColumn; 349 437 } 350 438 351 breakpoint.line = resolvedLine - 1; 352 breakpoint.column = resolvedColumn; 353 breakpoint.resolved = true; 354 } 355 356 BreakpointID Debugger::setBreakpoint(Breakpoint& breakpoint, bool& existing) 357 { 358 ASSERT(breakpoint.resolved); 359 ASSERT(breakpoint.sourceID != noSourceID); 360 361 SourceID sourceID = breakpoint.sourceID; 362 unsigned line = breakpoint.line; 363 unsigned column = breakpoint.column; 364 365 SourceIDToBreakpointsMap::iterator it = m_sourceIDToBreakpoints.find(breakpoint.sourceID); 366 if (it == m_sourceIDToBreakpoints.end()) 367 it = m_sourceIDToBreakpoints.set(sourceID, LineToBreakpointsMap()).iterator; 368 369 LineToBreakpointsMap::iterator breaksIt = it->value.find(line); 370 if (breaksIt == it->value.end()) 371 breaksIt = it->value.set(line, adoptRef(new BreakpointsList)).iterator; 372 373 BreakpointsList& breakpoints = *breaksIt->value; 374 for (Breakpoint* current = breakpoints.head(); current; current = current->next()) { 375 if (current->column == column) { 439 return breakpoint.resolve(resolvedLine - 1, resolvedColumn); 440 } 441 442 bool Debugger::setBreakpoint(Breakpoint& breakpoint) 443 { 444 ASSERT(breakpoint.isResolved()); 445 446 auto& breakpointsForLine = m_breakpointsForSourceID.ensure(breakpoint.sourceID(), [] { 447 return LineToBreakpointsMap(); 448 }).iterator->value; 449 450 auto& breakpoints = breakpointsForLine.ensure(breakpoint.lineNumber(), [] { 451 return BreakpointsVector(); 452 }).iterator->value; 453 454 for (auto& existingBreakpoint : breakpoints) { 455 if (existingBreakpoint->columnNumber() == breakpoint.columnNumber()) { 456 ASSERT(existingBreakpoint->id() != breakpoint.id()); 376 457 // Found existing breakpoint. Do not create a duplicate at this location. 377 existing = true; 378 return current->id; 458 return false; 379 459 } 380 460 } 381 461 382 existing = false; 383 BreakpointID id = ++m_topBreakpointID; 384 RELEASE_ASSERT(id != noBreakpointID); 385 386 breakpoint.id = id; 387 388 Breakpoint* newBreakpoint = new Breakpoint(breakpoint); 389 breakpoints.append(newBreakpoint); 390 m_breakpointIDToBreakpoint.set(id, newBreakpoint); 391 392 toggleBreakpoint(*newBreakpoint, BreakpointEnabled); 393 394 return id; 395 } 396 397 void Debugger::removeBreakpoint(BreakpointID id) 398 { 399 ASSERT(id != noBreakpointID); 400 401 BreakpointIDToBreakpointMap::iterator idIt = m_breakpointIDToBreakpoint.find(id); 402 ASSERT(idIt != m_breakpointIDToBreakpoint.end()); 403 Breakpoint* breakpoint = idIt->value; 404 405 SourceID sourceID = breakpoint->sourceID; 406 ASSERT(sourceID); 407 SourceIDToBreakpointsMap::iterator it = m_sourceIDToBreakpoints.find(sourceID); 408 ASSERT(it != m_sourceIDToBreakpoints.end()); 409 LineToBreakpointsMap::iterator breaksIt = it->value.find(breakpoint->line); 410 ASSERT(breaksIt != it->value.end()); 411 412 toggleBreakpoint(*breakpoint, BreakpointDisabled); 413 414 BreakpointsList& breakpoints = *breaksIt->value; 462 breakpoints.append(makeRef(breakpoint)); 463 464 m_breakpoints.add(makeRef(breakpoint)); 465 466 toggleBreakpoint(breakpoint, BreakpointEnabled); 467 468 return true; 469 } 470 471 bool Debugger::removeBreakpoint(Breakpoint& breakpoint) 472 { 473 ASSERT(breakpoint.isResolved()); 474 475 auto breakpointsForLineIterator = m_breakpointsForSourceID.find(breakpoint.sourceID()); 476 if (breakpointsForLineIterator == m_breakpointsForSourceID.end()) 477 return false; 478 479 auto breakpointsIterator = breakpointsForLineIterator->value.find(breakpoint.lineNumber()); 480 if (breakpointsIterator == breakpointsForLineIterator->value.end()) 481 return false; 482 483 toggleBreakpoint(breakpoint, BreakpointDisabled); 484 485 auto& breakpoints = breakpointsIterator->value; 486 415 487 #if ASSERT_ENABLED 416 488 bool found = false; 417 for (Breakpoint* current = breakpoints.head(); current && !found; current = current->next()) { 418 if (current->id == breakpoint->id) 489 for (auto& existingBreakpoint : breakpoints) { 490 if (existingBreakpoint->columnNumber() == breakpoint.columnNumber()) { 491 ASSERT(existingBreakpoint->id() == breakpoint.id()); 492 ASSERT(!found); 419 493 found = true; 420 }421 ASSERT(found);494 } 495 } 422 496 #endif // ASSERT_ENABLED 423 497 424 m_breakpointIDToBreakpoint.remove(idIt); 425 breakpoints.remove(breakpoint); 426 delete breakpoint; 498 auto removed = m_breakpoints.remove(breakpoint); 499 removed |= !breakpoints.removeAllMatching([&] (const Ref<Breakpoint>& existingBreakpoint) { 500 return &breakpoint == existingBreakpoint.ptr(); 501 }); 427 502 428 503 if (breakpoints.isEmpty()) { 429 it->value.remove(breaksIt); 430 if (it->value.isEmpty()) 431 m_sourceIDToBreakpoints.remove(it); 432 } 433 } 434 435 bool Debugger::hasBreakpoint(SourceID sourceID, const TextPosition& position, Breakpoint *hitBreakpoint) 504 breakpointsForLineIterator->value.remove(breakpointsIterator); 505 if (breakpointsForLineIterator->value.isEmpty()) 506 m_breakpointsForSourceID.remove(breakpointsForLineIterator); 507 } 508 509 return removed; 510 } 511 512 RefPtr<Breakpoint> Debugger::didHitBreakpoint(JSGlobalObject* globalObject, SourceID sourceID, const TextPosition& position) 436 513 { 437 514 if (!m_breakpointsActivated) 438 return false;439 440 SourceIDToBreakpointsMap::const_iterator it = m_sourceIDToBreakpoints.find(sourceID);441 if ( it == m_sourceIDToBreakpoints.end())442 return false;515 return nullptr; 516 517 auto breakpointsForLineIterator = m_breakpointsForSourceID.find(sourceID); 518 if (breakpointsForLineIterator == m_breakpointsForSourceID.end()) 519 return nullptr; 443 520 444 521 unsigned line = position.m_line.zeroBasedInt(); 445 522 unsigned column = position.m_column.zeroBasedInt(); 446 523 447 LineToBreakpointsMap::const_iterator breaksIt = it->value.find(line); 448 if (breaksIt == it->value.end()) 449 return false; 450 451 bool hit = false; 452 const BreakpointsList& breakpoints = *breaksIt->value; 453 Breakpoint* breakpoint; 454 for (breakpoint = breakpoints.head(); breakpoint; breakpoint = breakpoint->next()) { 455 unsigned breakLine = breakpoint->line; 456 unsigned breakColumn = breakpoint->column; 524 auto breakpointsIterator = breakpointsForLineIterator->value.find(line); 525 if (breakpointsIterator == breakpointsForLineIterator->value.end()) 526 return nullptr; 527 528 for (auto& breakpoint : breakpointsIterator->value) { 529 unsigned breakLine = breakpoint->lineNumber(); 530 unsigned breakColumn = breakpoint->columnNumber(); 531 457 532 // Since frontend truncates the indent, the first statement in a line must match the breakpoint (line,0). 458 533 ASSERT(this == m_currentCallFrame->codeBlock()->globalObject()->debugger()); 459 if ((line != m_lastExecutedLine && line == breakLine && !breakColumn) 460 || (line == breakLine && column == breakColumn)) {461 hit = true;534 if ((line != m_lastExecutedLine && line == breakLine && !breakColumn) || (line == breakLine && column == breakColumn)) { 535 if (breakpoint->shouldPause(*this, globalObject)) 536 return breakpoint.copyRef(); 462 537 break; 463 538 } 464 539 } 465 if (!hit) 466 return false; 467 468 if (hitBreakpoint) 469 *hitBreakpoint = *breakpoint; 470 471 breakpoint->hitCount++; 472 if (breakpoint->ignoreCount >= breakpoint->hitCount) 473 return false; 474 475 if (breakpoint->condition.isEmpty()) 476 return true; 477 478 // We cannot stop in the debugger while executing condition code, 479 // so make it looks like the debugger is already paused. 480 TemporaryPausedState pausedState(*this); 481 482 NakedPtr<Exception> exception; 483 DebuggerCallFrame& debuggerCallFrame = currentDebuggerCallFrame(); 484 JSObject* scopeExtensionObject = nullptr; 485 JSValue result = debuggerCallFrame.evaluateWithScopeExtension(breakpoint->condition, scopeExtensionObject, exception); 486 487 // We can lose the debugger while executing JavaScript. 488 if (!m_currentCallFrame) 489 return false; 490 491 JSGlobalObject* globalObject = m_currentCallFrame->lexicalGlobalObject(m_vm); 492 if (exception) { 493 // An erroneous condition counts as "false". 494 handleExceptionInBreakpointCondition(globalObject, exception); 495 return false; 496 } 497 498 return result.toBoolean(globalObject); 540 541 return nullptr; 499 542 } 500 543 … … 520 563 m_vm.heap.completeAllJITPlans(); 521 564 522 m_ topBreakpointID = noBreakpointID;523 m_breakpoint IDToBreakpoint.clear();524 m_s ourceIDToBreakpoints.clear();565 m_breakpointsForSourceID.clear(); 566 m_breakpoints.clear(); 567 m_specialBreakpoint = nullptr; 525 568 526 569 ClearCodeBlockDebuggerRequestsFunctor functor(this); 527 570 m_vm.heap.forEachCodeBlock(functor); 571 } 572 573 bool Debugger::evaluateBreakpointCondition(Breakpoint& breakpoint, JSGlobalObject* globalObject) 574 { 575 const String& condition = breakpoint.condition(); 576 if (condition.isEmpty()) 577 return true; 578 579 // We cannot stop in the debugger while executing condition code, 580 // so make it looks like the debugger is already paused. 581 TemporaryPausedState pausedState(*this); 582 583 NakedPtr<Exception> exception; 584 DebuggerCallFrame& debuggerCallFrame = currentDebuggerCallFrame(); 585 JSObject* scopeExtensionObject = nullptr; 586 JSValue result = debuggerCallFrame.evaluateWithScopeExtension(condition, scopeExtensionObject, exception); 587 588 // We can lose the debugger while executing JavaScript. 589 if (!m_currentCallFrame) 590 return false; 591 592 if (exception) { 593 reportException(globalObject, exception); 594 return false; 595 } 596 597 return result.toBoolean(globalObject); 598 } 599 600 void Debugger::evaluateBreakpointActions(Breakpoint& breakpoint, JSGlobalObject* globalObject) 601 { 602 ASSERT(m_isPaused); 603 ASSERT(isAttached(globalObject)); 604 605 m_currentProbeBatchId++; 606 607 for (auto& action : breakpoint.actions()) { 608 auto& debuggerCallFrame = currentDebuggerCallFrame(); 609 610 switch (action.type) { 611 case Breakpoint::Action::Type::Log: 612 dispatchFunctionToObservers([&] (Observer& observer) { 613 observer.breakpointActionLog(debuggerCallFrame.globalObject(), action.data); 614 }); 615 break; 616 617 case Breakpoint::Action::Type::Evaluate: { 618 NakedPtr<Exception> exception; 619 JSObject* scopeExtensionObject = nullptr; 620 debuggerCallFrame.evaluateWithScopeExtension(action.data, scopeExtensionObject, exception); 621 if (exception) 622 reportException(debuggerCallFrame.globalObject(), exception); 623 break; 624 } 625 626 case Breakpoint::Action::Type::Sound: 627 dispatchFunctionToObservers([&] (Observer& observer) { 628 observer.breakpointActionSound(action.id); 629 }); 630 break; 631 632 case Breakpoint::Action::Type::Probe: { 633 NakedPtr<Exception> exception; 634 JSObject* scopeExtensionObject = nullptr; 635 JSValue result = debuggerCallFrame.evaluateWithScopeExtension(action.data, scopeExtensionObject, exception); 636 JSC::JSGlobalObject* debuggerGlobalObject = debuggerCallFrame.globalObject(); 637 if (exception) 638 reportException(debuggerGlobalObject, exception); 639 640 dispatchFunctionToObservers([&] (Observer& observer) { 641 observer.breakpointActionProbe(debuggerGlobalObject, action.id, m_currentProbeBatchId, m_nextProbeSampleId++, exception ? exception->value() : result); 642 }); 643 break; 644 } 645 } 646 647 if (!isAttached(globalObject)) 648 return; 649 } 528 650 } 529 651 … … 572 694 } 573 695 574 void Debugger::setPauseOnNextStatement(bool pause) 575 { 576 m_pauseAtNextOpportunity = pause; 577 if (pause) 578 setSteppingMode(SteppingModeEnabled); 696 void Debugger::schedulePauseAtNextOpportunity() 697 { 698 m_pauseAtNextOpportunity = true; 699 700 setSteppingMode(SteppingModeEnabled); 701 } 702 703 void Debugger::cancelPauseAtNextOpportunity() 704 { 705 m_pauseAtNextOpportunity = false; 706 } 707 708 bool Debugger::schedulePauseForSpecialBreakpoint(Breakpoint& breakpoint) 709 { 710 if (m_specialBreakpoint) 711 return false; 712 713 m_specialBreakpoint = makeRef(breakpoint); 714 setSteppingMode(SteppingModeEnabled); 715 return true; 716 } 717 718 bool Debugger::cancelPauseForSpecialBreakpoint(Breakpoint& breakpoint) 719 { 720 if (&breakpoint != m_specialBreakpoint) 721 return false; 722 723 m_specialBreakpoint = nullptr; 724 return true; 579 725 } 580 726 … … 600 746 return; 601 747 602 notifyDoneProcessingDebuggerEvents();748 m_doneProcessingDebuggerEvents = true; 603 749 } 604 750 … … 611 757 m_pauseOnStepNext = true; 612 758 setSteppingMode(SteppingModeEnabled); 613 notifyDoneProcessingDebuggerEvents();759 m_doneProcessingDebuggerEvents = true; 614 760 } 615 761 … … 621 767 m_pauseAtNextOpportunity = true; 622 768 setSteppingMode(SteppingModeEnabled); 623 notifyDoneProcessingDebuggerEvents();769 m_doneProcessingDebuggerEvents = true; 624 770 } 625 771 … … 631 777 m_pauseOnCallFrame = m_currentCallFrame; 632 778 setSteppingMode(SteppingModeEnabled); 633 notifyDoneProcessingDebuggerEvents();779 m_doneProcessingDebuggerEvents = true; 634 780 } 635 781 … … 643 789 m_pauseOnStepOut = true; 644 790 setSteppingMode(SteppingModeEnabled); 645 notifyDoneProcessingDebuggerEvents();791 m_doneProcessingDebuggerEvents = true; 646 792 } 647 793 … … 702 848 bool didPauseForStep = pauseNow; 703 849 704 Breakpoint breakpoint;705 850 TextPosition position = DebuggerCallFrame::positionForCallFrame(vm, m_currentCallFrame); 706 bool didHitBreakpoint = hasBreakpoint(sourceID, position, &breakpoint); 707 pauseNow |= didHitBreakpoint; 851 852 auto breakpoint = didHitBreakpoint(globalObject, sourceID, position); 853 if (breakpoint) 854 pauseNow = true; 855 856 // Special breakpoints are only given one opportunity to pause. 857 auto specialBreakpoint = WTFMove(m_specialBreakpoint); 858 if (specialBreakpoint && specialBreakpoint->shouldPause(*this, globalObject)) 859 pauseNow = true; 860 708 861 m_lastExecutedLine = position.m_line.zeroBasedInt(); 709 862 if (!pauseNow) … … 717 870 TemporaryPausedState pausedState(*this); 718 871 719 if (didHitBreakpoint) { 720 handleBreakpointHit(globalObject, breakpoint); 872 if (breakpoint || specialBreakpoint) { 721 873 // Note that the actions can potentially stop the debugger, so we need to check that 722 874 // we still have a current call frame when we get back. 723 if (!m_currentCallFrame) 724 return; 725 726 if (breakpoint.autoContinue) { 875 876 bool autoContinue = false; 877 878 if (breakpoint) { 879 evaluateBreakpointActions(*breakpoint, globalObject); 880 881 if (!m_currentCallFrame) 882 return; 883 884 if (breakpoint->isAutoContinue()) 885 autoContinue = true; 886 } 887 888 if (specialBreakpoint) { 889 evaluateBreakpointActions(*specialBreakpoint, globalObject); 890 891 if (!m_currentCallFrame) 892 return; 893 894 if (specialBreakpoint->isAutoContinue()) 895 autoContinue = true; 896 } 897 898 if (autoContinue) { 727 899 if (!didPauseForStep) 728 900 return; 729 didHitBreakpoint = false; 730 } else 731 m_pausingBreakpointID = breakpoint.id; 901 902 breakpoint = nullptr; 903 specialBreakpoint = nullptr; 904 } else if (breakpoint) 905 m_pausingBreakpointID = breakpoint->id(); 732 906 } 733 907 734 908 if (blackboxTypeIterator != m_blackboxedScripts.end() && blackboxTypeIterator->value == BlackboxType::Deferred) { 735 909 m_afterBlackboxedScript = true; 736 s etPauseOnNextStatement(true);910 schedulePauseAtNextOpportunity(); 737 911 return; 738 912 } … … 742 916 if (afterBlackboxedScript) 743 917 reason = PausedAfterBlackboxedScript; 744 else if ( didHitBreakpoint)918 else if (breakpoint) 745 919 reason = PausedForBreakpoint; 746 920 PauseReasonDeclaration rauseReasonDeclaration(*this, reason); … … 752 926 m_pausingBreakpointID = noBreakpointID; 753 927 754 if (!m_pauseAtNextOpportunity && !m_pauseOnCallFrame ) {928 if (!m_pauseAtNextOpportunity && !m_pauseOnCallFrame && !m_specialBreakpoint) { 755 929 setSteppingMode(SteppingModeDisabled); 756 930 m_currentCallFrame = nullptr; 757 931 } 932 } 933 934 void Debugger::handlePause(JSGlobalObject* globalObject, ReasonForPause) 935 { 936 dispatchFunctionToObservers([&] (Observer& observer) { 937 ASSERT(isPaused()); 938 observer.didPause(globalObject, currentDebuggerCallFrame(), exceptionOrCaughtValue(globalObject)); 939 }); 940 941 didPause(globalObject); 942 943 m_doneProcessingDebuggerEvents = false; 944 runEventLoopWhilePaused(); 945 946 didContinue(globalObject); 947 948 dispatchFunctionToObservers([&] (Observer& observer) { 949 observer.didContinue(); 950 }); 951 } 952 953 JSC::JSValue Debugger::exceptionOrCaughtValue(JSC::JSGlobalObject* globalObject) 954 { 955 if (reasonForPause() == PausedForException) 956 return currentException(); 957 958 for (RefPtr<DebuggerCallFrame> frame = ¤tDebuggerCallFrame(); frame; frame = frame->callerFrame()) { 959 DebuggerScope& scope = *frame->scope(); 960 if (scope.isCatchScope()) 961 return scope.caughtValue(globalObject); 962 } 963 964 return { }; 758 965 } 759 966 … … 808 1015 } 809 1016 810 // Only pause at the next expression with step-in, step-next, and step-out.811 bool shouldAttemptPause = m_pauseAtNextOpportunity || m_pauseOnStepNext || m_pauseOnStepOut ;1017 // Only pause at the next expression for step-in, step-next, step-out, or special breakpoints. 1018 bool shouldAttemptPause = m_pauseAtNextOpportunity || m_pauseOnStepNext || m_pauseOnStepOut || m_specialBreakpoint; 812 1019 813 1020 PauseReasonDeclaration reason(*this, PausedAtExpression); … … 918 1125 m_pauseOnStepOut = false; 919 1126 m_afterBlackboxedScript = false; 1127 m_specialBreakpoint = nullptr; 920 1128 } 921 1129 … … 934 1142 } 935 1143 1144 void Debugger::willRunMicrotask() 1145 { 1146 dispatchFunctionToObservers([&] (Observer& observer) { 1147 observer.willRunMicrotask(); 1148 }); 1149 } 1150 1151 void Debugger::didRunMicrotask() 1152 { 1153 dispatchFunctionToObservers([&] (Observer& observer) { 1154 observer.didRunMicrotask(); 1155 }); 1156 } 1157 936 1158 DebuggerCallFrame& Debugger::currentDebuggerCallFrame() 937 1159 { -
trunk/Source/JavaScriptCore/debugger/Debugger.h
r260113 r266074 28 28 #include "DebuggerPrimitives.h" 29 29 #include "JSCJSValue.h" 30 #include <wtf/HashMap.h> 31 #include <wtf/HashSet.h> 32 #include <wtf/RefPtr.h> 33 #include <wtf/text/TextPosition.h> 30 #include <wtf/Forward.h> 34 31 35 32 namespace JSC { … … 42 39 class VM; 43 40 44 class JS_EXPORT_PRIVATEDebugger {41 class Debugger { 45 42 WTF_MAKE_FAST_ALLOCATED; 46 43 public: 47 Debugger(VM&);48 virtual ~Debugger();44 JS_EXPORT_PRIVATE Debugger(VM&); 45 JS_EXPORT_PRIVATE virtual ~Debugger(); 49 46 50 47 VM& vm() { return m_vm; } 51 52 JSC::DebuggerCallFrame& currentDebuggerCallFrame();53 bool hasHandlerForExceptionCallback() const54 {55 ASSERT(m_reasonForPause == PausedForException);56 return m_hasHandlerForExceptionCallback;57 }58 JSValue currentException()59 {60 ASSERT(m_reasonForPause == PausedForException);61 return m_currentException;62 }63 48 64 49 bool needsExceptionCallbacks() const { return m_breakpointsActivated && m_pauseOnExceptionsState != DontPauseOnExceptions; } … … 69 54 GlobalObjectIsDestructing 70 55 }; 71 void attach(JSGlobalObject*);72 void detach(JSGlobalObject*, ReasonForDetach);73 bool isAttached(JSGlobalObject*);74 75 voidresolveBreakpoint(Breakpoint&, SourceProvider*);76 BreakpointID setBreakpoint(Breakpoint&, bool& existing);77 void removeBreakpoint(BreakpointID);56 JS_EXPORT_PRIVATE void attach(JSGlobalObject*); 57 JS_EXPORT_PRIVATE void detach(JSGlobalObject*, ReasonForDetach); 58 JS_EXPORT_PRIVATE bool isAttached(JSGlobalObject*); 59 60 bool resolveBreakpoint(Breakpoint&, SourceProvider*); 61 bool setBreakpoint(Breakpoint&); 62 bool removeBreakpoint(Breakpoint&); 78 63 void clearBreakpoints(); 79 64 … … 81 66 void deactivateBreakpoints() { setBreakpointsActivated(false); } 82 67 bool breakpointsActive() const { return m_breakpointsActivated; } 68 69 // Breakpoint "delegate" functionality. 70 bool evaluateBreakpointCondition(Breakpoint&, JSGlobalObject*); 71 void evaluateBreakpointActions(Breakpoint&, JSGlobalObject*); 83 72 84 73 enum PauseOnExceptionsState { … … 88 77 }; 89 78 PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; } 90 void setPauseOnExceptionsState(PauseOnExceptionsState);79 JS_EXPORT_PRIVATE void setPauseOnExceptionsState(PauseOnExceptionsState); 91 80 92 81 void setPauseOnDebuggerStatements(bool enabled) { m_pauseOnDebuggerStatements = enabled; } … … 106 95 BreakpointID pausingBreakpointID() const { return m_pausingBreakpointID; } 107 96 108 void setPauseOnNextStatement(bool); 97 void schedulePauseAtNextOpportunity(); 98 void cancelPauseAtNextOpportunity(); 99 bool schedulePauseForSpecialBreakpoint(Breakpoint&); 100 bool cancelPauseForSpecialBreakpoint(Breakpoint&); 109 101 void breakProgram(); 110 102 void continueProgram(); … … 124 116 void setSuppressAllPauses(bool suppress) { m_suppressAllPauses = suppress; } 125 117 126 virtual void sourceParsed(JSGlobalObject*, SourceProvider*, int errorLineNumber, const WTF::String& errorMessage) = 0; 127 virtual void willRunMicrotask() { } 128 virtual void didRunMicrotask() { } 118 JS_EXPORT_PRIVATE virtual void sourceParsed(JSGlobalObject*, SourceProvider*, int errorLineNumber, const WTF::String& errorMessage); 129 119 130 120 void exception(JSGlobalObject*, CallFrame*, JSValue exceptionValue, bool hasCatchHandler); … … 138 128 void didReachDebuggerStatement(CallFrame*); 139 129 140 virtual void recompileAllJSFunctions(); 130 void willRunMicrotask(); 131 void didRunMicrotask(); 141 132 142 133 void registerCodeBlock(CodeBlock*); 134 135 // FIXME: <https://webkit.org/b/162773> Web Inspector: Simplify Debugger::Script to use SourceProvider 136 struct Script { 137 String url; 138 String source; 139 String sourceURL; 140 String sourceMappingURL; 141 RefPtr<SourceProvider> sourceProvider; 142 int startLine { 0 }; 143 int startColumn { 0 }; 144 int endLine { 0 }; 145 int endColumn { 0 }; 146 bool isContentScript { false }; 147 }; 148 149 class Observer { 150 public: 151 virtual ~Observer() { } 152 153 virtual void didParseSource(SourceID, const Debugger::Script&) { } 154 virtual void failedToParseSource(const String& /* url */, const String& /* data */, int /* firstLine */, int /* errorLine */, const String& /* errorMessage */) { } 155 156 virtual void willRunMicrotask() { } 157 virtual void didRunMicrotask() { } 158 159 virtual void didPause(JSGlobalObject*, DebuggerCallFrame&, JSValue /* exceptionOrCaughtValue */) { } 160 virtual void didContinue() { } 161 162 virtual void breakpointActionLog(JSGlobalObject*, const String& /* data */) { } 163 virtual void breakpointActionSound(BreakpointActionID) { } 164 virtual void breakpointActionProbe(JSGlobalObject*, BreakpointActionID, unsigned /* batchId */, unsigned /* sampleId */, JSValue /* result */) { } 165 }; 166 167 JS_EXPORT_PRIVATE void addObserver(Observer&); 168 JS_EXPORT_PRIVATE void removeObserver(Observer&, bool isBeingDestroyed); 143 169 144 170 class ProfilingClient { … … 157 183 158 184 protected: 159 virtual void handleBreakpointHit(JSGlobalObject*, const Breakpoint&) { } 160 virtual void handleExceptionInBreakpointCondition(JSGlobalObject*, Exception*) const { } 161 virtual void handlePause(JSGlobalObject*, ReasonForPause) { } 162 virtual void notifyDoneProcessingDebuggerEvents() { } 185 JS_EXPORT_PRIVATE JSC::DebuggerCallFrame& currentDebuggerCallFrame(); 186 187 bool hasHandlerForExceptionCallback() const 188 { 189 ASSERT(m_reasonForPause == PausedForException); 190 return m_hasHandlerForExceptionCallback; 191 } 192 193 JSValue currentException() 194 { 195 ASSERT(m_reasonForPause == PausedForException); 196 return m_currentException; 197 } 198 199 virtual void attachDebugger() { } 200 virtual void detachDebugger(bool /* isBeingDestroyed */) { } 201 JS_EXPORT_PRIVATE virtual void recompileAllJSFunctions(); 202 203 virtual void didPause(JSGlobalObject*) { } 204 JS_EXPORT_PRIVATE virtual void handlePause(JSGlobalObject*, ReasonForPause); 205 virtual void didContinue(JSGlobalObject*) { } 206 virtual void runEventLoopWhilePaused() { } 207 208 virtual bool isContentScript(JSGlobalObject*) const { return false; } 209 210 // NOTE: Currently all exceptions are reported at the API boundary through reportAPIException. 211 // Until a time comes where an exception can be caused outside of the API (e.g. setTimeout 212 // or some other async operation in a pure JSContext) we can ignore exceptions reported here. 213 virtual void reportException(JSGlobalObject*, Exception*) const { } 214 215 bool doneProcessingDebuggerEvents() const { return m_doneProcessingDebuggerEvents; } 163 216 164 217 private: 165 typedef HashMap<BreakpointID, Breakpoint*> BreakpointIDToBreakpointMap; 166 167 typedef HashMap<unsigned, RefPtr<BreakpointsList>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> LineToBreakpointsMap; 168 typedef HashMap<SourceID, LineToBreakpointsMap, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> SourceIDToBreakpointsMap; 218 JSValue exceptionOrCaughtValue(JSGlobalObject*); 169 219 170 220 class ClearCodeBlockDebuggerRequestsFunctor; … … 189 239 }; 190 240 191 bool hasBreakpoint(SourceID, const TextPosition&, Breakpoint* hitBreakpoint);241 RefPtr<Breakpoint> didHitBreakpoint(JSGlobalObject*, SourceID, const TextPosition&); 192 242 193 243 DebuggerParseData& debuggerParseData(SourceID, SourceProvider*); … … 216 266 BreakpointEnabled 217 267 }; 218 void setBreakpointsActivated(bool);268 JS_EXPORT_PRIVATE void setBreakpointsActivated(bool); 219 269 void toggleBreakpoint(CodeBlock*, Breakpoint&, BreakpointState); 220 270 void applyBreakpoints(CodeBlock*); … … 223 273 void clearDebuggerRequests(JSGlobalObject*); 224 274 void clearParsedData(); 275 276 bool canDispatchFunctionToObservers() const; 277 void dispatchFunctionToObservers(Function<void(Observer&)>); 225 278 226 279 VM& m_vm; … … 249 302 bool m_afterBlackboxedScript { false }; 250 303 251 BreakpointID m_topBreakpointID; 304 using LineToBreakpointsMap = HashMap<unsigned, BreakpointsVector, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>>; 305 HashMap<SourceID, LineToBreakpointsMap, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> m_breakpointsForSourceID; 306 HashSet<Ref<Breakpoint>> m_breakpoints; 307 RefPtr<Breakpoint> m_specialBreakpoint; 252 308 BreakpointID m_pausingBreakpointID; 253 BreakpointIDToBreakpointMap m_breakpointIDToBreakpoint; 254 SourceIDToBreakpointsMap m_sourceIDToBreakpoints; 309 310 unsigned m_nextProbeSampleId { 1 }; 311 unsigned m_currentProbeBatchId { 0 }; 255 312 256 313 RefPtr<JSC::DebuggerCallFrame> m_currentDebuggerCallFrame; 257 314 315 HashSet<Observer*> m_observers; 316 bool m_dispatchingFunctionToObservers { false }; 317 258 318 ProfilingClient* m_profilingClient { nullptr }; 319 320 bool m_doneProcessingDebuggerEvents { true }; 259 321 260 322 friend class DebuggerPausedScope; -
trunk/Source/JavaScriptCore/debugger/DebuggerPrimitives.h
r250005 r266074 30 30 namespace JSC { 31 31 32 typedef size_t SourceID;33 staticconstexpr SourceID noSourceID = 0;32 using SourceID = size_t; 33 constexpr SourceID noSourceID = 0; 34 34 35 typedef size_t BreakpointID; 36 static constexpr BreakpointID noBreakpointID = 0; 35 using BreakpointID = size_t; 36 constexpr BreakpointID noBreakpointID = 0; 37 38 using BreakpointActionID = int; 39 constexpr BreakpointActionID noBreakpointActionID = 0; 37 40 38 41 } // namespace JSC -
trunk/Source/JavaScriptCore/inspector/InspectorEnvironment.h
r261233 r266074 33 33 34 34 namespace JSC { 35 class Debugger; 35 36 class Exception; 36 37 class SourceCode; … … 40 41 namespace Inspector { 41 42 42 class ScriptDebugServer;43 43 typedef JSC::JSValue (*InspectorFunctionCallHandler)(JSC::JSGlobalObject* globalObject, JSC::JSValue functionObject, const JSC::CallData& callData, JSC::JSValue thisValue, const JSC::ArgList& args, NakedPtr<JSC::Exception>& returnedException); 44 44 typedef JSC::JSValue (*InspectorEvaluateHandler)(JSC::JSGlobalObject*, const JSC::SourceCode&, JSC::JSValue thisValue, NakedPtr<JSC::Exception>& returnedException); … … 53 53 virtual void frontendInitialized() = 0; 54 54 virtual WTF::Stopwatch& executionStopwatch() const = 0; 55 virtual ScriptDebugServer& scriptDebugServer() = 0;55 virtual JSC::Debugger& scriptDebugServer() = 0; 56 56 virtual JSC::VM& vm() = 0; 57 57 }; -
trunk/Source/JavaScriptCore/inspector/JSGlobalObjectScriptDebugServer.cpp
r261755 r266074 36 36 37 37 JSGlobalObjectScriptDebugServer::JSGlobalObjectScriptDebugServer(JSGlobalObject& globalObject) 38 : ScriptDebugServer(globalObject.vm())38 : Debugger(globalObject.vm()) 39 39 , m_globalObject(globalObject) 40 40 { … … 43 43 void JSGlobalObjectScriptDebugServer::attachDebugger() 44 44 { 45 JSC::Debugger::attachDebugger(); 46 45 47 attach(&m_globalObject); 46 48 } … … 48 50 void JSGlobalObjectScriptDebugServer::detachDebugger(bool isBeingDestroyed) 49 51 { 52 JSC::Debugger::detachDebugger(isBeingDestroyed); 53 50 54 detach(&m_globalObject, isBeingDestroyed ? Debugger::GlobalObjectIsDestructing : Debugger::TerminatingDebuggingSession); 51 55 if (!isBeingDestroyed) … … 55 59 void JSGlobalObjectScriptDebugServer::runEventLoopWhilePaused() 56 60 { 61 JSC::Debugger::runEventLoopWhilePaused(); 62 57 63 // Drop all locks so another thread can work in the VM while we are nested. 58 64 JSC::JSLock::DropAllLocks dropAllLocks(&m_globalObject.vm()); 59 65 60 while (! m_doneProcessingDebuggerEvents) {66 while (!doneProcessingDebuggerEvents()) { 61 67 if (RunLoop::cycle(JSGlobalObjectScriptDebugServer::runLoopMode()) == RunLoop::CycleResult::Stop) 62 68 break; -
trunk/Source/JavaScriptCore/inspector/JSGlobalObjectScriptDebugServer.h
r261569 r266074 26 26 #pragma once 27 27 28 #include " ScriptDebugServer.h"28 #include "Debugger.h" 29 29 #include <wtf/RunLoop.h> 30 30 31 31 namespace Inspector { 32 32 33 class JSGlobalObjectScriptDebugServer final : public ScriptDebugServer {33 class JSGlobalObjectScriptDebugServer final : public JSC::Debugger { 34 34 WTF_MAKE_NONCOPYABLE(JSGlobalObjectScriptDebugServer); 35 35 WTF_MAKE_FAST_ALLOCATED; … … 43 43 44 44 private: 45 // JSC::Debugger 45 46 void attachDebugger() final; 46 47 void detachDebugger(bool isBeingDestroyed) final; 47 48 void didPause(JSC::JSGlobalObject*) final { }49 void didContinue(JSC::JSGlobalObject*) final { }50 48 void runEventLoopWhilePaused() final; 51 bool isContentScript(JSC::JSGlobalObject*) const final { return false; }52 53 // NOTE: Currently all exceptions are reported at the API boundary through reportAPIException.54 // Until a time comes where an exception can be caused outside of the API (e.g. setTimeout55 // or some other async operation in a pure JSContext) we can ignore exceptions reported here.56 void reportException(JSC::JSGlobalObject*, JSC::Exception*) const final { }57 49 58 50 JSC::JSGlobalObject& m_globalObject; -
trunk/Source/JavaScriptCore/inspector/agents/InspectorAuditAgent.cpp
r261755 r266074 27 27 #include "InspectorAuditAgent.h" 28 28 29 #include "Debugger.h" 29 30 #include "InjectedScript.h" 30 31 #include "JSLock.h" 31 32 #include "ObjectConstructor.h" 32 #include "ScriptDebugServer.h"33 33 #include <wtf/RefPtr.h> 34 34 #include <wtf/Vector.h> … … 106 106 Optional<int> savedResultIndex; 107 107 108 ScriptDebugServer::PauseOnExceptionsStatepreviousPauseOnExceptionsState = m_scriptDebugServer.pauseOnExceptionsState();108 auto previousPauseOnExceptionsState = m_scriptDebugServer.pauseOnExceptionsState(); 109 109 110 m_scriptDebugServer.setPauseOnExceptionsState( ScriptDebugServer::DontPauseOnExceptions);110 m_scriptDebugServer.setPauseOnExceptionsState(Debugger::DontPauseOnExceptions); 111 111 muteConsole(); 112 112 -
trunk/Source/JavaScriptCore/inspector/agents/InspectorAuditAgent.h
r251425 r266074 33 33 #include <wtf/Noncopyable.h> 34 34 35 namespace JSC { 36 class Debugger; 37 } 38 35 39 namespace Inspector { 36 40 37 41 class InjectedScript; 38 42 class InjectedScriptManager; 39 class ScriptDebugServer;40 43 typedef String ErrorString; 41 44 … … 72 75 RefPtr<AuditBackendDispatcher> m_backendDispatcher; 73 76 InjectedScriptManager& m_injectedScriptManager; 74 ScriptDebugServer& m_scriptDebugServer;77 JSC::Debugger& m_scriptDebugServer; 75 78 76 79 JSC::Strong<JSC::JSObject> m_injectedWebInspectorAuditValue; -
trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp
r262786 r266074 33 33 #include "AsyncStackTrace.h" 34 34 #include "ContentSearchUtilities.h" 35 #include "Debugger.h" 36 #include "DebuggerScope.h" 35 37 #include "InjectedScript.h" 36 38 #include "InjectedScriptManager.h" 39 #include "JSJavaScriptCallFrame.h" 40 #include "JavaScriptCallFrame.h" 37 41 #include "RegularExpression.h" 38 42 #include "ScriptCallStack.h" 39 43 #include "ScriptCallStackFactory.h" 40 #include "ScriptDebugServer.h"44 #include <wtf/Function.h> 41 45 #include <wtf/JSONValues.h> 42 46 #include <wtf/Stopwatch.h> … … 51 55 // have several object groups, and objects from several backend breakpoint action instances may 52 56 // create objects in the same group. 53 static String objectGroupForBreakpointAction( const ScriptBreakpointAction& action)54 { 55 return makeString("breakpoint-action-", action.identifier);57 static String objectGroupForBreakpointAction(JSC::BreakpointActionID id) 58 { 59 return makeString("breakpoint-action-", id); 56 60 } 57 61 … … 59 63 { 60 64 return sourceURL.startsWith("__InjectedScript_") && sourceURL.endsWith(".js"); 65 } 66 67 static Optional<JSC::Breakpoint::Action::Type> breakpointActionTypeForString(ErrorString& errorString, const String& typeString) 68 { 69 auto type = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Debugger::BreakpointAction::Type>(typeString); 70 if (!type) { 71 errorString = makeString("Unknown breakpoint action type: "_s, typeString); 72 return WTF::nullopt; 73 } 74 75 switch (*type) { 76 case Inspector::Protocol::Debugger::BreakpointAction::Type::Log: 77 return JSC::Breakpoint::Action::Type::Log; 78 79 case Inspector::Protocol::Debugger::BreakpointAction::Type::Evaluate: 80 return JSC::Breakpoint::Action::Type::Evaluate; 81 82 case Inspector::Protocol::Debugger::BreakpointAction::Type::Sound: 83 return JSC::Breakpoint::Action::Type::Sound; 84 85 case Inspector::Protocol::Debugger::BreakpointAction::Type::Probe: 86 return JSC::Breakpoint::Action::Type::Probe; 87 } 88 89 ASSERT_NOT_REACHED(); 90 return WTF::nullopt; 91 } 92 93 template <typename T> 94 static T parseBreakpointOptions(ErrorString& errorString, const JSON::Object* optionsPayload, Function<T(const String&, JSC::Breakpoint::ActionsVector&&, bool, size_t)> callback) 95 { 96 String condition; 97 JSC::Breakpoint::ActionsVector actions; 98 bool autoContinue = false; 99 size_t ignoreCount = 0; 100 101 if (optionsPayload) { 102 optionsPayload->getString("condition"_s, condition); 103 104 RefPtr<JSON::Array> actionsPayload; 105 optionsPayload->getArray("actions"_s, actionsPayload); 106 if (auto count = actionsPayload ? actionsPayload->length() : 0) { 107 actions.reserveCapacity(count); 108 109 for (unsigned i = 0; i < count; ++i) { 110 RefPtr<JSON::Object> actionObject; 111 if (!actionsPayload->get(i)->asObject(actionObject)) { 112 errorString = "Unexpected non-object item in given actions"_s; 113 return { }; 114 } 115 116 String actionTypeString; 117 if (!actionObject->getString("type"_s, actionTypeString)) { 118 errorString = "Missing type for item in given actions"_s; 119 return { }; 120 } 121 122 auto actionType = breakpointActionTypeForString(errorString, actionTypeString); 123 if (!actionType) 124 return { }; 125 126 JSC::Breakpoint::Action action(*actionType); 127 128 actionObject->getString("data"_s, action.data); 129 130 // Specifying an identifier is optional. They are used to correlate probe samples 131 // in the frontend across multiple backend probe actions and segregate object groups. 132 actionObject->getInteger("id"_s, action.id); 133 134 actions.append(WTFMove(action)); 135 } 136 } 137 138 optionsPayload->getBoolean("autoContinue"_s, autoContinue); 139 optionsPayload->getInteger("ignoreCount"_s, ignoreCount); 140 } 141 142 return callback(condition, WTFMove(actions), autoContinue, ignoreCount); 143 } 144 145 Optional<InspectorDebuggerAgent::ProtocolBreakpoint> InspectorDebuggerAgent::ProtocolBreakpoint::fromPayload(ErrorString& errorString, JSC::SourceID sourceID, unsigned lineNumber, unsigned columnNumber, const JSON::Object* optionsPayload) 146 { 147 return parseBreakpointOptions<Optional<ProtocolBreakpoint>>(errorString, optionsPayload, [&] (const String& condition, JSC::Breakpoint::ActionsVector&& actions, bool autoContinue, size_t ignoreCount) -> Optional<ProtocolBreakpoint> { 148 return ProtocolBreakpoint(sourceID, lineNumber, columnNumber, condition, WTFMove(actions), autoContinue, ignoreCount); 149 }); 150 } 151 152 Optional<InspectorDebuggerAgent::ProtocolBreakpoint> InspectorDebuggerAgent::ProtocolBreakpoint::fromPayload(ErrorString& errorString, const String& url, bool isRegex, unsigned lineNumber, unsigned columnNumber, const JSON::Object* optionsPayload) 153 { 154 return parseBreakpointOptions<Optional<ProtocolBreakpoint>>(errorString, optionsPayload, [&] (const String& condition, JSC::Breakpoint::ActionsVector&& actions, bool autoContinue, size_t ignoreCount) -> Optional<ProtocolBreakpoint> { 155 return ProtocolBreakpoint(url, isRegex, lineNumber, columnNumber, condition, WTFMove(actions), autoContinue, ignoreCount); 156 }); 157 } 158 159 InspectorDebuggerAgent::ProtocolBreakpoint::ProtocolBreakpoint() = default; 160 161 InspectorDebuggerAgent::ProtocolBreakpoint::ProtocolBreakpoint(JSC::SourceID sourceID, unsigned lineNumber, unsigned columnNumber, const String& condition, JSC::Breakpoint::ActionsVector&& actions, bool autoContinue, size_t ignoreCount) 162 : m_id(makeString(sourceID, ':', lineNumber, ':', columnNumber)) 163 #if ASSERT_ENABLED 164 , m_sourceID(sourceID) 165 #endif 166 , m_lineNumber(lineNumber) 167 , m_columnNumber(columnNumber) 168 , m_condition(condition) 169 , m_actions(WTFMove(actions)) 170 , m_autoContinue(autoContinue) 171 , m_ignoreCount(ignoreCount) 172 { 173 } 174 175 InspectorDebuggerAgent::ProtocolBreakpoint::ProtocolBreakpoint(const String& url, bool isRegex, unsigned lineNumber, unsigned columnNumber, const String& condition, JSC::Breakpoint::ActionsVector&& actions, bool autoContinue, size_t ignoreCount) 176 : m_id(makeString(isRegex ? "/" : "", url, isRegex ? "/" : "", ':', lineNumber, ':', columnNumber)) 177 , m_url(url) 178 , m_isRegex(isRegex) 179 , m_lineNumber(lineNumber) 180 , m_columnNumber(columnNumber) 181 , m_condition(condition) 182 , m_actions(WTFMove(actions)) 183 , m_autoContinue(autoContinue) 184 , m_ignoreCount(ignoreCount) 185 { 186 } 187 188 Ref<JSC::Breakpoint> InspectorDebuggerAgent::ProtocolBreakpoint::createDebuggerBreakpoint(JSC::BreakpointID debuggerBreakpointID, JSC::SourceID sourceID) const 189 { 190 ASSERT(debuggerBreakpointID != JSC::noBreakpointID); 191 ASSERT(sourceID != JSC::noSourceID); 192 ASSERT(sourceID == m_sourceID || m_sourceID == JSC::noSourceID); 193 194 auto debuggerBreakpoint = JSC::Breakpoint::create(debuggerBreakpointID, m_condition, copyToVector(m_actions), m_autoContinue, m_ignoreCount); 195 debuggerBreakpoint->link(sourceID, m_lineNumber, m_columnNumber); 196 return debuggerBreakpoint; 197 } 198 199 bool InspectorDebuggerAgent::ProtocolBreakpoint::matchesScriptURL(const String& scriptURL) const 200 { 201 ASSERT(m_sourceID == JSC::noSourceID); 202 203 if (m_isRegex) { 204 JSC::Yarr::RegularExpression regex(m_url); 205 return regex.match(scriptURL) != -1; 206 } 207 return m_url == scriptURL; 208 } 209 210 RefPtr<JSC::Breakpoint> InspectorDebuggerAgent::debuggerBreakpointFromPayload(ErrorString& errorString, const JSON::Object* optionsPayload) 211 { 212 return parseBreakpointOptions<RefPtr<JSC::Breakpoint>>(errorString, optionsPayload, [] (const String& condition, JSC::Breakpoint::ActionsVector&& actions, bool autoContinue, size_t ignoreCount) { 213 return JSC::Breakpoint::create(JSC::noBreakpointID, condition, WTFMove(actions), autoContinue, ignoreCount); 214 }); 61 215 } 62 216 … … 88 242 m_enabled = true; 89 243 90 m_scriptDebugServer.add Listener(this);244 m_scriptDebugServer.addObserver(*this); 91 245 92 246 for (auto* listener : copyToVector(m_listeners)) … … 109 263 listener->debuggerWasDisabled(); 110 264 111 m_scriptDebugServer.remove Listener(this, isBeingDestroyed);265 m_scriptDebugServer.removeObserver(*this, isBeingDestroyed); 112 266 113 267 clearInspectorBreakpointState(); … … 115 269 if (!isBeingDestroyed) 116 270 m_scriptDebugServer.deactivateBreakpoints(); 117 118 ASSERT(m_javaScriptBreakpoints.isEmpty());119 271 120 272 clearAsyncStackTraceData(); … … 207 359 } 208 360 209 RefPtr<JSON::Object> InspectorDebuggerAgent::buildBreakpointPauseReason(JSC::BreakpointID debuggerBreakpointIdentifier) 210 { 211 ASSERT(debuggerBreakpointIdentifier != JSC::noBreakpointID); 212 auto it = m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.find(debuggerBreakpointIdentifier); 213 if (it == m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.end()) 214 return nullptr; 215 216 auto reason = Protocol::Debugger::BreakpointPauseReason::create() 217 .setBreakpointId(it->value) 218 .release(); 219 return reason->openAccessors(); 361 RefPtr<JSON::Object> InspectorDebuggerAgent::buildBreakpointPauseReason(JSC::BreakpointID debuggerBreakpointID) 362 { 363 ASSERT(debuggerBreakpointID != JSC::noBreakpointID); 364 365 for (auto& [protocolBreakpointID, debuggerBreakpoints] : m_debuggerBreakpointsForProtocolBreakpointID) { 366 for (auto& debuggerBreakpoint : debuggerBreakpoints) { 367 if (debuggerBreakpoint->id() == debuggerBreakpointID) { 368 auto reason = Protocol::Debugger::BreakpointPauseReason::create() 369 .setBreakpointId(protocolBreakpointID) 370 .release(); 371 return reason->openAccessors(); 372 } 373 } 374 } 375 376 return nullptr; 220 377 } 221 378 … … 235 392 void InspectorDebuggerAgent::handleConsoleAssert(const String& message) 236 393 { 237 if (! m_scriptDebugServer.breakpointsActive())394 if (!breakpointsActive()) 238 395 return; 239 396 … … 252 409 return; 253 410 254 if (! m_scriptDebugServer.breakpointsActive())411 if (!breakpointsActive()) 255 412 return; 256 413 … … 334 491 } 335 492 336 static Ref<JSON::Object> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, RefPtr<JSON::Array>& actions, bool isRegex, bool autoContinue, unsigned ignoreCount) 337 { 338 Ref<JSON::Object> breakpointObject = JSON::Object::create(); 339 breakpointObject->setString("url"_s, url); 340 breakpointObject->setInteger("lineNumber"_s, lineNumber); 341 breakpointObject->setInteger("columnNumber"_s, columnNumber); 342 breakpointObject->setString("condition"_s, condition); 343 breakpointObject->setBoolean("isRegex"_s, isRegex); 344 breakpointObject->setBoolean("autoContinue"_s, autoContinue); 345 breakpointObject->setInteger("ignoreCount"_s, ignoreCount); 346 347 if (actions) 348 breakpointObject->setArray("actions"_s, actions); 349 350 return breakpointObject; 351 } 352 353 static bool matches(const String& url, const String& pattern, bool isRegex) 354 { 355 if (isRegex) { 356 JSC::Yarr::RegularExpression regex(pattern); 357 return regex.match(url) != -1; 358 } 359 return url == pattern; 360 } 361 362 static bool breakpointActionTypeForString(const String& typeString, ScriptBreakpointActionType* output) 363 { 364 if (typeString == Protocol::InspectorHelpers::getEnumConstantValue(Protocol::Debugger::BreakpointAction::Type::Log)) { 365 *output = ScriptBreakpointActionTypeLog; 366 return true; 367 } 368 if (typeString == Protocol::InspectorHelpers::getEnumConstantValue(Protocol::Debugger::BreakpointAction::Type::Evaluate)) { 369 *output = ScriptBreakpointActionTypeEvaluate; 370 return true; 371 } 372 if (typeString == Protocol::InspectorHelpers::getEnumConstantValue(Protocol::Debugger::BreakpointAction::Type::Sound)) { 373 *output = ScriptBreakpointActionTypeSound; 374 return true; 375 } 376 if (typeString == Protocol::InspectorHelpers::getEnumConstantValue(Protocol::Debugger::BreakpointAction::Type::Probe)) { 377 *output = ScriptBreakpointActionTypeProbe; 378 return true; 379 } 380 381 return false; 382 } 383 384 bool InspectorDebuggerAgent::breakpointActionsFromProtocol(ErrorString& errorString, RefPtr<JSON::Array>& actions, BreakpointActions* result) 385 { 386 if (!actions) 387 return true; 388 389 unsigned actionsLength = actions->length(); 390 if (!actionsLength) 391 return true; 392 393 result->reserveCapacity(actionsLength); 394 for (unsigned i = 0; i < actionsLength; ++i) { 395 RefPtr<JSON::Value> value = actions->get(i); 396 RefPtr<JSON::Object> object; 397 if (!value->asObject(object)) { 398 errorString = "Unexpected non-object item in given actions"_s; 399 return false; 400 } 401 402 String typeString; 403 if (!object->getString("type"_s, typeString)) { 404 errorString = "Missing type for item in given actions"_s; 405 return false; 406 } 407 408 ScriptBreakpointActionType type; 409 if (!breakpointActionTypeForString(typeString, &type)) { 410 errorString = "Non-string type for item in given actions"_s; 411 return false; 412 } 413 414 // Specifying an identifier is optional. They are used to correlate probe samples 415 // in the frontend across multiple backend probe actions and segregate object groups. 416 int identifier = 0; 417 object->getInteger("id"_s, identifier); 418 419 String data; 420 object->getString("data"_s, data); 421 422 result->append(ScriptBreakpointAction(type, identifier, data)); 423 } 424 425 return true; 426 } 427 428 static RefPtr<Protocol::Debugger::Location> buildDebuggerLocation(const JSC::Breakpoint& breakpoint) 429 { 430 ASSERT(breakpoint.resolved); 493 static RefPtr<Protocol::Debugger::Location> buildDebuggerLocation(const JSC::Breakpoint& debuggerBreakpoint) 494 { 495 ASSERT(debuggerBreakpoint.isResolved()); 431 496 432 497 auto location = Protocol::Debugger::Location::create() 433 .setScriptId(String::number( breakpoint.sourceID))434 .setLineNumber( breakpoint.line)498 .setScriptId(String::number(debuggerBreakpoint.sourceID())) 499 .setLineNumber(debuggerBreakpoint.lineNumber()) 435 500 .release(); 436 location->setColumnNumber( breakpoint.column);501 location->setColumnNumber(debuggerBreakpoint.columnNumber()); 437 502 438 503 return location; … … 460 525 } 461 526 462 void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString& errorString, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const JSON::Object* options, Protocol::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<JSON::ArrayOf<Protocol::Debugger::Location>>& locations) 463 { 464 locations = JSON::ArrayOf<Protocol::Debugger::Location>::create(); 527 void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString& errorString, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const JSON::Object* optionsPayload, Protocol::Debugger::BreakpointId* outBreakpointId, RefPtr<JSON::ArrayOf<Protocol::Debugger::Location>>& outLocations) 528 { 465 529 if (!optionalURL == !optionalURLRegex) { 466 530 errorString = "Either url or urlRegex must be specified"_s; … … 468 532 } 469 533 470 String url = optionalURL ? *optionalURL : *optionalURLRegex; 471 int columnNumber = optionalColumnNumber ? *optionalColumnNumber : 0; 472 bool isRegex = optionalURLRegex; 473 474 String breakpointIdentifier = makeString(isRegex ? "/" : "", url, isRegex ? "/:" : ":", lineNumber, ':', columnNumber); 475 if (m_javaScriptBreakpoints.contains(breakpointIdentifier)) { 534 auto protocolBreakpoint = ProtocolBreakpoint::fromPayload(errorString, optionalURL ? *optionalURL : *optionalURLRegex, !!optionalURLRegex, lineNumber, optionalColumnNumber ? *optionalColumnNumber : 0, optionsPayload); 535 if (!protocolBreakpoint) 536 return; 537 538 if (m_protocolBreakpointForProtocolBreakpointID.contains(protocolBreakpoint->id())) { 476 539 errorString = "Breakpoint for given location already exists."_s; 477 540 return; 478 541 } 479 542 480 String condition = emptyString(); 481 bool autoContinue = false; 482 unsigned ignoreCount = 0; 483 RefPtr<JSON::Array> actions; 484 if (options) { 485 options->getString("condition"_s, condition); 486 options->getBoolean("autoContinue"_s, autoContinue); 487 options->getArray("actions"_s, actions); 488 options->getInteger("ignoreCount"_s, ignoreCount); 489 } 490 491 BreakpointActions breakpointActions; 492 if (!breakpointActionsFromProtocol(errorString, actions, &breakpointActions)) 493 return; 494 495 m_javaScriptBreakpoints.set(breakpointIdentifier, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, actions, isRegex, autoContinue, ignoreCount)); 496 497 for (auto& entry : m_scripts) { 498 Script& script = entry.value; 543 m_protocolBreakpointForProtocolBreakpointID.set(protocolBreakpoint->id(), *protocolBreakpoint); 544 545 outLocations = JSON::ArrayOf<Protocol::Debugger::Location>::create(); 546 547 for (auto& [sourceID, script] : m_scripts) { 499 548 String scriptURLForBreakpoints = !script.sourceURL.isEmpty() ? script.sourceURL : script.url; 500 if (! matches(scriptURLForBreakpoints, url, isRegex))549 if (!protocolBreakpoint->matchesScriptURL(scriptURLForBreakpoints)) 501 550 continue; 502 551 503 JSC::SourceID sourceID = entry.key; 504 JSC::Breakpoint breakpoint(sourceID, lineNumber, columnNumber, condition, autoContinue, ignoreCount); 505 resolveBreakpoint(script, breakpoint); 506 if (!breakpoint.resolved) 552 auto debuggerBreakpoint = protocolBreakpoint->createDebuggerBreakpoint(m_nextDebuggerBreakpointID++, sourceID); 553 554 if (!resolveBreakpoint(script, debuggerBreakpoint)) 507 555 continue; 508 556 509 bool existing; 510 setBreakpoint(breakpoint, existing); 511 if (existing) 557 if (!setBreakpoint(debuggerBreakpoint)) 512 558 continue; 513 559 514 ScriptBreakpoint scriptBreakpoint(breakpoint.line, breakpoint.column, condition, breakpointActions, autoContinue, ignoreCount); 515 didSetBreakpoint(breakpoint, breakpointIdentifier, scriptBreakpoint); 516 517 locations->addItem(buildDebuggerLocation(breakpoint)); 518 } 519 520 *outBreakpointIdentifier = breakpointIdentifier; 521 } 522 523 void InspectorDebuggerAgent::setBreakpoint(ErrorString& errorString, const JSON::Object& location, const JSON::Object* options, Protocol::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Protocol::Debugger::Location>& actualLocation) 560 didSetBreakpoint(*protocolBreakpoint, debuggerBreakpoint); 561 562 outLocations->addItem(buildDebuggerLocation(debuggerBreakpoint)); 563 } 564 565 *outBreakpointId = protocolBreakpoint->id(); 566 } 567 568 void InspectorDebuggerAgent::setBreakpoint(ErrorString& errorString, const JSON::Object& location, const JSON::Object* optionsPayload, Protocol::Debugger::BreakpointId* outBreakpointId, RefPtr<Protocol::Debugger::Location>& outActualLocation) 524 569 { 525 570 JSC::SourceID sourceID; … … 529 574 return; 530 575 531 String condition = emptyString();532 bool autoContinue = false;533 unsigned ignoreCount = 0;534 RefPtr<JSON::Array> actions;535 if (options) {536 options->getString("condition"_s, condition);537 options->getBoolean("autoContinue"_s, autoContinue);538 options->getArray("actions"_s, actions);539 options->getInteger("ignoreCount"_s, ignoreCount);540 }541 542 BreakpointActions breakpointActions;543 if (!breakpointActionsFromProtocol(errorString, actions, &breakpointActions))544 return;545 546 576 auto scriptIterator = m_scripts.find(sourceID); 547 577 if (scriptIterator == m_scripts.end()) { … … 550 580 } 551 581 552 Script& script = scriptIterator->value; 553 JSC::Breakpoint breakpoint(sourceID, lineNumber, columnNumber, condition, autoContinue, ignoreCount); 554 resolveBreakpoint(script, breakpoint); 555 if (!breakpoint.resolved) { 582 auto protocolBreakpoint = ProtocolBreakpoint::fromPayload(errorString, sourceID, lineNumber, columnNumber, optionsPayload); 583 if (!protocolBreakpoint) 584 return; 585 586 // Don't save `protocolBreakpoint` in `m_protocolBreakpointForProtocolBreakpointID` because it 587 // was set specifically for the given `sourceID`, which is unique, meaning that it will never 588 // be used inside `InspectorDebuggerAgent::didParseSource`. 589 590 auto debuggerBreakpoint = protocolBreakpoint->createDebuggerBreakpoint(m_nextDebuggerBreakpointID++, sourceID); 591 592 if (!resolveBreakpoint(scriptIterator->value, debuggerBreakpoint)) { 556 593 errorString = "Could not resolve breakpoint"_s; 557 594 return; 558 595 } 559 596 560 bool existing; 561 setBreakpoint(breakpoint, existing); 562 if (existing) { 597 if (!setBreakpoint(debuggerBreakpoint)) { 563 598 errorString = "Breakpoint for given location already exists"_s; 564 599 return; 565 600 } 566 601 567 String breakpointIdentifier = makeString(sourceID, ':', breakpoint.line, ':', breakpoint.column); 568 ScriptBreakpoint scriptBreakpoint(breakpoint.line, breakpoint.column, condition, breakpointActions, autoContinue, ignoreCount); 569 didSetBreakpoint(breakpoint, breakpointIdentifier, scriptBreakpoint); 570 571 actualLocation = buildDebuggerLocation(breakpoint); 572 *outBreakpointIdentifier = breakpointIdentifier; 573 } 574 575 void InspectorDebuggerAgent::didSetBreakpoint(const JSC::Breakpoint& breakpoint, const String& breakpointIdentifier, const ScriptBreakpoint& scriptBreakpoint) 576 { 577 JSC::BreakpointID id = breakpoint.id; 578 m_scriptDebugServer.setBreakpointActions(id, scriptBreakpoint); 579 580 auto debugServerBreakpointIDsIterator = m_breakpointIdentifierToDebugServerBreakpointIDs.find(breakpointIdentifier); 581 if (debugServerBreakpointIDsIterator == m_breakpointIdentifierToDebugServerBreakpointIDs.end()) 582 debugServerBreakpointIDsIterator = m_breakpointIdentifierToDebugServerBreakpointIDs.set(breakpointIdentifier, Vector<JSC::BreakpointID>()).iterator; 583 debugServerBreakpointIDsIterator->value.append(id); 584 585 m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.set(id, breakpointIdentifier); 586 } 587 588 void InspectorDebuggerAgent::resolveBreakpoint(const Script& script, JSC::Breakpoint& breakpoint) 589 { 590 if (breakpoint.line < static_cast<unsigned>(script.startLine) || static_cast<unsigned>(script.endLine) < breakpoint.line) 591 return; 592 593 m_scriptDebugServer.resolveBreakpoint(breakpoint, script.sourceProvider.get()); 594 } 595 596 void InspectorDebuggerAgent::setBreakpoint(JSC::Breakpoint& breakpoint, bool& existing) 602 didSetBreakpoint(*protocolBreakpoint, debuggerBreakpoint); 603 604 outActualLocation = buildDebuggerLocation(debuggerBreakpoint); 605 *outBreakpointId = protocolBreakpoint->id(); 606 } 607 608 void InspectorDebuggerAgent::didSetBreakpoint(ProtocolBreakpoint& protocolBreakpoint, JSC::Breakpoint& debuggerBreakpoint) 609 { 610 auto& debuggerBreakpoints = m_debuggerBreakpointsForProtocolBreakpointID.ensure(protocolBreakpoint.id(), [] { 611 return JSC::BreakpointsVector(); 612 }).iterator->value; 613 614 debuggerBreakpoints.append(debuggerBreakpoint); 615 } 616 617 bool InspectorDebuggerAgent::resolveBreakpoint(const JSC::Debugger::Script& script, JSC::Breakpoint& debuggerBreakpoint) 618 { 619 if (debuggerBreakpoint.lineNumber() < static_cast<unsigned>(script.startLine) || static_cast<unsigned>(script.endLine) < debuggerBreakpoint.lineNumber()) 620 return false; 621 622 return m_scriptDebugServer.resolveBreakpoint(debuggerBreakpoint, script.sourceProvider.get()); 623 } 624 625 bool InspectorDebuggerAgent::setBreakpoint(JSC::Breakpoint& debuggerBreakpoint) 597 626 { 598 627 JSC::JSLockHolder locker(m_scriptDebugServer.vm()); 599 m_scriptDebugServer.setBreakpoint(breakpoint, existing); 600 } 601 602 void InspectorDebuggerAgent::removeBreakpoint(ErrorString&, const String& breakpointIdentifier) 603 { 604 m_javaScriptBreakpoints.remove(breakpointIdentifier); 605 606 for (JSC::BreakpointID breakpointID : m_breakpointIdentifierToDebugServerBreakpointIDs.take(breakpointIdentifier)) { 607 m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.remove(breakpointID); 608 609 const BreakpointActions& breakpointActions = m_scriptDebugServer.getActionsForBreakpoint(breakpointID); 610 for (auto& action : breakpointActions) 611 m_injectedScriptManager.releaseObjectGroup(objectGroupForBreakpointAction(action)); 628 return m_scriptDebugServer.setBreakpoint(debuggerBreakpoint); 629 } 630 631 void InspectorDebuggerAgent::removeBreakpoint(ErrorString&, const Inspector::Protocol::Debugger::BreakpointId& protocolBreakpointID) 632 { 633 m_protocolBreakpointForProtocolBreakpointID.remove(protocolBreakpointID); 634 635 for (auto& debuggerBreakpoint : m_debuggerBreakpointsForProtocolBreakpointID.take(protocolBreakpointID)) { 636 for (const auto& action : debuggerBreakpoint->actions()) 637 m_injectedScriptManager.releaseObjectGroup(objectGroupForBreakpointAction(action.id)); 612 638 613 639 JSC::JSLockHolder locker(m_scriptDebugServer.vm()); 614 m_scriptDebugServer.removeBreakpointActions(breakpointID); 615 m_scriptDebugServer.removeBreakpoint(breakpointID); 640 m_scriptDebugServer.removeBreakpoint(debuggerBreakpoint); 616 641 } 617 642 } … … 634 659 return; 635 660 636 if (m_continueToLocation BreakpointID != JSC::noBreakpointID) {637 m_scriptDebugServer.removeBreakpoint( m_continueToLocationBreakpointID);638 m_continueToLocation BreakpointID = JSC::noBreakpointID;661 if (m_continueToLocationDebuggerBreakpoint) { 662 m_scriptDebugServer.removeBreakpoint(*m_continueToLocationDebuggerBreakpoint); 663 m_continueToLocationDebuggerBreakpoint = nullptr; 639 664 } 640 665 … … 653 678 } 654 679 655 String condition; 656 bool autoContinue = false; 657 unsigned ignoreCount = 0; 658 JSC::Breakpoint breakpoint(sourceID, lineNumber, columnNumber, condition, autoContinue, ignoreCount); 659 Script& script = scriptIterator->value; 660 resolveBreakpoint(script, breakpoint); 661 if (!breakpoint.resolved) { 680 auto protocolBreakpoint = ProtocolBreakpoint::fromPayload(errorString, sourceID, lineNumber, columnNumber); 681 if (!protocolBreakpoint) 682 return; 683 684 // Don't save `protocolBreakpoint` in `m_protocolBreakpointForProtocolBreakpointID` because it 685 // is a temporary breakpoint that will be removed as soon as `location` is reached. 686 687 auto debuggerBreakpoint = protocolBreakpoint->createDebuggerBreakpoint(m_nextDebuggerBreakpointID++, sourceID); 688 689 if (!resolveBreakpoint(scriptIterator->value, debuggerBreakpoint)) { 662 690 m_scriptDebugServer.continueProgram(); 663 691 m_frontendDispatcher->resumed(); … … 666 694 } 667 695 668 bool existing; 669 setBreakpoint(breakpoint, existing); 670 if (existing) { 696 if (!setBreakpoint(debuggerBreakpoint)) { 671 697 // There is an existing breakpoint at this location. Instead of 672 698 // acting like a series of steps, just resume and we will either … … 677 703 } 678 704 679 m_continueToLocation BreakpointID = breakpoint.id;705 m_continueToLocationDebuggerBreakpoint = WTFMove(debuggerBreakpoint); 680 706 681 707 // Treat this as a series of steps until reaching the new breakpoint. … … 720 746 } 721 747 722 void InspectorDebuggerAgent::schedulePause OnNextStatement(DebuggerFrontendDispatcher::Reason reason, RefPtr<JSON::Object>&& data)748 void InspectorDebuggerAgent::schedulePauseAtNextOpportunity(DebuggerFrontendDispatcher::Reason reason, RefPtr<JSON::Object>&& data) 723 749 { 724 750 if (m_javaScriptPauseScheduled) … … 730 756 731 757 JSC::JSLockHolder locker(m_scriptDebugServer.vm()); 732 m_scriptDebugServer.s etPauseOnNextStatement(true);733 } 734 735 void InspectorDebuggerAgent::cancelPause OnNextStatement()758 m_scriptDebugServer.schedulePauseAtNextOpportunity(); 759 } 760 761 void InspectorDebuggerAgent::cancelPauseAtNextOpportunity() 736 762 { 737 763 if (!m_javaScriptPauseScheduled) … … 741 767 742 768 clearPauseDetails(); 743 m_scriptDebugServer. setPauseOnNextStatement(false);769 m_scriptDebugServer.cancelPauseAtNextOpportunity(); 744 770 m_enablePauseWhenIdle = false; 745 771 } 746 772 773 bool InspectorDebuggerAgent::schedulePauseForSpecialBreakpoint(JSC::Breakpoint& breakpoint, DebuggerFrontendDispatcher::Reason reason, RefPtr<JSON::Object>&& data) 774 { 775 JSC::JSLockHolder locker(m_scriptDebugServer.vm()); 776 777 if (!m_scriptDebugServer.schedulePauseForSpecialBreakpoint(breakpoint)) 778 return false; 779 780 updatePauseReasonAndData(reason, WTFMove(data)); 781 return true; 782 } 783 784 bool InspectorDebuggerAgent::cancelPauseForSpecialBreakpoint(JSC::Breakpoint& breakpoint) 785 { 786 if (!m_scriptDebugServer.cancelPauseForSpecialBreakpoint(breakpoint)) 787 return false; 788 789 clearPauseDetails(); 790 return true; 791 } 792 747 793 void InspectorDebuggerAgent::pause(ErrorString&) 748 794 { 749 schedulePause OnNextStatement(DebuggerFrontendDispatcher::Reason::PauseOnNextStatement, nullptr);795 schedulePauseAtNextOpportunity(DebuggerFrontendDispatcher::Reason::PauseOnNextStatement); 750 796 } 751 797 … … 757 803 } 758 804 759 cancelPause OnNextStatement();805 cancelPauseAtNextOpportunity(); 760 806 m_scriptDebugServer.continueProgram(); 761 807 m_conditionToDispatchResumed = ShouldDispatchResumed::WhenContinued; … … 823 869 824 870 if (m_conditionToDispatchResumed == ShouldDispatchResumed::WhenIdle) { 825 cancelPause OnNextStatement();871 cancelPauseAtNextOpportunity(); 826 872 m_scriptDebugServer.continueProgram(); 827 873 m_frontendDispatcher->resumed(); … … 959 1005 } 960 1006 961 String InspectorDebuggerAgent::sourceMapURLForScript(const Script& script)1007 String InspectorDebuggerAgent::sourceMapURLForScript(const JSC::Debugger::Script& script) 962 1008 { 963 1009 return script.sourceMappingURL; … … 979 1025 } 980 1026 981 void InspectorDebuggerAgent::didParseSource(JSC::SourceID sourceID, const Script& script)1027 void InspectorDebuggerAgent::didParseSource(JSC::SourceID sourceID, const JSC::Debugger::Script& script) 982 1028 { 983 1029 String scriptIDStr = String::number(sourceID); … … 1005 1051 return; 1006 1052 1007 for (auto& entry : m_javaScriptBreakpoints) { 1008 RefPtr<JSON::Object> breakpointObject = entry.value; 1009 1010 bool isRegex; 1011 String url; 1012 breakpointObject->getBoolean("isRegex"_s, isRegex); 1013 breakpointObject->getString("url"_s, url); 1014 if (!matches(scriptURLForBreakpoints, url, isRegex)) 1053 for (auto& protocolBreakpoint : m_protocolBreakpointForProtocolBreakpointID.values()) { 1054 if (!protocolBreakpoint.matchesScriptURL(scriptURLForBreakpoints)) 1015 1055 continue; 1016 1056 1017 ScriptBreakpoint scriptBreakpoint; 1018 breakpointObject->getInteger("lineNumber"_s, scriptBreakpoint.lineNumber); 1019 breakpointObject->getInteger("columnNumber"_s, scriptBreakpoint.columnNumber); 1020 breakpointObject->getString("condition"_s, scriptBreakpoint.condition); 1021 breakpointObject->getBoolean("autoContinue"_s, scriptBreakpoint.autoContinue); 1022 breakpointObject->getInteger("ignoreCount"_s, scriptBreakpoint.ignoreCount); 1023 ErrorString errorString; 1024 RefPtr<JSON::Array> actions; 1025 breakpointObject->getArray("actions"_s, actions); 1026 if (!breakpointActionsFromProtocol(errorString, actions, &scriptBreakpoint.actions)) { 1027 ASSERT_NOT_REACHED(); 1057 auto debuggerBreakpoint = protocolBreakpoint.createDebuggerBreakpoint(m_nextDebuggerBreakpointID++, sourceID); 1058 1059 if (!resolveBreakpoint(script, debuggerBreakpoint)) 1028 1060 continue; 1029 } 1030 1031 JSC::Breakpoint breakpoint(sourceID, scriptBreakpoint.lineNumber, scriptBreakpoint.columnNumber, scriptBreakpoint.condition, scriptBreakpoint.autoContinue, scriptBreakpoint.ignoreCount); 1032 resolveBreakpoint(script, breakpoint); 1033 if (!breakpoint.resolved) 1061 1062 if (!setBreakpoint(debuggerBreakpoint)) 1034 1063 continue; 1035 1064 1036 bool existing; 1037 setBreakpoint(breakpoint, existing); 1038 if (existing) 1039 continue; 1040 1041 String breakpointIdentifier = entry.key; 1042 didSetBreakpoint(breakpoint, breakpointIdentifier, scriptBreakpoint); 1043 1044 m_frontendDispatcher->breakpointResolved(breakpointIdentifier, buildDebuggerLocation(breakpoint)); 1065 didSetBreakpoint(protocolBreakpoint, debuggerBreakpoint); 1066 1067 m_frontendDispatcher->breakpointResolved(protocolBreakpoint.id(), buildDebuggerLocation(debuggerBreakpoint)); 1045 1068 } 1046 1069 } … … 1053 1076 void InspectorDebuggerAgent::willRunMicrotask() 1054 1077 { 1055 if (! m_scriptDebugServer.breakpointsActive())1078 if (!breakpointsActive()) 1056 1079 return; 1057 1080 1058 1081 if (m_pauseOnMicrotasks) 1059 schedulePause OnNextStatement(DebuggerFrontendDispatcher::Reason::Microtask, nullptr);1082 schedulePauseAtNextOpportunity(DebuggerFrontendDispatcher::Reason::Microtask); 1060 1083 } 1061 1084 1062 1085 void InspectorDebuggerAgent::didRunMicrotask() 1063 1086 { 1064 if (! m_scriptDebugServer.breakpointsActive())1087 if (!breakpointsActive()) 1065 1088 return; 1066 1089 1067 1090 if (m_pauseOnMicrotasks) 1068 cancelPause OnNextStatement();1069 } 1070 1071 void InspectorDebuggerAgent::didPause(JSC::JSGlobalObject* globalObject, JSC:: JSValue callFrames, JSC::JSValue exceptionOrCaughtValue)1091 cancelPauseAtNextOpportunity(); 1092 } 1093 1094 void InspectorDebuggerAgent::didPause(JSC::JSGlobalObject* globalObject, JSC::DebuggerCallFrame& debuggerCallFrame, JSC::JSValue exceptionOrCaughtValue) 1072 1095 { 1073 1096 ASSERT(!m_pausedGlobalObject); 1074 1097 m_pausedGlobalObject = globalObject; 1075 m_currentCallStack = { globalObject->vm(), callFrames }; 1076 1077 InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(globalObject); 1098 1099 auto* debuggerGlobalObject = debuggerCallFrame.scope()->globalObject(); 1100 m_currentCallStack = { m_pausedGlobalObject->vm(), toJS(debuggerGlobalObject, debuggerGlobalObject, JavaScriptCallFrame::create(debuggerCallFrame).ptr()) }; 1101 1102 InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(m_pausedGlobalObject); 1078 1103 1079 1104 // If a high level pause pause reason is not already set, try to infer a reason from the debugger. … … 1082 1107 case JSC::Debugger::PausedForBreakpoint: { 1083 1108 auto debuggerBreakpointId = m_scriptDebugServer.pausingBreakpointID(); 1084 if ( debuggerBreakpointId != m_continueToLocationBreakpointID)1109 if (!m_continueToLocationDebuggerBreakpoint || debuggerBreakpointId != m_continueToLocationDebuggerBreakpoint->id()) 1085 1110 updatePauseReasonAndData(DebuggerFrontendDispatcher::Reason::Breakpoint, buildBreakpointPauseReason(debuggerBreakpointId)); 1086 1111 break; … … 1120 1145 RefPtr<JSON::Object> data; 1121 1146 if (auto debuggerBreakpointId = m_scriptDebugServer.pausingBreakpointID()) { 1122 ASSERT( debuggerBreakpointId != m_continueToLocationBreakpointID);1147 ASSERT(!m_continueToLocationDebuggerBreakpoint || debuggerBreakpointId != m_continueToLocationDebuggerBreakpoint->id()); 1123 1148 data = JSON::Object::create(); 1124 1149 data->setString("originalReason"_s, Protocol::InspectorHelpers::getEnumConstantValue(DebuggerFrontendDispatcher::Reason::Breakpoint)); … … 1152 1177 m_javaScriptPauseScheduled = false; 1153 1178 1154 if (m_continueToLocation BreakpointID != JSC::noBreakpointID) {1155 m_scriptDebugServer.removeBreakpoint( m_continueToLocationBreakpointID);1156 m_continueToLocation BreakpointID = JSC::noBreakpointID;1179 if (m_continueToLocationDebuggerBreakpoint) { 1180 m_scriptDebugServer.removeBreakpoint(*m_continueToLocationDebuggerBreakpoint); 1181 m_continueToLocationDebuggerBreakpoint = nullptr; 1157 1182 } 1158 1183 … … 1164 1189 } 1165 1190 1166 void InspectorDebuggerAgent::breakpointActionSound( int breakpointActionIdentifier)1167 { 1168 m_frontendDispatcher->playBreakpointActionSound( breakpointActionIdentifier);1169 } 1170 1171 void InspectorDebuggerAgent::breakpointActionProbe(JSC::JSGlobalObject* globalObject, const ScriptBreakpointAction& action, unsigned batchId, unsigned sampleId, JSC::JSValue sample)1191 void InspectorDebuggerAgent::breakpointActionSound(JSC::BreakpointActionID id) 1192 { 1193 m_frontendDispatcher->playBreakpointActionSound(id); 1194 } 1195 1196 void InspectorDebuggerAgent::breakpointActionProbe(JSC::JSGlobalObject* globalObject, JSC::BreakpointActionID actionID, unsigned batchId, unsigned sampleId, JSC::JSValue sample) 1172 1197 { 1173 1198 InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(globalObject); 1174 auto payload = injectedScript.wrapObject(sample, objectGroupForBreakpointAction(action ), true);1199 auto payload = injectedScript.wrapObject(sample, objectGroupForBreakpointAction(actionID), true); 1175 1200 auto result = Protocol::Debugger::ProbeSample::create() 1176 .setProbeId(action .identifier)1201 .setProbeId(actionID) 1177 1202 .setBatchId(batchId) 1178 1203 .setSampleId(sampleId) … … 1210 1235 { 1211 1236 ErrorString ignored; 1212 for (const String& identifier : copyToVector(m_breakpointIdentifierToDebugServerBreakpointIDs.keys())) 1213 removeBreakpoint(ignored, identifier); 1214 1215 m_javaScriptBreakpoints.clear(); 1237 for (auto& protocolBreakpointID : copyToVector(m_debuggerBreakpointsForProtocolBreakpointID.keys())) 1238 removeBreakpoint(ignored, protocolBreakpointID); 1239 1240 m_protocolBreakpointForProtocolBreakpointID.clear(); 1241 1242 if (m_continueToLocationDebuggerBreakpoint) { 1243 m_scriptDebugServer.removeBreakpoint(*m_continueToLocationDebuggerBreakpoint); 1244 m_continueToLocationDebuggerBreakpoint = nullptr; 1245 } 1216 1246 1217 1247 clearDebuggerBreakpointState(); … … 1222 1252 { 1223 1253 JSC::JSLockHolder holder(m_scriptDebugServer.vm()); 1224 m_scriptDebugServer.clearBreakpointActions();1225 1254 m_scriptDebugServer.clearBreakpoints(); 1226 1255 m_scriptDebugServer.clearBlackbox(); … … 1230 1259 m_currentCallStack = { }; 1231 1260 m_scripts.clear(); 1232 m_breakpointIdentifierToDebugServerBreakpointIDs.clear(); 1233 m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier.clear(); 1234 m_continueToLocationBreakpointID = JSC::noBreakpointID; 1261 m_protocolBreakpointForProtocolBreakpointID.clear(); 1262 m_debuggerBreakpointsForProtocolBreakpointID.clear(); 1263 m_nextDebuggerBreakpointID = JSC::noBreakpointID + 1; 1264 m_continueToLocationDebuggerBreakpoint = nullptr; 1235 1265 clearPauseDetails(); 1236 1266 m_javaScriptPauseScheduled = false; -
trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h
r262786 r266074 30 30 #pragma once 31 31 32 #include "Breakpoint.h" 32 33 #include "Debugger.h" 34 #include "DebuggerPrimitives.h" 33 35 #include "InspectorAgentBase.h" 34 36 #include "InspectorBackendDispatchers.h" 35 37 #include "InspectorFrontendDispatchers.h" 36 #include "ScriptBreakpoint.h"37 #include "ScriptDebugListener.h"38 38 #include <wtf/Forward.h> 39 39 #include <wtf/HashMap.h> 40 40 #include <wtf/HashSet.h> 41 41 #include <wtf/Noncopyable.h> 42 #include <wtf/Optional.h> 43 #include <wtf/RefPtr.h> 42 44 #include <wtf/Vector.h> 43 45 … … 47 49 class InjectedScript; 48 50 class InjectedScriptManager; 49 class ScriptDebugServer;50 51 typedef String ErrorString; 51 52 52 class JS_EXPORT_PRIVATE InspectorDebuggerAgent : public InspectorAgentBase, public DebuggerBackendDispatcherHandler, public ScriptDebugListener {53 class JS_EXPORT_PRIVATE InspectorDebuggerAgent : public InspectorAgentBase, public DebuggerBackendDispatcherHandler, public JSC::Debugger::Observer { 53 54 WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent); 54 55 WTF_MAKE_FAST_ALLOCATED; 55 56 public: 56 57 ~InspectorDebuggerAgent() override; 58 59 static RefPtr<JSC::Breakpoint> debuggerBreakpointFromPayload(ErrorString&, const JSON::Object* optionsPayload); 57 60 58 61 static const char* const backtraceObjectGroup; … … 69 72 void setBreakpointsActive(ErrorString&, bool active) final; 70 73 void setBreakpointByUrl(ErrorString&, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const JSON::Object* options, Protocol::Debugger::BreakpointId*, RefPtr<JSON::ArrayOf<Protocol::Debugger::Location>>& locations) final; 71 void setBreakpoint(ErrorString&, const JSON::Object& location, const JSON::Object* options, Protocol::Debugger::BreakpointId* , RefPtr<Protocol::Debugger::Location>& actualLocation) final;74 void setBreakpoint(ErrorString&, const JSON::Object& location, const JSON::Object* options, Protocol::Debugger::BreakpointId* outBreakpointId, RefPtr<Protocol::Debugger::Location>& outActualLocation) final; 72 75 void removeBreakpoint(ErrorString&, const String& breakpointIdentifier) final; 73 76 void continueUntilNextRunLoop(ErrorString&) final; … … 90 93 void setShouldBlackboxURL(ErrorString&, const String& url, bool shouldBlackbox, const bool* caseSensitive, const bool* isRegex) final; 91 94 92 // ScriptDebugListener93 void didParseSource(JSC::SourceID, const Script&) final;95 // JSC::Debugger::Observer 96 void didParseSource(JSC::SourceID, const JSC::Debugger::Script&) final; 94 97 void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) final; 95 98 void willRunMicrotask() final; 96 99 void didRunMicrotask() final; 97 void didPause(JSC::JSGlobalObject*, JSC:: JSValue callFrames, JSC::JSValue exceptionOrCaughtValue) final;100 void didPause(JSC::JSGlobalObject*, JSC::DebuggerCallFrame&, JSC::JSValue exceptionOrCaughtValue) final; 98 101 void didContinue() final; 99 void breakpointActionSound( int breakpointActionIdentifier) final;100 void breakpointActionProbe(JSC::JSGlobalObject*, const ScriptBreakpointAction&, unsigned batchId, unsigned sampleId, JSC::JSValue sample) final;102 void breakpointActionSound(JSC::BreakpointActionID) final; 103 void breakpointActionProbe(JSC::JSGlobalObject*, JSC::BreakpointActionID, unsigned batchId, unsigned sampleId, JSC::JSValue sample) final; 101 104 102 105 bool isPaused() const; … … 119 122 void didDispatchAsyncCall(); 120 123 121 void schedulePause OnNextStatement(DebuggerFrontendDispatcher::Reason, RefPtr<JSON::Object>&& data);122 void cancelPause OnNextStatement();124 void schedulePauseAtNextOpportunity(DebuggerFrontendDispatcher::Reason, RefPtr<JSON::Object>&& data = nullptr); 125 void cancelPauseAtNextOpportunity(); 123 126 bool pauseOnNextStatementEnabled() const { return m_javaScriptPauseScheduled; } 127 128 bool schedulePauseForSpecialBreakpoint(JSC::Breakpoint&, DebuggerFrontendDispatcher::Reason, RefPtr<JSON::Object>&& data = nullptr); 129 bool cancelPauseForSpecialBreakpoint(JSC::Breakpoint&); 124 130 125 131 void breakProgram(DebuggerFrontendDispatcher::Reason, RefPtr<JSON::Object>&& data); … … 143 149 virtual InjectedScript injectedScriptForEval(ErrorString&, const int* executionContextId) = 0; 144 150 145 ScriptDebugServer& scriptDebugServer() { return m_scriptDebugServer; }151 JSC::Debugger& scriptDebugServer() { return m_scriptDebugServer; } 146 152 147 153 virtual void muteConsole() = 0; 148 154 virtual void unmuteConsole() = 0; 149 155 150 virtual String sourceMapURLForScript(const Script&);156 virtual String sourceMapURLForScript(const JSC::Debugger::Script&); 151 157 152 158 void didClearGlobalObject(); … … 158 164 Ref<JSON::ArrayOf<Protocol::Debugger::CallFrame>> currentCallFrames(const InjectedScript&); 159 165 160 void resolveBreakpoint(const Script&, JSC::Breakpoint&); 161 void setBreakpoint(JSC::Breakpoint&, bool& existing); 162 void didSetBreakpoint(const JSC::Breakpoint&, const String&, const ScriptBreakpoint&); 166 class ProtocolBreakpoint { 167 WTF_MAKE_FAST_ALLOCATED; 168 public: 169 static Optional<ProtocolBreakpoint> fromPayload(ErrorString&, JSC::SourceID, unsigned lineNumber, unsigned columnNumber, const JSON::Object* optionsPayload = nullptr); 170 static Optional<ProtocolBreakpoint> fromPayload(ErrorString&, const String& url, bool isRegex, unsigned lineNumber, unsigned columnNumber, const JSON::Object* optionsPayload = nullptr); 171 172 ProtocolBreakpoint(); 173 ProtocolBreakpoint(JSC::SourceID, unsigned lineNumber, unsigned columnNumber, const String& condition = nullString(), JSC::Breakpoint::ActionsVector&& actions = { }, bool autoContinue = false, size_t ignoreCount = 0); 174 ProtocolBreakpoint(const String& url, bool isRegex, unsigned lineNumber, unsigned columnNumber, const String& condition = nullString(), JSC::Breakpoint::ActionsVector&& actions = { }, bool autoContinue = false, size_t ignoreCount = 0); 175 176 Ref<JSC::Breakpoint> createDebuggerBreakpoint(JSC::BreakpointID, JSC::SourceID) const; 177 178 const Inspector::Protocol::Debugger::BreakpointId& id() const { return m_id; } 179 180 bool matchesScriptURL(const String&) const; 181 182 private: 183 Inspector::Protocol::Debugger::BreakpointId m_id; 184 185 #if ASSERT_ENABLED 186 JSC::SourceID m_sourceID { JSC::noSourceID }; 187 #endif 188 String m_url; 189 bool m_isRegex { false }; 190 191 // FIXME: <https://webkit.org/b/162771> Web Inspector: Adopt TextPosition in Inspector to avoid oneBasedInt/zeroBasedInt ambiguity 192 unsigned m_lineNumber { 0 }; 193 unsigned m_columnNumber { 0 }; 194 195 String m_condition; 196 JSC::Breakpoint::ActionsVector m_actions; 197 bool m_autoContinue { false }; 198 size_t m_ignoreCount { 0 }; 199 }; 200 201 bool resolveBreakpoint(const JSC::Debugger::Script&, JSC::Breakpoint&); 202 bool setBreakpoint(JSC::Breakpoint&); 203 void didSetBreakpoint(ProtocolBreakpoint&, JSC::Breakpoint&); 163 204 164 205 bool assertPaused(ErrorString&); … … 179 220 RefPtr<JSON::Object> buildExceptionPauseReason(JSC::JSValue exception, const InjectedScript&); 180 221 181 bool breakpointActionsFromProtocol(ErrorString&, RefPtr<JSON::Array>& actions, BreakpointActions* result);182 183 222 typedef std::pair<unsigned, int> AsyncCallIdentifier; 184 223 static AsyncCallIdentifier asyncCallIdentifier(AsyncCallType, int callbackId); … … 187 226 RefPtr<DebuggerBackendDispatcher> m_backendDispatcher; 188 227 189 ScriptDebugServer& m_scriptDebugServer;228 JSC::Debugger& m_scriptDebugServer; 190 229 InjectedScriptManager& m_injectedScriptManager; 191 HashMap<JSC::SourceID, Script> m_scripts;230 HashMap<JSC::SourceID, JSC::Debugger::Script> m_scripts; 192 231 193 232 struct BlackboxConfig { … … 210 249 JSC::Strong<JSC::Unknown> m_currentCallStack; 211 250 212 HashMap<String, Vector<JSC::BreakpointID>> m_breakpointIdentifierToDebugServerBreakpointIDs; 213 HashMap<String, RefPtr<JSON::Object>> m_javaScriptBreakpoints; 214 HashMap<JSC::BreakpointID, String> m_debuggerBreakpointIdentifierToInspectorBreakpointIdentifier; 215 JSC::BreakpointID m_continueToLocationBreakpointID { JSC::noBreakpointID }; 251 HashMap<Inspector::Protocol::Debugger::BreakpointId, ProtocolBreakpoint> m_protocolBreakpointForProtocolBreakpointID; 252 HashMap<Inspector::Protocol::Debugger::BreakpointId, JSC::BreakpointsVector> m_debuggerBreakpointsForProtocolBreakpointID; 253 JSC::BreakpointID m_nextDebuggerBreakpointID { JSC::noBreakpointID + 1 }; 254 255 RefPtr<JSC::Breakpoint> m_continueToLocationDebuggerBreakpoint; 256 216 257 ShouldDispatchResumed m_conditionToDispatchResumed { ShouldDispatchResumed::No }; 217 258 -
trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
r265142 r266074 35 35 #include "Completion.h" 36 36 #include "ControlFlowProfiler.h" 37 #include "Debugger.h" 37 38 #include "InjectedScript.h" 38 39 #include "InjectedScriptHost.h" … … 40 41 #include "JSLock.h" 41 42 #include "ParserError.h" 42 #include "ScriptDebugServer.h"43 43 #include "SourceCode.h" 44 44 #include "TypeProfiler.h" … … 74 74 } 75 75 76 static ScriptDebugServer::PauseOnExceptionsState setPauseOnExceptionsState(ScriptDebugServer& scriptDebugServer, ScriptDebugServer::PauseOnExceptionsState newState)76 static JSC::Debugger::PauseOnExceptionsState setPauseOnExceptionsState(JSC::Debugger& scriptDebugServer, JSC::Debugger::PauseOnExceptionsState newState) 77 77 { 78 78 auto presentState = scriptDebugServer.pauseOnExceptionsState(); … … 124 124 return; 125 125 126 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = ScriptDebugServer::DontPauseOnExceptions;126 auto previousPauseOnExceptionsState = JSC::Debugger::DontPauseOnExceptions; 127 127 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) 128 previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);128 previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, JSC::Debugger::DontPauseOnExceptions); 129 129 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) 130 130 muteConsole(); … … 166 166 arguments = optionalArguments->toJSONString(); 167 167 168 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = ScriptDebugServer::DontPauseOnExceptions;168 auto previousPauseOnExceptionsState = JSC::Debugger::DontPauseOnExceptions; 169 169 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) 170 previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);170 previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, JSC::Debugger::DontPauseOnExceptions); 171 171 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) 172 172 muteConsole(); … … 188 188 } 189 189 190 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);190 auto previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, JSC::Debugger::DontPauseOnExceptions); 191 191 muteConsole(); 192 192 … … 217 217 } 218 218 219 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);219 auto previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, JSC::Debugger::DontPauseOnExceptions); 220 220 muteConsole(); 221 221 … … 250 250 } 251 251 252 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);252 auto previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, JSC::Debugger::DontPauseOnExceptions); 253 253 muteConsole(); 254 254 -
trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
r251620 r266074 38 38 39 39 namespace JSC { 40 class Debugger; 40 41 class VM; 41 42 } … … 45 46 class InjectedScript; 46 47 class InjectedScriptManager; 47 class ScriptDebugServer;48 48 typedef String ErrorString; 49 49 … … 95 95 96 96 InjectedScriptManager& m_injectedScriptManager; 97 ScriptDebugServer& m_scriptDebugServer;97 JSC::Debugger& m_scriptDebugServer; 98 98 JSC::VM& m_vm; 99 99 bool m_enabled {false}; -
trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp
r261895 r266074 27 27 #include "InspectorScriptProfilerAgent.h" 28 28 29 #include "Debugger.h" 29 30 #include "DeferGC.h" 30 31 #include "HeapInlines.h" 31 32 #include "InspectorEnvironment.h" 32 33 #include "SamplingProfiler.h" 33 #include "ScriptDebugServer.h"34 34 #include <wtf/Stopwatch.h> 35 35 -
trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectDebuggerAgent.h
r261569 r266074 39 39 ~JSGlobalObjectDebuggerAgent() final; 40 40 41 // ScriptDebugListener42 void breakpointActionLog(JSC::JSGlobalObject*, const String& ) final;41 // JSC::Debugger::Observer 42 void breakpointActionLog(JSC::JSGlobalObject*, const String& data) final; 43 43 44 44 private: -
trunk/Source/JavaScriptCore/inspector/protocol/DOM.json
r262302 r266074 317 317 "targetTypes": ["page"], 318 318 "parameters": [ 319 { "name": "eventListenerId", "$ref": "EventListenerId" } 319 { "name": "eventListenerId", "$ref": "EventListenerId" }, 320 { "name": "options", "$ref": "Debugger.BreakpointOptions", "optional": true, "description": "Options to apply to this breakpoint to modify its behavior." } 320 321 ] 321 322 }, -
trunk/Source/JavaScriptCore/inspector/protocol/DOMDebugger.json
r251227 r266074 40 40 "parameters": [ 41 41 { "name": "breakpointType", "$ref": "EventBreakpointType" }, 42 { "name": "eventName", "type": "string", "optional": true, "description": "The name of the specific event to stop on." } 42 { "name": "eventName", "type": "string", "optional": true, "description": "The name of the specific event to stop on." }, 43 { "name": "options", "$ref": "Debugger.BreakpointOptions", "optional": true, "description": "Options to apply to this breakpoint to modify its behavior." } 43 44 ] 44 45 }, -
trunk/Source/JavaScriptCore/runtime/JSMicrotask.cpp
r261755 r266074 92 92 profiledCall(globalObject, ProfilingReason::Microtask, m_job.get(), handlerCallData, jsUndefined(), handlerArguments); 93 93 scope.clearException(); 94 95 if (UNLIKELY(globalObject->hasDebugger())) 96 globalObject->debugger()->didRunMicrotask(); 94 97 } 95 98 -
trunk/Source/WebCore/ChangeLog
r266063 r266074 1 2020-08-24 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: allow event breakpoints to be configured 4 https://bugs.webkit.org/show_bug.cgi?id=215362 5 <rdar://problem/66932921> 6 7 Reviewed by Brian Burg. 8 9 This allows developers to do things like: 10 - only pause when `window.event.type` is a certain value 11 - ignore the first N pauses 12 - evaluate JavaScript whenever an event listener is invoked without pausing 13 14 Tests: inspector/dom/breakpoint-for-event-listener.html 15 inspector/dom-debugger/event-animation-frame-breakpoints.html 16 inspector/dom-debugger/event-interval-breakpoints.html 17 inspector/dom-debugger/event-listener-breakpoints.html 18 inspector/dom-debugger/event-timeout-breakpoints.html 19 20 * inspector/agents/InspectorDOMAgent.h: 21 * inspector/agents/InspectorDOMAgent.cpp: 22 (WebCore::InspectorDOMAgent::getEventListenersForNode): 23 (WebCore::InspectorDOMAgent::setBreakpointForEventListener): 24 (WebCore::InspectorDOMAgent::removeBreakpointForEventListener): 25 (WebCore::InspectorDOMAgent::buildObjectForEventListener): 26 (WebCore::InspectorDOMAgent::breakpointForEventListener): 27 (WebCore::InspectorDOMAgent::hasBreakpointForEventListener): Deleted. 28 * inspector/agents/InspectorDOMDebuggerAgent.h: 29 * inspector/agents/InspectorDOMDebuggerAgent.cpp: 30 (WebCore::InspectorDOMDebuggerAgent::disable): 31 (WebCore::InspectorDOMDebuggerAgent::mainFrameNavigated): 32 (WebCore::InspectorDOMDebuggerAgent::setEventBreakpoint): 33 (WebCore::InspectorDOMDebuggerAgent::removeEventBreakpoint): 34 (WebCore::InspectorDOMDebuggerAgent::willHandleEvent): 35 (WebCore::InspectorDOMDebuggerAgent::didHandleEvent): 36 (WebCore::InspectorDOMDebuggerAgent::willFireTimer): 37 (WebCore::InspectorDOMDebuggerAgent::didFireTimer): 38 * inspector/agents/page/PageDOMDebuggerAgent.h: 39 * inspector/agents/page/PageDOMDebuggerAgent.cpp: 40 (WebCore::PageDOMDebuggerAgent::disable): 41 (WebCore::PageDOMDebuggerAgent::mainFrameNavigated): 42 (WebCore::PageDOMDebuggerAgent::willFireAnimationFrame): 43 (WebCore::PageDOMDebuggerAgent::didFireAnimationFrame): 44 (WebCore::PageDOMDebuggerAgent::setAnimationFrameBreakpoint): 45 * inspector/agents/worker/WorkerDOMDebuggerAgent.h: 46 * inspector/agents/worker/WorkerDOMDebuggerAgent.cpp: 47 (WebCore::WorkerDOMDebuggerAgent::setAnimationFrameBreakpoint): 48 Keep a `JSC::Breakpoint` for each event breakpoint instead of a simple `bool`, allowing for 49 configuration when the breakpoint is first set. When any of these breakpoints are hit, pass 50 it to the `JSC::Debugger` as a "special breakpoint", which behaves the same as "pause ASAP" 51 but also supports a condition, an ignore count, actions, and auto-continue. Reset the hit 52 count for any of these "special breakpoints" that persist across Web Inspector sessions 53 when the main frame navigates. 54 55 * inspector/PageScriptDebugServer.h: 56 * inspector/PageScriptDebugServer.cpp: 57 (WebCore::PageScriptDebugServer::PageScriptDebugServer): 58 (WebCore::PageScriptDebugServer::attachDebugger): 59 (WebCore::PageScriptDebugServer::detachDebugger): 60 (WebCore::PageScriptDebugServer::didPause): 61 (WebCore::PageScriptDebugServer::didContinue): 62 (WebCore::PageScriptDebugServer::runEventLoopWhilePaused): 63 (WebCore::PageScriptDebugServer::runEventLoopWhilePausedInternal): 64 (WebCore::PageScriptDebugServer::isContentScript const): 65 (WebCore::PageScriptDebugServer::reportException const): 66 * inspector/WorkerScriptDebugServer.h: 67 * inspector/WorkerScriptDebugServer.cpp: 68 (WebCore::WorkerScriptDebugServer::WorkerScriptDebugServer): 69 (WebCore::WorkerScriptDebugServer::attachDebugger): 70 (WebCore::WorkerScriptDebugServer::detachDebugger): 71 (WebCore::WorkerScriptDebugServer::runEventLoopWhilePaused): 72 (WebCore::WorkerScriptDebugServer::reportException const): 73 * inspector/agents/page/PageDebuggerAgent.h: 74 * inspector/agents/page/PageDebuggerAgent.cpp: 75 (WebCore::PageDebuggerAgent::sourceMapURLForScript): 76 Replace `Inspector::ScriptDebugServer` with `JSC::Debugger`. 77 78 * inspector/TimelineRecordFactory.h: 79 * inspector/TimelineRecordFactory.cpp: 80 (WebCore::TimelineRecordFactory::createProbeSampleData): 81 * inspector/agents/InspectorTimelineAgent.h: 82 * inspector/agents/InspectorTimelineAgent.cpp: 83 (WebCore::InspectorTimelineAgent::internalStart): 84 (WebCore::InspectorTimelineAgent::internalStop): 85 (WebCore::InspectorTimelineAgent::breakpointActionProbe): 86 Replace `Inspector::ScriptBreakpoint` with `JSC::Breakpoint`. 87 88 * inspector/InspectorInstrumentation.h: 89 (WebCore::InspectorInstrumentation::didHandleEvent): 90 (WebCore::InspectorInstrumentation::didFireTimer): 91 * inspector/InspectorInstrumentation.cpp: 92 (WebCore::InspectorInstrumentation::didHandleEventImpl): 93 (WebCore::InspectorInstrumentation::didFireTimerImpl): 94 (WebCore::InspectorInstrumentation::didCommitLoadImpl): 95 (WebCore::InspectorInstrumentation::didFireAnimationFrameImpl): 96 97 * dom/EventTarget.cpp: 98 (WebCore::EventTarget::innerInvokeEventListeners): 99 * page/DOMTimer.cpp: 100 (WebCore::DOMTimer::fired): 101 When notifying Web Inspector that activity did occur, include all information previously 102 included when notifying Web Inspector that that activity was about to occur so that Web 103 Inspector can know whether a pause for the "special breakpoint" for that activity is still 104 scheduled and if so cancel it. 105 1 106 2020-08-24 Aditya Keerthi <akeerthi@apple.com> 2 107 -
trunk/Source/WebCore/dom/EventTarget.cpp
r265623 r266074 331 331 InspectorInstrumentation::willHandleEvent(context, event, *registeredListener); 332 332 registeredListener->callback().handleEvent(context, event); 333 InspectorInstrumentation::didHandleEvent(context );333 InspectorInstrumentation::didHandleEvent(context, event, *registeredListener); 334 334 335 335 if (registeredListener->isPassive()) -
trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp
r263119 r266074 419 419 } 420 420 421 void InspectorInstrumentation::didHandleEventImpl(InstrumentingAgents& instrumentingAgents )421 void InspectorInstrumentation::didHandleEventImpl(InstrumentingAgents& instrumentingAgents, Event& event, const RegisteredEventListener& listener) 422 422 { 423 423 if (auto* webDebuggerAgent = instrumentingAgents.enabledWebDebuggerAgent()) … … 425 425 426 426 if (auto* domDebuggerAgent = instrumentingAgents.enabledDOMDebuggerAgent()) 427 domDebuggerAgent->didHandleEvent( );427 domDebuggerAgent->didHandleEvent(event, listener); 428 428 } 429 429 … … 474 474 } 475 475 476 void InspectorInstrumentation::didFireTimerImpl(InstrumentingAgents& instrumentingAgents )476 void InspectorInstrumentation::didFireTimerImpl(InstrumentingAgents& instrumentingAgents, int /* timerId */, bool oneShot) 477 477 { 478 478 if (auto* webDebuggerAgent = instrumentingAgents.enabledWebDebuggerAgent()) 479 479 webDebuggerAgent->didDispatchAsyncCall(); 480 if (auto* domDebuggerAgent = instrumentingAgents.enabledDOMDebuggerAgent()) 481 domDebuggerAgent->didFireTimer(oneShot); 480 482 if (auto* timelineAgent = instrumentingAgents.trackingTimelineAgent()) 481 483 timelineAgent->didFireTimer(); … … 716 718 if (auto* pageDebuggerAgent = instrumentingAgents.enabledPageDebuggerAgent()) 717 719 pageDebuggerAgent->mainFrameNavigated(); 720 721 if (auto* domDebuggerAgent = instrumentingAgents.enabledDOMDebuggerAgent()) 722 domDebuggerAgent->mainFrameNavigated(); 718 723 719 724 if (auto* enabledPageHeapAgent = instrumentingAgents.enabledPageHeapAgent()) … … 1263 1268 if (auto* webDebuggerAgent = instrumentingAgents.enabledWebDebuggerAgent()) 1264 1269 webDebuggerAgent->didDispatchAsyncCall(); 1270 if (auto* pageDOMDebuggerAgent = instrumentingAgents.enabledPageDOMDebuggerAgent()) 1271 pageDOMDebuggerAgent->didFireAnimationFrame(); 1265 1272 if (auto* timelineAgent = instrumentingAgents.trackingTimelineAgent()) 1266 1273 timelineAgent->didFireAnimationFrame(); -
trunk/Source/WebCore/inspector/InspectorInstrumentation.h
r263119 r266074 172 172 static void didDispatchEvent(Document&, const Event&); 173 173 static void willHandleEvent(ScriptExecutionContext&, Event&, const RegisteredEventListener&); 174 static void didHandleEvent(ScriptExecutionContext& );174 static void didHandleEvent(ScriptExecutionContext&, Event&, const RegisteredEventListener&); 175 175 static void willDispatchEventOnWindow(Frame*, const Event&, DOMWindow&); 176 176 static void didDispatchEventOnWindow(Frame*, const Event&); … … 179 179 static void didEvaluateScript(Frame&); 180 180 static void willFireTimer(ScriptExecutionContext&, int timerId, bool oneShot); 181 static void didFireTimer(ScriptExecutionContext& );181 static void didFireTimer(ScriptExecutionContext&, int timerId, bool oneShot); 182 182 static void didInvalidateLayout(Frame&); 183 183 static void willLayout(Frame&); … … 395 395 static void willDispatchEventImpl(InstrumentingAgents&, Document&, const Event&); 396 396 static void willHandleEventImpl(InstrumentingAgents&, Event&, const RegisteredEventListener&); 397 static void didHandleEventImpl(InstrumentingAgents& );397 static void didHandleEventImpl(InstrumentingAgents&, Event&, const RegisteredEventListener&); 398 398 static void didDispatchEventImpl(InstrumentingAgents&, const Event&); 399 399 static void willDispatchEventOnWindowImpl(InstrumentingAgents&, const Event&, DOMWindow&); … … 403 403 static void didEvaluateScriptImpl(InstrumentingAgents&, Frame&); 404 404 static void willFireTimerImpl(InstrumentingAgents&, int timerId, bool oneShot, ScriptExecutionContext&); 405 static void didFireTimerImpl(InstrumentingAgents& );405 static void didFireTimerImpl(InstrumentingAgents&, int timerId, bool oneShot); 406 406 static void didInvalidateLayoutImpl(InstrumentingAgents&, Frame&); 407 407 static void willLayoutImpl(InstrumentingAgents&, Frame&); … … 893 893 } 894 894 895 inline void InspectorInstrumentation::didHandleEvent(ScriptExecutionContext& context )895 inline void InspectorInstrumentation::didHandleEvent(ScriptExecutionContext& context, Event& event, const RegisteredEventListener& listener) 896 896 { 897 897 FAST_RETURN_IF_NO_FRONTENDS(void()); 898 898 if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context)) 899 return didHandleEventImpl(*instrumentingAgents );899 return didHandleEventImpl(*instrumentingAgents, event, listener); 900 900 } 901 901 … … 947 947 } 948 948 949 inline void InspectorInstrumentation::didFireTimer(ScriptExecutionContext& context )949 inline void InspectorInstrumentation::didFireTimer(ScriptExecutionContext& context, int timerId, bool oneShot) 950 950 { 951 951 FAST_RETURN_IF_NO_FRONTENDS(void()); 952 952 if (auto* instrumentingAgents = instrumentingAgentsForContext(context)) 953 didFireTimerImpl(*instrumentingAgents );953 didFireTimerImpl(*instrumentingAgents, timerId, oneShot); 954 954 } 955 955 -
trunk/Source/WebCore/inspector/PageScriptDebugServer.cpp
r263432 r266074 55 55 56 56 PageScriptDebugServer::PageScriptDebugServer(Page& page) 57 : ScriptDebugServer(WebCore::commonVM())57 : Debugger(WebCore::commonVM()) 58 58 , m_page(page) 59 59 { … … 62 62 void PageScriptDebugServer::attachDebugger() 63 63 { 64 JSC::Debugger::attachDebugger(); 65 64 66 m_page.setDebugger(this); 65 67 } … … 67 69 void PageScriptDebugServer::detachDebugger(bool isBeingDestroyed) 68 70 { 71 JSC::Debugger::detachDebugger(isBeingDestroyed); 72 69 73 m_page.setDebugger(nullptr); 70 74 if (!isBeingDestroyed) … … 78 82 } 79 83 80 void PageScriptDebugServer::didPause(JSGlobalObject* )84 void PageScriptDebugServer::didPause(JSGlobalObject* globalObject) 81 85 { 86 JSC::Debugger::didPause(globalObject); 87 82 88 setJavaScriptPaused(m_page.group(), true); 83 89 } 84 90 85 void PageScriptDebugServer::didContinue(JSGlobalObject* )91 void PageScriptDebugServer::didContinue(JSGlobalObject* globalObject) 86 92 { 93 JSC::Debugger::didContinue(globalObject); 94 87 95 setJavaScriptPaused(m_page.group(), false); 88 96 } … … 90 98 void PageScriptDebugServer::runEventLoopWhilePaused() 91 99 { 100 JSC::Debugger::runEventLoopWhilePaused(); 101 92 102 #if PLATFORM(IOS_FAMILY) 93 103 // On iOS, running an EventLoop causes us to run a nested WebRunLoop. … … 116 126 m_page.incrementNestedRunLoopCount(); 117 127 118 while (! m_doneProcessingDebuggerEvents) {128 while (!doneProcessingDebuggerEvents()) { 119 129 if (!platformShouldContinueRunningEventLoopWhilePaused()) 120 130 break; … … 126 136 bool PageScriptDebugServer::isContentScript(JSGlobalObject* state) const 127 137 { 128 return ¤tWorld(*state) != &mainThreadNormalWorld() ;138 return ¤tWorld(*state) != &mainThreadNormalWorld() || JSC::Debugger::isContentScript(state); 129 139 } 130 140 131 141 void PageScriptDebugServer::reportException(JSGlobalObject* state, JSC::Exception* exception) const 132 142 { 143 JSC::Debugger::reportException(state, exception); 144 133 145 WebCore::reportException(state, exception); 134 146 } -
trunk/Source/WebCore/inspector/PageScriptDebugServer.h
r259931 r266074 27 27 #pragma once 28 28 29 #include <JavaScriptCore/ ScriptDebugServer.h>29 #include <JavaScriptCore/Debugger.h> 30 30 31 31 namespace WebCore { … … 35 35 class PageGroup; 36 36 37 class PageScriptDebugServer final : public Inspector::ScriptDebugServer {37 class PageScriptDebugServer final : public JSC::Debugger { 38 38 WTF_MAKE_NONCOPYABLE(PageScriptDebugServer); 39 39 WTF_MAKE_FAST_ALLOCATED; … … 45 45 46 46 private: 47 void attachDebugger() override;48 void detachDebugger(bool isBeingDestroyed) override;49 50 void didPause(JSC::JSGlobalObject*) override;51 void didContinue(JSC::JSGlobalObject*) override;52 void runEventLoopWhilePaused() override;53 bool isContentScript(JSC::JSGlobalObject*) const override;54 void reportException(JSC::JSGlobalObject*, JSC::Exception*) const override;47 // JSC::Debugger 48 void attachDebugger() final; 49 void detachDebugger(bool isBeingDestroyed) final; 50 void didPause(JSC::JSGlobalObject*) final; 51 void didContinue(JSC::JSGlobalObject*) final; 52 void runEventLoopWhilePaused() final; 53 bool isContentScript(JSC::JSGlobalObject*) const final; 54 void reportException(JSC::JSGlobalObject*, JSC::Exception*) const final; 55 55 56 56 void runEventLoopWhilePausedInternal(); -
trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp
r240323 r266074 37 37 #include "JSExecState.h" 38 38 #include <JavaScriptCore/InspectorProtocolObjects.h> 39 #include <JavaScriptCore/ScriptBreakpoint.h>40 39 #include <JavaScriptCore/ScriptCallStack.h> 41 40 #include <JavaScriptCore/ScriptCallStackFactory.h> … … 74 73 } 75 74 76 Ref<JSON::Object> TimelineRecordFactory::createProbeSampleData( const ScriptBreakpointAction& action, unsigned sampleId)75 Ref<JSON::Object> TimelineRecordFactory::createProbeSampleData(JSC::BreakpointActionID actionID, unsigned sampleId) 77 76 { 78 77 Ref<JSON::Object> data = JSON::Object::create(); 79 data->setInteger("probeId"_s, action .identifier);78 data->setInteger("probeId"_s, actionID); 80 79 data->setInteger("sampleId"_s, sampleId); 81 80 return data; -
trunk/Source/WebCore/inspector/TimelineRecordFactory.h
r240323 r266074 32 32 #pragma once 33 33 34 #include <JavaScriptCore/DebuggerPrimitives.h> 34 35 #include <wtf/Forward.h> 35 36 #include <wtf/JSONValues.h> 36 37 #include <wtf/Seconds.h> 37 38 #include <wtf/text/WTFString.h> 38 39 namespace Inspector {40 struct ScriptBreakpointAction;41 }42 39 43 40 namespace WebCore { … … 52 49 static Ref<JSON::Object> createFunctionCallData(const String& scriptName, int scriptLine, int scriptColumn); 53 50 static Ref<JSON::Object> createConsoleProfileData(const String& title); 54 static Ref<JSON::Object> createProbeSampleData( const Inspector::ScriptBreakpointAction&, unsigned sampleId);51 static Ref<JSON::Object> createProbeSampleData(JSC::BreakpointActionID, unsigned sampleId); 55 52 static Ref<JSON::Object> createEventDispatchData(const Event&); 56 53 static Ref<JSON::Object> createGenericTimerData(int timerId); -
trunk/Source/WebCore/inspector/WorkerScriptDebugServer.cpp
r251425 r266074 45 45 46 46 WorkerScriptDebugServer::WorkerScriptDebugServer(WorkerGlobalScope& context) 47 : ScriptDebugServer(context.script()->vm())47 : Debugger(context.script()->vm()) 48 48 , m_workerGlobalScope(context) 49 49 { … … 52 52 void WorkerScriptDebugServer::attachDebugger() 53 53 { 54 JSC::Debugger::attachDebugger(); 55 54 56 m_workerGlobalScope.script()->attachDebugger(this); 55 57 } … … 57 59 void WorkerScriptDebugServer::detachDebugger(bool isBeingDestroyed) 58 60 { 61 JSC::Debugger::detachDebugger(isBeingDestroyed); 62 59 63 if (m_workerGlobalScope.script()) 60 64 m_workerGlobalScope.script()->detachDebugger(this); … … 71 75 void WorkerScriptDebugServer::runEventLoopWhilePaused() 72 76 { 77 JSC::Debugger::runEventLoopWhilePaused(); 78 73 79 TimerBase::fireTimersInNestedEventLoop(); 74 80 … … 76 82 do { 77 83 result = m_workerGlobalScope.thread().runLoop().runInDebuggerMode(m_workerGlobalScope); 78 } while (result != MessageQueueTerminated && ! m_doneProcessingDebuggerEvents);84 } while (result != MessageQueueTerminated && !doneProcessingDebuggerEvents()); 79 85 } 80 86 81 87 void WorkerScriptDebugServer::reportException(JSC::JSGlobalObject* exec, JSC::Exception* exception) const 82 88 { 89 JSC::Debugger::reportException(exec, exception); 90 83 91 WebCore::reportException(exec, exception); 84 92 } -
trunk/Source/WebCore/inspector/WorkerScriptDebugServer.h
r251425 r266074 32 32 #pragma once 33 33 34 #include <JavaScriptCore/ ScriptDebugServer.h>34 #include <JavaScriptCore/Debugger.h> 35 35 36 36 namespace WebCore { … … 38 38 class WorkerGlobalScope; 39 39 40 class WorkerScriptDebugServer final : public Inspector::ScriptDebugServer {40 class WorkerScriptDebugServer final : public JSC::Debugger { 41 41 WTF_MAKE_NONCOPYABLE(WorkerScriptDebugServer); 42 42 WTF_MAKE_FAST_ALLOCATED; … … 45 45 ~WorkerScriptDebugServer() override = default; 46 46 47 void recompileAllJSFunctions() override;48 47 49 48 private: 50 void attachDebugger() override; 51 void detachDebugger(bool isBeingDestroyed) override; 52 53 void didPause(JSC::JSGlobalObject*) override { } 54 void didContinue(JSC::JSGlobalObject*) override { } 55 void runEventLoopWhilePaused() override; 56 bool isContentScript(JSC::JSGlobalObject*) const override { return false; } 57 void reportException(JSC::JSGlobalObject*, JSC::Exception*) const override; 49 // JSC::Debugger 50 void attachDebugger() final; 51 void detachDebugger(bool isBeingDestroyed) final; 52 void recompileAllJSFunctions() final; 53 void runEventLoopWhilePaused() final; 54 void reportException(JSC::JSGlobalObject*, JSC::Exception*) const final; 58 55 59 56 WorkerGlobalScope& m_workerGlobalScope; -
trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
r264585 r266074 113 113 #include <JavaScriptCore/InjectedScript.h> 114 114 #include <JavaScriptCore/InjectedScriptManager.h> 115 #include <JavaScriptCore/InspectorDebuggerAgent.h> 115 116 #include <JavaScriptCore/JSCInlines.h> 116 117 #include <pal/crypto/CryptoDigest.h> … … 932 933 int identifier = 0; 933 934 bool disabled = false; 934 bool hasBreakpoint = false;935 RefPtr<JSC::Breakpoint> breakpoint; 935 936 936 937 for (auto& inspectorEventListener : m_eventListenerEntries.values()) { … … 938 939 identifier = inspectorEventListener.identifier; 939 940 disabled = inspectorEventListener.disabled; 940 hasBreakpoint = inspectorEventListener.hasBreakpoint;941 breakpoint = inspectorEventListener.breakpoint; 941 942 break; 942 943 } … … 948 949 identifier = inspectorEventListener.identifier; 949 950 disabled = inspectorEventListener.disabled; 950 hasBreakpoint = inspectorEventListener.hasBreakpoint;951 breakpoint = inspectorEventListener.breakpoint; 951 952 952 953 m_eventListenerEntries.add(identifier, inspectorEventListener); 953 954 } 954 955 955 listenersArray->addItem(buildObjectForEventListener(listener, identifier, *info.eventTarget, info.eventType, disabled, hasBreakpoint));956 listenersArray->addItem(buildObjectForEventListener(listener, identifier, *info.eventTarget, info.eventType, disabled, breakpoint)); 956 957 }; 957 958 … … 989 990 } 990 991 991 void InspectorDOMAgent::setBreakpointForEventListener(ErrorString& errorString, int eventListenerId )992 void InspectorDOMAgent::setBreakpointForEventListener(ErrorString& errorString, int eventListenerId, const JSON::Object* optionsPayload) 992 993 { 993 994 auto it = m_eventListenerEntries.find(eventListenerId); … … 997 998 } 998 999 999 it->value.hasBreakpoint = true; 1000 if (it->value.breakpoint) { 1001 errorString = "Breakpoint for given eventListenerId already exists"_s; 1002 return; 1003 } 1004 1005 it->value.breakpoint = InspectorDebuggerAgent::debuggerBreakpointFromPayload(errorString, optionsPayload); 1000 1006 } 1001 1007 … … 1008 1014 } 1009 1015 1010 it->value.hasBreakpoint = false; 1016 if (!it->value.breakpoint) 1017 errorString = "Breakpoint for given eventListenerId missing"_s; 1018 1019 it->value.breakpoint = nullptr; 1011 1020 } 1012 1021 … … 1752 1761 } 1753 1762 1754 Ref<Inspector::Protocol::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, int identifier, EventTarget& eventTarget, const AtomString& eventType, bool disabled, bool hasBreakpoint)1763 Ref<Inspector::Protocol::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, int identifier, EventTarget& eventTarget, const AtomString& eventType, bool disabled, const RefPtr<JSC::Breakpoint>& breakpoint) 1755 1764 { 1756 1765 Ref<EventListener> eventListener = registeredEventListener.callback(); … … 1840 1849 if (disabled) 1841 1850 value->setDisabled(disabled); 1842 if ( hasBreakpoint)1843 value->setHasBreakpoint( hasBreakpoint);1851 if (breakpoint) 1852 value->setHasBreakpoint(breakpoint); 1844 1853 return value; 1845 1854 } … … 2549 2558 } 2550 2559 2551 bool InspectorDOMAgent::hasBreakpointForEventListener(EventTarget& target, const AtomString& eventType, EventListener& listener, bool capture)2560 RefPtr<JSC::Breakpoint> InspectorDOMAgent::breakpointForEventListener(EventTarget& target, const AtomString& eventType, EventListener& listener, bool capture) 2552 2561 { 2553 2562 for (auto& inspectorEventListener : m_eventListenerEntries.values()) { 2554 2563 if (inspectorEventListener.matches(target, eventType, listener, capture)) 2555 return inspectorEventListener. hasBreakpoint;2556 } 2557 return false;2564 return inspectorEventListener.breakpoint; 2565 } 2566 return nullptr; 2558 2567 } 2559 2568 -
trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h
r262302 r266074 33 33 #include "InspectorWebAgentBase.h" 34 34 #include "Timer.h" 35 #include <JavaScriptCore/Breakpoint.h> 35 36 #include <JavaScriptCore/InspectorBackendDispatchers.h> 36 37 #include <JavaScriptCore/InspectorFrontendDispatchers.h> … … 126 127 void getEventListenersForNode(ErrorString&, int nodeId, RefPtr<JSON::ArrayOf<Inspector::Protocol::DOM::EventListener>>& listenersArray) override; 127 128 void setEventListenerDisabled(ErrorString&, int eventListenerId, bool disabled) override; 128 void setBreakpointForEventListener(ErrorString&, int eventListenerId ) override;129 void setBreakpointForEventListener(ErrorString&, int eventListenerId, const JSON::Object* options) final; 129 130 void removeBreakpointForEventListener(ErrorString&, int eventListenerId) override; 130 131 void getAccessibilityPropertiesForNode(ErrorString&, int nodeId, RefPtr<Inspector::Protocol::DOM::AccessibilityProperties>& axProperties) override; … … 206 207 Document* assertDocument(ErrorString&, int nodeId); 207 208 208 bool hasBreakpointForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture);209 RefPtr<JSC::Breakpoint> breakpointForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture); 209 210 int idForEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture); 210 211 … … 232 233 Ref<JSON::ArrayOf<Inspector::Protocol::DOM::Node>> buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap); 233 234 RefPtr<JSON::ArrayOf<Inspector::Protocol::DOM::Node>> buildArrayForPseudoElements(const Element&, NodeToIdMap* nodesMap); 234 Ref<Inspector::Protocol::DOM::EventListener> buildObjectForEventListener(const RegisteredEventListener&, int identifier, EventTarget&, const AtomString& eventType, bool disabled, bool hasBreakpoint);235 Ref<Inspector::Protocol::DOM::EventListener> buildObjectForEventListener(const RegisteredEventListener&, int identifier, EventTarget&, const AtomString& eventType, bool disabled, const RefPtr<JSC::Breakpoint>&); 235 236 RefPtr<Inspector::Protocol::DOM::AccessibilityProperties> buildObjectForAccessibilityProperties(Node*); 236 237 void processAccessibilityChildren(AXCoreObject&, JSON::ArrayOf<int>&); … … 291 292 bool useCapture { false }; 292 293 bool disabled { false }; 293 bool hasBreakpoint { false };294 RefPtr<JSC::Breakpoint> breakpoint; 294 295 295 296 InspectorEventListener() { } -
trunk/Source/WebCore/inspector/agents/InspectorDOMDebuggerAgent.cpp
r262673 r266074 77 77 78 78 m_listenerBreakpoints.clear(); 79 m_pauseOnAllIntervalsBreakpoint = nullptr; 80 m_pauseOnAllListenersBreakpoint = nullptr; 81 m_pauseOnAllTimeoutsBreakpoint = nullptr; 82 79 83 m_urlBreakpoints.clear(); 80 m_pauseOnAllIntervalsEnabled = false;81 m_pauseOnAllListenersEnabled = false;82 m_pauseOnAllTimeoutsEnabled = false;83 84 m_pauseOnAllURLsEnabled = false; 84 85 } … … 112 113 } 113 114 114 void InspectorDOMDebuggerAgent::setEventBreakpoint(ErrorString& errorString, const String& breakpointTypeString, const String* eventName) 115 void InspectorDOMDebuggerAgent::mainFrameNavigated() 116 { 117 for (auto& breakpoint : m_listenerBreakpoints.values()) 118 breakpoint->resetHitCount(); 119 120 if (m_pauseOnAllIntervalsBreakpoint) 121 m_pauseOnAllIntervalsBreakpoint->resetHitCount(); 122 123 if (m_pauseOnAllListenersBreakpoint) 124 m_pauseOnAllListenersBreakpoint->resetHitCount(); 125 126 if (m_pauseOnAllTimeoutsBreakpoint) 127 m_pauseOnAllTimeoutsBreakpoint->resetHitCount(); 128 } 129 130 void InspectorDOMDebuggerAgent::setEventBreakpoint(ErrorString& errorString, const String& breakpointTypeString, const String* eventName, const JSON::Object* optionsPayload) 115 131 { 116 132 if (breakpointTypeString.isEmpty()) { … … 125 141 } 126 142 143 auto breakpoint = InspectorDebuggerAgent::debuggerBreakpointFromPayload(errorString, optionsPayload); 144 if (!breakpoint) 145 return; 146 127 147 if (eventName && !eventName->isEmpty()) { 128 148 if (breakpointType.value() == Inspector::Protocol::DOMDebugger::EventBreakpointType::Listener) { 129 if (!m_listenerBreakpoints.add(*eventName ))149 if (!m_listenerBreakpoints.add(*eventName, breakpoint.releaseNonNull())) 130 150 errorString = "Breakpoint with eventName already exists"_s; 131 151 return; … … 138 158 switch (breakpointType.value()) { 139 159 case Inspector::Protocol::DOMDebugger::EventBreakpointType::AnimationFrame: 140 setAnimationFrameBreakpoint(errorString, true);160 setAnimationFrameBreakpoint(errorString, WTFMove(breakpoint)); 141 161 break; 142 162 143 163 case Inspector::Protocol::DOMDebugger::EventBreakpointType::Interval: 144 if (m_pauseOnAllIntervalsEnabled) 164 if (!m_pauseOnAllIntervalsBreakpoint) 165 m_pauseOnAllIntervalsBreakpoint = WTFMove(breakpoint); 166 else 145 167 errorString = "Breakpoint for Interval already exists"_s; 146 m_pauseOnAllIntervalsEnabled = true;147 168 break; 148 169 149 170 case Inspector::Protocol::DOMDebugger::EventBreakpointType::Listener: 150 if (m_pauseOnAllListenersEnabled) 171 if (!m_pauseOnAllListenersBreakpoint) 172 m_pauseOnAllListenersBreakpoint = WTFMove(breakpoint); 173 else 151 174 errorString = "Breakpoint for Listener already exists"_s; 152 m_pauseOnAllListenersEnabled = true;153 175 break; 154 176 155 177 case Inspector::Protocol::DOMDebugger::EventBreakpointType::Timeout: 156 if (m_pauseOnAllTimeoutsEnabled) 178 if (!m_pauseOnAllTimeoutsBreakpoint) 179 m_pauseOnAllTimeoutsBreakpoint = WTFMove(breakpoint); 180 else 157 181 errorString = "Breakpoint for Timeout already exists"_s; 158 m_pauseOnAllTimeoutsEnabled = true;159 182 break; 160 183 } … … 187 210 switch (breakpointType.value()) { 188 211 case Inspector::Protocol::DOMDebugger::EventBreakpointType::AnimationFrame: 189 setAnimationFrameBreakpoint(errorString, false);212 setAnimationFrameBreakpoint(errorString, nullptr); 190 213 break; 191 214 192 215 case Inspector::Protocol::DOMDebugger::EventBreakpointType::Interval: 193 if (!m_pauseOnAllIntervals Enabled)216 if (!m_pauseOnAllIntervalsBreakpoint) 194 217 errorString = "Breakpoint for Intervals missing"_s; 195 m_pauseOnAllIntervals Enabled = false;218 m_pauseOnAllIntervalsBreakpoint = nullptr; 196 219 break; 197 220 198 221 case Inspector::Protocol::DOMDebugger::EventBreakpointType::Listener: 199 if (!m_pauseOnAllListeners Enabled)222 if (!m_pauseOnAllListenersBreakpoint) 200 223 errorString = "Breakpoint for Listeners missing"_s; 201 m_pauseOnAllListeners Enabled = false;224 m_pauseOnAllListenersBreakpoint = nullptr; 202 225 break; 203 226 204 227 case Inspector::Protocol::DOMDebugger::EventBreakpointType::Timeout: 205 if (!m_pauseOnAllTimeouts Enabled)228 if (!m_pauseOnAllTimeoutsBreakpoint) 206 229 errorString = "Breakpoint for Timeouts missing"_s; 207 m_pauseOnAllTimeouts Enabled = false;230 m_pauseOnAllTimeoutsBreakpoint = nullptr; 208 231 break; 209 232 } … … 212 235 void InspectorDOMDebuggerAgent::willHandleEvent(Event& event, const RegisteredEventListener& registeredEventListener) 213 236 { 214 if (!m_debuggerAgent->breakpointsActive())215 return;216 217 237 auto state = event.target()->scriptExecutionContext()->execState(); 218 238 auto injectedScript = m_injectedScriptManager.injectedScriptFor(state); … … 220 240 return; 221 241 242 // Set Web Inspector console command line `$event` getter. 222 243 { 223 244 JSC::JSLockHolder lock(state); … … 226 247 } 227 248 249 if (!m_debuggerAgent->breakpointsActive()) 250 return; 251 228 252 auto* domAgent = m_instrumentingAgents.persistentDOMAgent(); 229 253 230 bool shouldPause = m_debuggerAgent->pauseOnNextStatementEnabled() || m_pauseOnAllListenersEnabled || m_listenerBreakpoints.contains(event.type()); 231 if (!shouldPause && domAgent) 232 shouldPause = domAgent->hasBreakpointForEventListener(*event.currentTarget(), event.type(), registeredEventListener.callback(), registeredEventListener.useCapture()); 233 if (!shouldPause) 254 auto breakpoint = m_pauseOnAllListenersBreakpoint; 255 if (!breakpoint) { 256 auto it = m_listenerBreakpoints.find(event.type()); 257 if (it != m_listenerBreakpoints.end()) 258 breakpoint = it->value.copyRef(); 259 } 260 if (!breakpoint && domAgent) 261 breakpoint = domAgent->breakpointForEventListener(*event.currentTarget(), event.type(), registeredEventListener.callback(), registeredEventListener.useCapture()); 262 if (!breakpoint) 234 263 return; 235 264 … … 242 271 } 243 272 244 m_debuggerAgent->schedulePauseOnNextStatement(Inspector::DebuggerFrontendDispatcher::Reason::Listener, WTFMove(eventData)); 245 } 246 247 void InspectorDOMDebuggerAgent::didHandleEvent() 248 { 249 m_injectedScriptManager.clearEventValue(); 273 m_debuggerAgent->schedulePauseForSpecialBreakpoint(*breakpoint, Inspector::DebuggerFrontendDispatcher::Reason::Listener, WTFMove(eventData)); 274 } 275 276 void InspectorDOMDebuggerAgent::didHandleEvent(Event& event, const RegisteredEventListener& registeredEventListener) 277 { 278 auto state = event.target()->scriptExecutionContext()->execState(); 279 auto injectedScript = m_injectedScriptManager.injectedScriptFor(state); 280 if (injectedScript.hasNoValue()) 281 return; 282 283 // Clear Web Inspector console command line `$event` getter. 284 { 285 JSC::JSLockHolder lock(state); 286 287 injectedScript.clearEventValue(); 288 } 289 290 if (!m_debuggerAgent->breakpointsActive()) 291 return; 292 293 auto breakpoint = m_pauseOnAllListenersBreakpoint; 294 if (!breakpoint) 295 breakpoint = m_listenerBreakpoints.get(event.type()); 296 if (!breakpoint) { 297 if (auto* domAgent = m_instrumentingAgents.persistentDOMAgent()) 298 breakpoint = domAgent->breakpointForEventListener(*event.currentTarget(), event.type(), registeredEventListener.callback(), registeredEventListener.useCapture()); 299 } 300 if (!breakpoint) 301 return; 302 303 m_debuggerAgent->cancelPauseForSpecialBreakpoint(*breakpoint); 250 304 } 251 305 … … 255 309 return; 256 310 257 bool shouldPause = m_debuggerAgent->pauseOnNextStatementEnabled() || (oneShot ? m_pauseOnAllTimeoutsEnabled : m_pauseOnAllIntervalsEnabled);258 if (! shouldPause)311 auto breakpoint = oneShot ? m_pauseOnAllTimeoutsBreakpoint : m_pauseOnAllIntervalsBreakpoint; 312 if (!breakpoint) 259 313 return; 260 314 261 315 auto breakReason = oneShot ? Inspector::DebuggerFrontendDispatcher::Reason::Timeout : Inspector::DebuggerFrontendDispatcher::Reason::Interval; 262 m_debuggerAgent->schedulePauseOnNextStatement(breakReason, nullptr); 316 m_debuggerAgent->schedulePauseForSpecialBreakpoint(*breakpoint, breakReason); 317 } 318 319 void InspectorDOMDebuggerAgent::didFireTimer(bool oneShot) 320 { 321 if (!m_debuggerAgent->breakpointsActive()) 322 return; 323 324 auto breakpoint = oneShot ? m_pauseOnAllTimeoutsBreakpoint : m_pauseOnAllIntervalsBreakpoint; 325 if (!breakpoint) 326 return; 327 328 m_debuggerAgent->cancelPauseForSpecialBreakpoint(*breakpoint); 263 329 } 264 330 -
trunk/Source/WebCore/inspector/agents/InspectorDOMDebuggerAgent.h
r250996 r266074 33 33 34 34 #include "InspectorWebAgentBase.h" 35 #include <JavaScriptCore/Breakpoint.h> 35 36 #include <JavaScriptCore/InspectorBackendDispatchers.h> 36 37 #include <JavaScriptCore/InspectorDebuggerAgent.h> 37 38 #include <wtf/HashMap.h> 39 #include <wtf/HashSet.h> 38 40 #include <wtf/JSONValues.h> 41 #include <wtf/RefPtr.h> 39 42 #include <wtf/text/WTFString.h> 40 43 … … 65 68 void setURLBreakpoint(ErrorString&, const String& url, const bool* optionalIsRegex) final; 66 69 void removeURLBreakpoint(ErrorString&, const String& url) final; 67 void setEventBreakpoint(ErrorString&, const String& breakpointType, const String* eventName ) final;70 void setEventBreakpoint(ErrorString&, const String& breakpointType, const String* eventName, const JSON::Object* options) final; 68 71 void removeEventBreakpoint(ErrorString&, const String& breakpointType, const String* eventName) final; 69 72 … … 73 76 74 77 // InspectorInstrumentation 78 virtual void mainFrameNavigated(); 75 79 void willSendXMLHttpRequest(const String& url); 76 80 void willFetch(const String& url); 77 81 void willHandleEvent(Event&, const RegisteredEventListener&); 78 void didHandleEvent( );82 void didHandleEvent(Event&, const RegisteredEventListener&); 79 83 void willFireTimer(bool oneShot); 84 void didFireTimer(bool oneShot); 80 85 81 86 protected: … … 84 89 virtual void disable(); 85 90 86 virtual void setAnimationFrameBreakpoint(ErrorString&, bool enabled) = 0;91 virtual void setAnimationFrameBreakpoint(ErrorString&, RefPtr<JSC::Breakpoint>&&) = 0; 87 92 88 93 Inspector::InspectorDebuggerAgent* m_debuggerAgent { nullptr }; … … 95 100 Inspector::InjectedScriptManager& m_injectedScriptManager; 96 101 97 HashSet<String> m_listenerBreakpoints; 102 HashMap<String, Ref<JSC::Breakpoint>> m_listenerBreakpoints; 103 RefPtr<JSC::Breakpoint> m_pauseOnAllIntervalsBreakpoint; 104 RefPtr<JSC::Breakpoint> m_pauseOnAllListenersBreakpoint; 105 RefPtr<JSC::Breakpoint> m_pauseOnAllTimeoutsBreakpoint; 98 106 99 107 enum class URLBreakpointType { RegularExpression, Text }; 100 108 HashMap<String, URLBreakpointType> m_urlBreakpoints; 101 102 bool m_pauseOnAllIntervalsEnabled { false };103 bool m_pauseOnAllListenersEnabled { false };104 bool m_pauseOnAllTimeoutsEnabled { false };105 109 bool m_pauseOnAllURLsEnabled { false }; 106 110 }; -
trunk/Source/WebCore/inspector/agents/InspectorTimelineAgent.cpp
r262673 r266074 52 52 #include "WebConsoleAgent.h" 53 53 #include "WebDebuggerAgent.h" 54 #include <JavaScriptCore/Breakpoint.h> 54 55 #include <JavaScriptCore/ConsoleMessage.h> 55 56 #include <JavaScriptCore/InspectorScriptProfilerAgent.h> 56 #include <JavaScriptCore/ScriptBreakpoint.h>57 57 #include <wtf/Stopwatch.h> 58 58 … … 188 188 m_instrumentingAgents.setTrackingTimelineAgent(this); 189 189 190 m_environment.scriptDebugServer().add Listener(this);190 m_environment.scriptDebugServer().addObserver(*this); 191 191 192 192 m_tracking = true; … … 242 242 m_instrumentingAgents.setTrackingTimelineAgent(nullptr); 243 243 244 m_environment.scriptDebugServer().remove Listener(this, true);244 m_environment.scriptDebugServer().removeObserver(*this, true); 245 245 246 246 #if PLATFORM(COCOA) … … 670 670 } 671 671 672 // ScriptDebugListener 673 674 void InspectorTimelineAgent::breakpointActionProbe(JSC::JSGlobalObject* lexicalGlobalObject, const Inspector::ScriptBreakpointAction& action, unsigned /*batchId*/, unsigned sampleId, JSC::JSValue) 675 { 676 appendRecord(TimelineRecordFactory::createProbeSampleData(action, sampleId), TimelineRecordType::ProbeSample, false, frameFromExecState(lexicalGlobalObject)); 672 void InspectorTimelineAgent::breakpointActionProbe(JSC::JSGlobalObject* lexicalGlobalObject, JSC::BreakpointActionID actionID, unsigned /*batchId*/, unsigned sampleId, JSC::JSValue) 673 { 674 appendRecord(TimelineRecordFactory::createProbeSampleData(actionID, sampleId), TimelineRecordType::ProbeSample, false, frameFromExecState(lexicalGlobalObject)); 677 675 } 678 676 -
trunk/Source/WebCore/inspector/agents/InspectorTimelineAgent.h
r251959 r266074 35 35 #include "InspectorWebAgentBase.h" 36 36 #include "LayoutRect.h" 37 #include <JavaScriptCore/Debugger.h> 38 #include <JavaScriptCore/DebuggerPrimitives.h> 37 39 #include <JavaScriptCore/InspectorBackendDispatchers.h> 38 40 #include <JavaScriptCore/InspectorFrontendDispatchers.h> 39 #include <JavaScriptCore/ScriptDebugListener.h>40 41 #include <wtf/JSONValues.h> 41 42 #include <wtf/Vector.h> … … 82 83 }; 83 84 84 class InspectorTimelineAgent final : public InspectorAgentBase , public Inspector::TimelineBackendDispatcherHandler , public Inspector::ScriptDebugListener {85 class InspectorTimelineAgent final : public InspectorAgentBase , public Inspector::TimelineBackendDispatcherHandler , public JSC::Debugger::Observer { 85 86 WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent); 86 87 WTF_MAKE_FAST_ALLOCATED; … … 101 102 void setInstruments(ErrorString&, const JSON::Array&) override; 102 103 103 // ScriptDebugListener 104 void didParseSource(JSC::SourceID, const Script&) override { } 105 void failedToParseSource(const String&, const String&, int, int, const String&) override { } 106 void willRunMicrotask() override { } 107 void didRunMicrotask() override { } 108 void didPause(JSC::JSGlobalObject*, JSC::JSValue, JSC::JSValue) override { } 109 void didContinue() override { } 110 void breakpointActionLog(JSC::JSGlobalObject*, const String&) override { } 111 void breakpointActionSound(int) override { } 112 void breakpointActionProbe(JSC::JSGlobalObject*, const Inspector::ScriptBreakpointAction&, unsigned batchId, unsigned sampleId, JSC::JSValue result) override; 104 // JSC::Debugger::Observer 105 void breakpointActionProbe(JSC::JSGlobalObject*, JSC::BreakpointActionID, unsigned batchId, unsigned sampleId, JSC::JSValue result) final; 113 106 114 107 // InspectorInstrumentation -
trunk/Source/WebCore/inspector/agents/page/PageDOMDebuggerAgent.cpp
r262673 r266074 95 95 96 96 m_domBreakpoints.clear(); 97 m_pauseOnAllAnimationFramesEnabled = false; 97 98 m_pauseOnAllAnimationFramesBreakpoint = nullptr; 98 99 99 100 InspectorDOMDebuggerAgent::disable(); … … 151 152 updateSubtreeBreakpoints(child, rootBit, false); 152 153 } 154 } 155 156 void PageDOMDebuggerAgent::mainFrameNavigated() 157 { 158 InspectorDOMDebuggerAgent::mainFrameNavigated(); 159 160 if (m_pauseOnAllAnimationFramesBreakpoint) 161 m_pauseOnAllAnimationFramesBreakpoint->resetHitCount(); 153 162 } 154 163 … … 253 262 return; 254 263 255 bool shouldPause = m_debuggerAgent->pauseOnNextStatementEnabled() || m_pauseOnAllAnimationFramesEnabled; 256 if (!shouldPause) 257 return; 258 259 m_debuggerAgent->schedulePauseOnNextStatement(Inspector::DebuggerFrontendDispatcher::Reason::AnimationFrame, nullptr); 264 auto breakpoint = m_pauseOnAllAnimationFramesBreakpoint; 265 if (!breakpoint) 266 return; 267 268 m_debuggerAgent->schedulePauseForSpecialBreakpoint(*breakpoint, Inspector::DebuggerFrontendDispatcher::Reason::AnimationFrame); 269 } 270 271 void PageDOMDebuggerAgent::didFireAnimationFrame() 272 { 273 if (!m_debuggerAgent->breakpointsActive()) 274 return; 275 276 auto breakpoint = m_pauseOnAllAnimationFramesBreakpoint; 277 if (!breakpoint) 278 return; 279 280 m_debuggerAgent->cancelPauseForSpecialBreakpoint(*breakpoint); 260 281 } 261 282 … … 272 293 } 273 294 274 void PageDOMDebuggerAgent::setAnimationFrameBreakpoint(ErrorString& errorString, bool enabled) 275 { 276 if (m_pauseOnAllAnimationFramesEnabled == enabled) 277 errorString = m_pauseOnAllAnimationFramesEnabled ? "Breakpoint for AnimationFrame already exists"_s : "Breakpoint for AnimationFrame missing"_s; 278 279 m_pauseOnAllAnimationFramesEnabled = enabled; 295 void PageDOMDebuggerAgent::setAnimationFrameBreakpoint(ErrorString& errorString, RefPtr<JSC::Breakpoint>&& breakpoint) 296 { 297 if (!m_pauseOnAllAnimationFramesBreakpoint == !breakpoint) { 298 errorString = m_pauseOnAllAnimationFramesBreakpoint ? "Breakpoint for AnimationFrame already exists"_s : "Breakpoint for AnimationFrame missing"_s; 299 return; 300 } 301 302 m_pauseOnAllAnimationFramesBreakpoint = WTFMove(breakpoint); 280 303 } 281 304 -
trunk/Source/WebCore/inspector/agents/page/PageDOMDebuggerAgent.h
r251871 r266074 27 27 28 28 #include "InspectorDOMDebuggerAgent.h" 29 #include <JavaScriptCore/Breakpoint.h> 30 #include <wtf/RefPtr.h> 29 31 30 32 namespace WebCore { … … 48 50 49 51 // InspectorInstrumentation 52 void mainFrameNavigated() final; 50 53 void frameDocumentUpdated(Frame&); 51 54 void willInsertDOMNode(Node& parent); … … 56 59 void willInvalidateStyleAttr(Element&); 57 60 void willFireAnimationFrame(); 61 void didFireAnimationFrame(); 58 62 59 63 private: … … 61 65 void disable() override; 62 66 63 void setAnimationFrameBreakpoint(ErrorString&, bool enabled) override;67 void setAnimationFrameBreakpoint(ErrorString&, RefPtr<JSC::Breakpoint>&&) override; 64 68 65 69 void descriptionForDOMEvent(Node&, int breakpointType, bool insertion, JSON::Object& description); … … 69 73 70 74 HashMap<Node*, uint32_t> m_domBreakpoints; 71 bool m_pauseOnAllAnimationFramesEnabled { false }; 75 76 RefPtr<JSC::Breakpoint> m_pauseOnAllAnimationFramesBreakpoint; 72 77 }; 73 78 -
trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp
r262673 r266074 91 91 } 92 92 93 String PageDebuggerAgent::sourceMapURLForScript(const Script& script)93 String PageDebuggerAgent::sourceMapURLForScript(const JSC::Debugger::Script& script) 94 94 { 95 95 static NeverDestroyed<String> sourceMapHTTPHeader(MAKE_STATIC_STRING_IMPL("SourceMap")); -
trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.h
r255191 r266074 52 52 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<Inspector::Protocol::Runtime::RemoteObject>& result, Optional<bool>& wasThrown, Optional<int>& savedResultIndex) override; 53 53 54 // ScriptDebugListener55 void breakpointActionLog(JSC::JSGlobalObject*, const String& ) override;54 // JSC::Debugger::Observer 55 void breakpointActionLog(JSC::JSGlobalObject*, const String& data) final; 56 56 57 57 // InspectorInstrumentation … … 68 68 void disable(bool isBeingDestroyed) override; 69 69 70 String sourceMapURLForScript(const Script&) override;70 String sourceMapURLForScript(const JSC::Debugger::Script&) override; 71 71 72 72 void muteConsole() override; -
trunk/Source/WebCore/inspector/agents/worker/WorkerDOMDebuggerAgent.cpp
r249305 r266074 48 48 } 49 49 50 void WorkerDOMDebuggerAgent::setAnimationFrameBreakpoint(ErrorString& errorString, bool /* enabled */)50 void WorkerDOMDebuggerAgent::setAnimationFrameBreakpoint(ErrorString& errorString, RefPtr<JSC::Breakpoint>&&) 51 51 { 52 52 errorString = "Not supported"_s; -
trunk/Source/WebCore/inspector/agents/worker/WorkerDOMDebuggerAgent.h
r250996 r266074 27 27 28 28 #include "InspectorDOMDebuggerAgent.h" 29 #include <JavaScriptCore/Breakpoint.h> 30 #include <wtf/RefPtr.h> 29 31 30 32 namespace WebCore { … … 42 44 43 45 private: 44 void setAnimationFrameBreakpoint(ErrorString&, bool enabled) override;46 void setAnimationFrameBreakpoint(ErrorString&, RefPtr<JSC::Breakpoint>&&) override; 45 47 }; 46 48 -
trunk/Source/WebCore/inspector/agents/worker/WorkerDebuggerAgent.h
r251425 r266074 39 39 ~WorkerDebuggerAgent() override; 40 40 41 // ScriptDebugListener42 void breakpointActionLog(JSC::JSGlobalObject*, const String& ) override;41 // JSC::Debugger::Observer 42 void breakpointActionLog(JSC::JSGlobalObject*, const String& data) final; 43 43 44 44 private: -
trunk/Source/WebCore/page/DOMTimer.cpp
r264853 r266074 285 285 Ref<DOMTimer> protectedThis(*this); 286 286 287 bool oneShot = !repeatInterval(); 288 287 289 ASSERT(scriptExecutionContext()); 288 290 ScriptExecutionContext& context = *scriptExecutionContext(); … … 292 294 auto& document = downcast<Document>(context); 293 295 if (auto* holdingTank = document.domTimerHoldingTankIfExists(); holdingTank && holdingTank->contains(*this)) { 294 if ( !repeatInterval())296 if (oneShot) 295 297 startOneShot(0_s); 296 298 return; … … 310 312 m_userGestureTokenToForward = nullptr; 311 313 312 InspectorInstrumentation::willFireTimer(context, m_timeoutId, !repeatInterval());314 InspectorInstrumentation::willFireTimer(context, m_timeoutId, oneShot); 313 315 314 316 // Simple case for non-one-shot timers. … … 321 323 m_action->execute(context); 322 324 323 InspectorInstrumentation::didFireTimer(context );325 InspectorInstrumentation::didFireTimer(context, m_timeoutId, oneShot); 324 326 325 327 updateThrottlingStateIfNecessary(fireState); … … 339 341 m_action->execute(context); 340 342 341 InspectorInstrumentation::didFireTimer(context );343 InspectorInstrumentation::didFireTimer(context, m_timeoutId, oneShot); 342 344 343 345 // Check if we should throttle nested single-shot timers. -
trunk/Source/WebInspectorUI/ChangeLog
r266072 r266074 1 2020-08-24 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: allow event breakpoints to be configured 4 https://bugs.webkit.org/show_bug.cgi?id=215362 5 <rdar://problem/66932921> 6 7 Reviewed by Brian Burg. 8 9 This allows developers to do things like: 10 - only pause when `window.event.type` is a certain value 11 - ignore the first N pauses 12 - evaluate JavaScript whenever an event listener is invoked without pausing 13 14 * UserInterface/Models/Breakpoint.js: 15 (WI.Breakpoint): 16 (WI.Breakpoint.prototype.toJSON): 17 (WI.Breakpoint.prototype.get special): Added. 18 (WI.Breakpoint.prototype.get removable): Added. 19 (WI.Breakpoint.prototype.get editable): Added. 20 (WI.Breakpoint.prototype.set condition): 21 (WI.Breakpoint.prototype.get ignoreCount): 22 (WI.Breakpoint.prototype.set ignoreCount): 23 (WI.Breakpoint.prototype.get autoContinue): 24 (WI.Breakpoint.prototype.set autoContinue): 25 (WI.Breakpoint.prototype.get actions): 26 (WI.Breakpoint.prototype.get probeActions): 27 (WI.Breakpoint.prototype.cycleToNextMode): 28 (WI.Breakpoint.prototype.createAction): 29 (WI.Breakpoint.prototype.recreateAction): 30 (WI.Breakpoint.prototype.removeAction): 31 (WI.Breakpoint.prototype.clearActions): 32 (WI.Breakpoint.prototype.remove): Added. 33 (WI.Breakpoint.prototype.optionsToProtocol): Added. 34 (WI.Breakpoint.prototype.breakpointActionDidChange): 35 (WI.Breakpoint.fromJSON): Deleted. 36 (WI.Breakpoint.prototype.get sourceCodeLocation): Deleted. 37 (WI.Breakpoint.prototype.get contentIdentifier): Deleted. 38 (WI.Breakpoint.prototype.get scriptIdentifier): Deleted. 39 (WI.Breakpoint.prototype.get target): Deleted. 40 (WI.Breakpoint.prototype.get identifier): Deleted. 41 (WI.Breakpoint.prototype.set identifier): Deleted. 42 (WI.Breakpoint.prototype.get resolved): Deleted. 43 (WI.Breakpoint.prototype.set resolved): Deleted. 44 (WI.Breakpoint.prototype.saveIdentityToCookie): Deleted. 45 (WI.Breakpoint.prototype._isSpecial): Deleted. 46 (WI.Breakpoint.prototype._sourceCodeLocationLocationChanged): Deleted. 47 (WI.Breakpoint.prototype._sourceCodeLocationDisplayLocationChanged): Deleted. 48 * UserInterface/Models/DOMBreakpoint.js: 49 (WI.DOMBreakpoint): 50 (WI.DOMBreakpoint.fromJSON): Added. 51 (WI.DOMBreakpoint.prototype.remove): Added. 52 (WI.DOMBreakpoint.prototype.toJSON): 53 (WI.DOMBreakpoint.deserialize): Deleted. 54 (WI.DOMBreakpoint.prototype.get disabled): Deleted. 55 (WI.DOMBreakpoint.prototype.set disabled): Deleted. 56 * UserInterface/Models/EventBreakpoint.js: 57 (WI.EventBreakpoint): 58 (WI.EventBreakpoint.fromJSON): Added. 59 (WI.EventBreakpoint.prototype.get special): Added. 60 (WI.EventBreakpoint.prototype.get editable): Added. 61 (WI.EventBreakpoint.prototype.remove): Added. 62 (WI.EventBreakpoint.prototype.saveIdentityToCookie): 63 (WI.EventBreakpoint.prototype.toJSON): 64 (WI.EventBreakpoint.deserialize): Deleted. 65 (WI.EventBreakpoint.prototype.get disabled): Deleted. 66 (WI.EventBreakpoint.prototype.set disabled): Deleted. 67 * UserInterface/Models/JavaScriptBreakpoint.js: Copied from UserInterface/Models/Breakpoint.js. 68 (WI.JavaScriptBreakpoint): 69 (WI.JavaScriptBreakpoint.fromJSON): 70 (WI.JavaScriptBreakpoint.prototype.toJSON): 71 (WI.JavaScriptBreakpoint.prototype.get sourceCodeLocation): 72 (WI.JavaScriptBreakpoint.prototype.get contentIdentifier): 73 (WI.JavaScriptBreakpoint.prototype.get scriptIdentifier): 74 (WI.JavaScriptBreakpoint.prototype.get target): 75 (WI.JavaScriptBreakpoint.prototype.get special): Added. 76 (WI.JavaScriptBreakpoint.prototype.get removable): Added. 77 (WI.JavaScriptBreakpoint.prototype.get editable): Added. 78 (WI.JavaScriptBreakpoint.prototype.get identifier): 79 (WI.JavaScriptBreakpoint.prototype.set identifier): 80 (WI.JavaScriptBreakpoint.prototype.get resolved): 81 (WI.JavaScriptBreakpoint.prototype.set resolved): 82 (WI.JavaScriptBreakpoint.prototype.remove): Added. 83 (WI.JavaScriptBreakpoint.prototype.saveIdentityToCookie): 84 (WI.JavaScriptBreakpoint.prototype._isSpecial): 85 (WI.JavaScriptBreakpoint.prototype._sourceCodeLocationLocationChanged): 86 (WI.JavaScriptBreakpoint.prototype._sourceCodeLocationDisplayLocationChanged): 87 * UserInterface/Models/URLBreakpoint.js: 88 (WI.URLBreakpoint): 89 (WI.URLBreakpoint.fromJSON): Added. 90 (WI.URLBreakpoint.prototype.get special): Added. 91 (WI.URLBreakpoint.prototype.remove): Added. 92 (WI.URLBreakpoint.prototype.toJSON): 93 (WI.URLBreakpoint.deserialize): Deleted. 94 (WI.URLBreakpoint.prototype.get disabled): Deleted. 95 (WI.URLBreakpoint.prototype.set disabled): Deleted. 96 Rename `WI.Breakpoint` to `WI.JavaScriptBreakpoint` and use `WI.Breakpoint` as a new common 97 base class for all breakpoint types, allowing more logic to be shared (e.g. disabled state). 98 Additionally, breakpoints are now able to 99 - determine whether or not they're 100 - special 101 - removable 102 - editable (i.e. configurable) 103 - remove themselves 104 without the caller needing to know what manager to consult with. 105 106 * UserInterface/Controllers/DOMManager.js: 107 (WI.DOMManager): 108 (WI.DOMManager.supportsEventListenerBreakpointConfiguration): Added. 109 (WI.DOMManager.prototype.setBreakpointForEventListener): 110 (WI.DOMManager.prototype.removeBreakpointForEventListener): 111 (WI.DOMManager.prototype._setEventBreakpoint): Added. 112 (WI.DOMManager.prototype._removeEventBreakpoint): Added. 113 (WI.DOMManager.prototype._handleEventBreakpointEditablePropertyChanged): Added. 114 (WI.DOMManager.prototype._handleEventBreakpointActionsChanged): Added. 115 (WI.DOMManager.prototype._updateEventBreakpoint): Deleted. 116 Keep track of configuration changes for specific listener breakpoints. 117 118 * UserInterface/Controllers/DOMDebuggerManager.js: 119 (WI.DOMDebuggerManager): 120 (WI.DOMDebuggerManager.prototype.initializeTarget): 121 (WI.DOMDebuggerManager.prototype.addDOMBreakpoint): 122 (WI.DOMDebuggerManager.prototype.removeDOMBreakpoint): 123 (WI.DOMDebuggerManager.prototype.addEventBreakpoint): 124 (WI.DOMDebuggerManager.prototype.removeEventBreakpoint): 125 (WI.DOMDebuggerManager.prototype.addURLBreakpoint): 126 (WI.DOMDebuggerManager.prototype.removeURLBreakpoint): 127 (WI.DOMDebuggerManager.prototype._commandArgumentsForEventBreakpoint): Added. 128 (WI.DOMDebuggerManager.prototype._setEventBreakpoint): Added. 129 (WI.DOMDebuggerManager.prototype._removeEventBreakpoint): Added. 130 (WI.DOMDebuggerManager.prototype._handleEventBreakpointDisabledStateChanged): Added. 131 (WI.DOMDebuggerManager.prototype._handleEventBreakpointEditablePropertyChanged): Added. 132 (WI.DOMDebuggerManager.prototype._handleEventBreakpointActionsChanged): Added. 133 (WI.DOMDebuggerManager.prototype.isBreakpointSpecial): Deleted. 134 (WI.DOMDebuggerManager.prototype._updateEventBreakpoint): Deleted. 135 Keep track of configuration changes for special event breakpoints. 136 Store special event breakpoints inside `WI.objectStores.eventBreakpoints`. 137 138 * UserInterface/Controllers/DebuggerManager.js: 139 (WI.DebuggerManager): 140 (WI.DebuggerManager.prototype.addBreakpoint): 141 (WI.DebuggerManager.prototype.removeBreakpoint): 142 (WI.DebuggerManager.prototype.addProbesForBreakpoint): Added. 143 (WI.DebuggerManager.prototype.removeProbesForBreakpoint): Added. 144 (WI.DebuggerManager.prototype.updateProbesForBreakpoint): Added. 145 (WI.DebuggerManager.prototype._setBreakpoint): 146 (WI.DebuggerManager.prototype._breakpointEditablePropertyDidChange): 147 (WI.DebuggerManager.prototype._handleBreakpointActionsDidChange): 148 (WI.DebuggerManager.prototype.isBreakpointRemovable): Deleted. 149 (WI.DebuggerManager.prototype.isBreakpointSpecial): Deleted. 150 (WI.DebuggerManager.prototype.isBreakpointEditable): Deleted. 151 (WI.DebuggerManager.prototype._debuggerBreakpointActionType): Deleted. 152 (WI.DebuggerManager.prototype._debuggerBreakpointOptions): Deleted. 153 (WI.DebuggerManager.prototype._addProbesForBreakpoint): Deleted. 154 (WI.DebuggerManager.prototype._removeProbesForBreakpoint): Deleted. 155 (WI.DebuggerManager.prototype._updateProbesForBreakpoint): Deleted. 156 Replace `WI.Breakpoint` with `WI.JavaScriptBreakpoint`. 157 Probes now support `WI.EventBreakpoint` in addition to `WI.JavaScriptBreakpoint`. 158 159 * UserInterface/Controllers/BreakpointPopoverController.js: 160 (WI.BreakpointPopoverController.prototype.appendContextMenuItems): 161 (WI.BreakpointPopoverController.prototype._createPopoverContent): 162 Allow any breakpoint instead of only `WI.JavaScriptBreakpoint`. 163 Drive-by: the existing `ignoreCount` value wasn't being used to populate the `<input>`. 164 165 * UserInterface/Views/BreakpointTreeElement.js: 166 (WI.BreakpointTreeElement.prototype.ondelete): 167 (WI.BreakpointTreeElement.prototype.get listenerSet): Added. 168 (WI.BreakpointTreeElement.prototype.updateStatus): Added. 169 (WI.BreakpointTreeElement.prototype.updateTitles): Added. 170 (WI.BreakpointTreeElement.prototype.get breakpoint): Deleted. 171 (WI.BreakpointTreeElement.prototype.get filterableData): Deleted. 172 (WI.BreakpointTreeElement.prototype._updateTitles): Deleted. 173 (WI.BreakpointTreeElement.prototype._updateStatus): Deleted. 174 (WI.BreakpointTreeElement.prototype._breakpointLocationDidChange): Deleted. 175 * UserInterface/Views/BreakpointTreeElement.css: 176 (.item.breakpoint .status > .status-image): 177 (.item.breakpoint.paused .icon): Added. 178 (@media (prefers-color-scheme: dark) .item.breakpoint.paused .icon): Added. 179 (.item.breakpoint .status > .status-image.resolved): Deleted. 180 (body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.breakpoint.selected .status > .status-image.resolved): Deleted. 181 (.item.breakpoint .subtitle.formatted-location): Deleted. 182 (.breakpoint-debugger-statement-icon .icon): Deleted. 183 (.breakpoint-exception-icon .icon): Deleted. 184 (.breakpoint-assertion-icon .icon): Deleted. 185 (.breakpoint-microtask-icon .icon): Deleted. 186 (.breakpoint-paused-icon .icon): Deleted. 187 (.breakpoint-generic-line-icon .icon): Deleted. 188 (.breakpoint-generic-line-icon .icon > span): Deleted. 189 (.data-updated.breakpoint-generic-line-icon .icon > span): Deleted. 190 (@media (prefers-color-scheme: dark) .breakpoint-debugger-statement-icon .icon): Deleted. 191 (@media (prefers-color-scheme: dark) .breakpoint-exception-icon .icon): Deleted. 192 (@media (prefers-color-scheme: dark) .breakpoint-assertion-icon .icon): Deleted. 193 (@media (prefers-color-scheme: dark) .breakpoint-microtask-icon .icon): Deleted. 194 (@media (prefers-color-scheme: dark) .breakpoint-paused-icon .icon): Deleted. 195 (@media (prefers-color-scheme: dark) .breakpoint-generic-line-icon .icon): Deleted. 196 * UserInterface/Views/DOMBreakpointTreeElement.js: 197 (WI.DOMBreakpointTreeElement): 198 (WI.DOMBreakpointTreeElement.prototype.onattach): Deleted. 199 (WI.DOMBreakpointTreeElement.prototype.ondetach): Deleted. 200 (WI.DOMBreakpointTreeElement.prototype.ondelete): Deleted. 201 (WI.DOMBreakpointTreeElement.prototype.onenter): Deleted. 202 (WI.DOMBreakpointTreeElement.prototype.onspace): Deleted. 203 (WI.DOMBreakpointTreeElement.prototype.populateContextMenu): Deleted. 204 (WI.DOMBreakpointTreeElement.prototype._statusImageElementClicked): Deleted. 205 (WI.DOMBreakpointTreeElement.prototype._statusImageElementFocused): Deleted. 206 (WI.DOMBreakpointTreeElement.prototype._statusImageElementMouseDown): Deleted. 207 (WI.DOMBreakpointTreeElement.prototype._toggleBreakpoint): Deleted. 208 (WI.DOMBreakpointTreeElement.prototype._updateStatus): Deleted. 209 * UserInterface/Views/DOMBreakpointTreeElement.css: 210 (.item.breakpoint.dom.subtree-modified:not(.paused) .icon): Added. 211 (.item.breakpoint.dom.attribute-modified:not(.paused) .icon): Added. 212 (.item.breakpoint.dom.node-removed:not(.paused) .icon): Added. 213 (@media (prefers-color-scheme: dark) .item.breakpoint.dom.subtree-modified:not(.paused) .icon): Added. 214 (@media (prefers-color-scheme: dark) .item.breakpoint.dom.attribute-modified:not(.paused) .icon): Added. 215 (@media (prefers-color-scheme: dark) .item.breakpoint.dom.node-removed:not(.paused) .icon): Added. 216 (.breakpoint.dom.breakpoint-for-subtree-modified:not(.breakpoint-paused-icon) .icon): Deleted. 217 (.breakpoint.dom.breakpoint-for-attribute-modified:not(.breakpoint-paused-icon) .icon): Deleted. 218 (.breakpoint.dom.breakpoint-for-node-removed:not(.breakpoint-paused-icon) .icon): Deleted. 219 (@media (prefers-color-scheme: dark) .breakpoint.dom.breakpoint-for-subtree-modified:not(.breakpoint-paused-icon) .icon): Deleted. 220 (@media (prefers-color-scheme: dark) .breakpoint.dom.breakpoint-for-attribute-modified:not(.breakpoint-paused-icon) .icon): Deleted. 221 (@media (prefers-color-scheme: dark) .breakpoint.dom.breakpoint-for-node-removed:not(.breakpoint-paused-icon) .icon): Deleted. 222 * UserInterface/Views/EventBreakpointTreeElement.js: 223 (WI.EventBreakpointTreeElement): 224 (WI.EventBreakpointTreeElement.prototype.onattach): Deleted. 225 (WI.EventBreakpointTreeElement.prototype.ondetach): Deleted. 226 (WI.EventBreakpointTreeElement.prototype.ondelete): Deleted. 227 (WI.EventBreakpointTreeElement.prototype.onenter): Deleted. 228 (WI.EventBreakpointTreeElement.prototype.onspace): Deleted. 229 (WI.EventBreakpointTreeElement.prototype.populateContextMenu): Deleted. 230 (WI.EventBreakpointTreeElement.prototype._statusImageElementClicked): Deleted. 231 (WI.EventBreakpointTreeElement.prototype._statusImageElementFocused): Deleted. 232 (WI.EventBreakpointTreeElement.prototype._statusImageElementMouseDown): Deleted. 233 (WI.EventBreakpointTreeElement.prototype._toggleBreakpoint): Deleted. 234 (WI.EventBreakpointTreeElement.prototype._updateStatus): Deleted. 235 * UserInterface/Views/EventBreakpointTreeElement.css: 236 (.item.breakpoint.event.animation-frame:not(.paused) .icon): Added. 237 (.item.breakpoint.event.interval:not(.paused) .icon): Added. 238 (.item.breakpoint.event.listener:not(.paused) .icon): Added. 239 (.item.breakpoint.event.timeout:not(.paused) .icon): Added. 240 (@media(prefers-color-scheme: dark) .item.breakpoint.event.animation-frame:not(.paused) .icon): Added. 241 (@media(prefers-color-scheme: dark) .item.breakpoint.event.interval:not(.paused) .icon): Added. 242 (@media(prefers-color-scheme: dark) .item.breakpoint.event.listener:not(.paused) .icon): Added. 243 (@media(prefers-color-scheme: dark) .item.breakpoint.event.timeout:not(.paused) .icon): Added. 244 (.breakpoint.event.breakpoint-for-animation-frame:not(.breakpoint-paused-icon) .icon): Deleted. 245 (.breakpoint.event.breakpoint-for-interval:not(.breakpoint-paused-icon) .icon): Deleted. 246 (.breakpoint.event.breakpoint-for-listener:not(.breakpoint-paused-icon) .icon): Deleted. 247 (.breakpoint.event.breakpoint-for-timeout:not(.breakpoint-paused-icon) .icon): Deleted. 248 (@media(prefers-color-scheme: dark) .breakpoint.event.breakpoint-for-animation-frame:not(.breakpoint-paused-icon) .icon): Deleted. 249 (@media(prefers-color-scheme: dark) .breakpoint.event.breakpoint-for-interval:not(.breakpoint-paused-icon) .icon): Deleted. 250 (@media(prefers-color-scheme: dark) .breakpoint.event.breakpoint-for-listener:not(.breakpoint-paused-icon) .icon): Deleted. 251 (@media(prefers-color-scheme: dark) .breakpoint.event.breakpoint-for-timeout:not(.breakpoint-paused-icon) .icon): Deleted. 252 * UserInterface/Views/JavaScriptBreakpointTreeElement.js: Copied from Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.js. 253 (WI.JavaScriptBreakpointTreeElement): 254 (WI.JavaScriptBreakpointTreeElement.prototype.get filterableData): 255 (WI.JavaScriptBreakpointTreeElement.prototype.updateStatus): Added. 256 (WI.JavaScriptBreakpointTreeElement.prototype.updateTitles): Added. 257 (WI.JavaScriptBreakpointTreeElement.prototype._breakpointLocationDidChange): 258 * UserInterface/Views/JavaScriptBreakpointTreeElement.css: Copied from Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.css. 259 (.item.breakpoint.javascript .status > .status-image): Added. 260 (.item.breakpoint.javascript .status > .status-image.resolved): Added. 261 (body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.breakpoint.javascript.selected .status > .status-image.resolved): Added. 262 (.item.breakpoint.javascript .subtitle.formatted-location): Added. 263 (.item.breakpoint.javascript.line .icon): Added. 264 (.item.breakpoint.javascript.line .icon > span): Added. 265 (.data-updated.item.breakpoint.javascript.line .icon > span): Added. 266 (.item.breakpoint.javascript.debugger-statement .icon): Added. 267 (.item.breakpoint.javascript.exception .icon): Added. 268 (.item.breakpoint.javascript.assertion .icon): Added. 269 (.item.breakpoint.javascript.microtask .icon): Added. 270 (@media (prefers-color-scheme: dark) .item.breakpoint.javascript.line .icon): Added. 271 (@media (prefers-color-scheme: dark) .item.breakpoint.javascript.debugger-statement .icon): Added. 272 (@media (prefers-color-scheme: dark) .item.breakpoint.javascript.exception .icon): Added. 273 (@media (prefers-color-scheme: dark) .item.breakpoint.javascript.assertion .icon): Added. 274 (@media (prefers-color-scheme: dark) .item.breakpoint.javascript.microtask .icon): Added. 275 * UserInterface/Views/URLBreakpointTreeElement.js: 276 (WI.URLBreakpointTreeElement): 277 (WI.URLBreakpointTreeElement.prototype.onattach): Deleted. 278 (WI.URLBreakpointTreeElement.prototype.ondetach): Deleted. 279 (WI.URLBreakpointTreeElement.prototype.ondelete): Deleted. 280 (WI.URLBreakpointTreeElement.prototype.onenter): Deleted. 281 (WI.URLBreakpointTreeElement.prototype.onspace): Deleted. 282 (WI.URLBreakpointTreeElement.prototype.populateContextMenu): Deleted. 283 (WI.URLBreakpointTreeElement.prototype._statusImageElementClicked): Deleted. 284 (WI.URLBreakpointTreeElement.prototype._statusImageElementFocused): Deleted. 285 (WI.URLBreakpointTreeElement.prototype._statusImageElementMouseDown): Deleted. 286 (WI.URLBreakpointTreeElement.prototype._toggleBreakpoint): Deleted. 287 (WI.URLBreakpointTreeElement.prototype._updateStatus): Deleted. 288 * UserInterface/Views/URLBreakpointTreeElement.css: 289 (.item.breakpoint.url .subtitle): Added. 290 (.item.breakpoint.url:not(.paused) .icon): Added. 291 (@media (prefers-color-scheme: dark) .item.breakpoint.url:not(.paused) .icon): Added. 292 (.breakpoint.url .subtitle): Deleted. 293 (.breakpoint.url:not(.breakpoint-paused-icon) .icon): Deleted. 294 (@media (prefers-color-scheme: dark) .breakpoint.url:not(.breakpoint-paused-icon) .icon): Deleted. 295 Rename `WI.BreakpointTreeElement` to `WI.JavaScriptBreakpointTreeElement` and use 296 `WI.BreakpointTreeElement` as a new common base class for all breakpoint tree elements, 297 allowing more logic and styles to be shared (e.g. disabled state). 298 299 * UserInterface/Views/SourcesNavigationSidebarPanel.js: 300 (WI.SourcesNavigationSidebarPanel): 301 (WI.SourcesNavigationSidebarPanel.prototype.closed): 302 (WI.SourcesNavigationSidebarPanel.prototype._insertDebuggerTreeElement): 303 (WI.SourcesNavigationSidebarPanel.prototype._compareJavaScriptBreakpointTreeElements): Added. 304 (WI.SourcesNavigationSidebarPanel.prototype._addBreakpoint): 305 (WI.SourcesNavigationSidebarPanel.prototype._removeAllBreakpoints): 306 (WI.SourcesNavigationSidebarPanel.prototype._breakpointsBeneathTreeElement): 307 (WI.SourcesNavigationSidebarPanel.prototype._addIssue): 308 (WI.SourcesNavigationSidebarPanel.prototype._updatePauseReasonSection): 309 (WI.SourcesNavigationSidebarPanel.prototype._handleTreeSelectionDidChange): 310 (WI.SourcesNavigationSidebarPanel.prototype._handleBreakpointElementAddedOrRemoved): 311 (WI.SourcesNavigationSidebarPanel.prototype._populateCreateBreakpointContextMenu.addToggleForSpecialEventBreakpoint): 312 (WI.SourcesNavigationSidebarPanel.prototype._populateCreateBreakpointContextMenu): 313 (WI.SourcesNavigationSidebarPanel.prototype._handleDebuggerObjectDisplayLocationDidChange): 314 (WI.SourcesNavigationSidebarPanel.prototype._compareBreakpointTreeElements): Deleted. 315 316 * UserInterface/Models/ProbeSet.js: 317 (WI.ProbeSet): 318 (WI.ProbeSet.prototype.createProbe): 319 (WI.ProbeSet.prototype.willRemove): 320 * UserInterface/Controllers/TimelineManager.js: 321 (WI.TimelineManager.prototype._processRecord): 322 * UserInterface/Views/ProbeSetDetailsSection.js: 323 (WI.ProbeSetDetailsSection): 324 * UserInterface/Views/ProbeDetailsSidebarPanel.js: 325 (WI.ProbeDetailsSidebarPanel.prototype.inspect): 326 * UserInterface/Views/SourceCodeTextEditor.js: 327 (WI.SourceCodeTextEditor): 328 (WI.SourceCodeTextEditor.prototype.close): 329 (WI.SourceCodeTextEditor.prototype.textEditorBreakpointAdded): 330 * UserInterface/Views/TextResourceContentView.js: 331 (WI.TextResourceContentView.prototype.get supplementalRepresentedObjects): 332 (WI.TextResourceContentView.prototype._probeSetsChanged): 333 Probes now support `WI.EventBreakpoint` in addition to `WI.JavaScriptBreakpoint`. 334 335 * UserInterface/Views/ContentView.js: 336 (WI.ContentView.createFromRepresentedObject): 337 (WI.ContentView.resolvedRepresentedObjectForRepresentedObject): 338 (WI.ContentView.isViewable): 339 * UserInterface/Views/ContextMenuUtilities.js: 340 (WI.appendContextMenuItemsForSourceCode): 341 Replace `WI.Breakpoint` with `WI.JavaScriptBreakpoint`. 342 343 * UserInterface/Views/DOMTreeContentView.js: 344 (WI.DOMTreeContentView): 345 Replace `WI.DOMBreakpoint` with `WI.Breakpoint`. 346 347 * UserInterface/Views/EventListenerSectionGroup.js: 348 (WI.EventListenerSectionGroup): 349 * UserInterface/Views/EventListenerSectionGroup.css: 350 (.event-listener-section > .content input[type="checkbox"] + .go-to-arrow): Added. 351 (.event-listener-section > .content input[type="checkbox"]:not(:checked) + .go-to-arrow): Added. 352 Add a go-to arrow next to the Breakpoint checkbox that reveals the `WI.EventBreakpoint` in 353 the Sources Tab. 354 355 * UserInterface/Views/BreakpointActionView.js: 356 (WI.BreakpointActionView.prototype._appendActionButtonClicked): 357 Drive-by: minor code cleanup. 358 359 * UserInterface/Views/CallFrameTreeElement.js: 360 (WI.CallFrameTreeElement.prototype.populateContextMenu): 361 Drive-by: include source code location context menu items. 362 363 * UserInterface/Base/Setting.js: 364 * UserInterface/Main.html: 365 * UserInterface/Test.html: 366 1 367 2020-08-24 Devin Rousso <drousso@apple.com> 2 368 -
trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js
r259929 r266074 198 198 selectedNetworkDetailContentViewIdentifier: new WI.Setting("network-detail-content-view-identifier", "preview"), 199 199 sourceMapsEnabled: new WI.Setting("source-maps-enabled", true), 200 showAllAnimationFramesBreakpoint: new WI.Setting("show-all-animation-frames-breakpoint", false),201 showAllIntervalsBreakpoint: new WI.Setting("show-all-inteverals-breakpoint", false),202 showAllListenersBreakpoint: new WI.Setting("show-all-listeners-breakpoint", false),203 200 showAllMicrotasksBreakpoint: new WI.Setting("show-all-microtasks-breakpoint", false), 204 201 showAllRequestsBreakpoint: new WI.Setting("show-all-requests-breakpoint", false), 205 showAllTimeoutsBreakpoint: new WI.Setting("show-all-timeouts-breakpoint", false),206 202 showAssertionFailuresBreakpoint: new WI.Setting("show-assertion-failures-breakpoint", true), 207 203 showCanvasPath: new WI.Setting("show-canvas-path", false), -
trunk/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js
r261109 r266074 41 41 console.assert(document.body.contains(breakpointDisplayElement), "Breakpoint popover display element must be in the DOM."); 42 42 43 const editBreakpoint = () => { 44 console.assert(!this._popover, "Breakpoint popover already exists."); 45 if (this._popover) 46 return; 47 48 this._createPopoverContent(breakpoint); 49 this._popover = new WI.Popover(this); 50 this._popover.content = this._popoverContentElement; 51 52 let bounds = WI.Rect.rectFromClientRect(breakpointDisplayElement.getBoundingClientRect()); 53 bounds.origin.x -= 1; // Move the anchor left one pixel so it looks more centered. 54 this._popover.present(bounds.pad(2), [WI.RectEdge.MAX_Y]); 55 }; 56 57 const removeBreakpoint = () => { 58 WI.debuggerManager.removeBreakpoint(breakpoint); 59 }; 60 61 const toggleBreakpoint = () => { 62 breakpoint.disabled = !breakpoint.disabled; 63 }; 64 65 const toggleAutoContinue = () => { 66 breakpoint.autoContinue = !breakpoint.autoContinue; 67 }; 68 69 const revealOriginalSourceCodeLocation = () => { 70 const options = { 71 ignoreNetworkTab: true, 72 ignoreSearchTab: true, 73 }; 74 WI.showOriginalOrFormattedSourceCodeLocation(breakpoint.sourceCodeLocation, options); 75 }; 76 77 if (WI.debuggerManager.isBreakpointEditable(breakpoint)) 78 contextMenu.appendItem(WI.UIString("Edit Breakpoint\u2026"), editBreakpoint); 79 80 if (breakpoint.autoContinue && !breakpoint.disabled) { 81 contextMenu.appendItem(WI.UIString("Disable Breakpoint"), toggleBreakpoint); 82 contextMenu.appendItem(WI.UIString("Cancel Automatic Continue"), toggleAutoContinue); 83 } else if (!breakpoint.disabled) 84 contextMenu.appendItem(WI.UIString("Disable Breakpoint"), toggleBreakpoint); 85 else 86 contextMenu.appendItem(WI.UIString("Enable Breakpoint"), toggleBreakpoint); 87 88 if (!breakpoint.autoContinue && !breakpoint.disabled && breakpoint.actions.length) 89 contextMenu.appendItem(WI.UIString("Set to Automatically Continue"), toggleAutoContinue); 90 91 if (WI.debuggerManager.isBreakpointRemovable(breakpoint)) 92 contextMenu.appendItem(WI.UIString("Delete Breakpoint"), removeBreakpoint); 93 94 if (breakpoint._sourceCodeLocation.hasMappedLocation()) { 43 if (breakpoint.editable) { 44 contextMenu.appendItem(WI.UIString("Edit Breakpoint\u2026"), () => { 45 console.assert(!this._popover, "Breakpoint popover already exists."); 46 if (this._popover) 47 return; 48 49 this._createPopoverContent(breakpoint); 50 this._popover = new WI.Popover(this); 51 this._popover.content = this._popoverContentElement; 52 53 let bounds = WI.Rect.rectFromClientRect(breakpointDisplayElement.getBoundingClientRect()); 54 bounds.origin.x -= 1; // Move the anchor left one pixel so it looks more centered. 55 this._popover.present(bounds.pad(2), [WI.RectEdge.MAX_Y]); 56 }); 57 } 58 59 if (!breakpoint.disabled) { 60 contextMenu.appendItem(WI.UIString("Disable Breakpoint"), () => { 61 breakpoint.disabled = !breakpoint.disabled; 62 }); 63 64 if (breakpoint.editable && breakpoint.autoContinue) { 65 contextMenu.appendItem(WI.UIString("Cancel Automatic Continue"), () => { 66 breakpoint.autoContinue = !breakpoint.autoContinue; 67 }); 68 } 69 } else { 70 contextMenu.appendItem(WI.UIString("Enable Breakpoint"), () => { 71 breakpoint.disabled = !breakpoint.disabled; 72 }); 73 } 74 75 if (breakpoint.editable && !breakpoint.autoContinue && !breakpoint.disabled && breakpoint.actions.length) { 76 contextMenu.appendItem(WI.UIString("Set to Automatically Continue"), () => { 77 breakpoint.autoContinue = !breakpoint.autoContinue; 78 }); 79 } 80 81 if (breakpoint.removable) { 82 contextMenu.appendItem(WI.UIString("Delete Breakpoint"), () => { 83 breakpoint.remove(); 84 }); 85 } 86 87 if (breakpoint instanceof WI.JavaScriptBreakpoint && breakpoint.sourceCodeLocation.hasMappedLocation()) { 95 88 contextMenu.appendSeparator(); 96 contextMenu.appendItem(WI.UIString("Reveal in Original Resource"), revealOriginalSourceCodeLocation); 89 contextMenu.appendItem(WI.UIString("Reveal in Original Resource"), () => { 90 const options = { 91 ignoreNetworkTab: true, 92 ignoreSearchTab: true, 93 }; 94 WI.showOriginalOrFormattedSourceCodeLocation(breakpoint.sourceCodeLocation, options); 95 }); 97 96 } 98 97 } … … 125 124 checkboxLabel.className = "toggle"; 126 125 checkboxLabel.appendChild(checkboxElement); 127 checkboxLabel.append(this._breakpoint.sourceCodeLocation.displayLocationString()); 126 if (this._breakpoint instanceof WI.JavaScriptBreakpoint) 127 checkboxLabel.append(this._breakpoint.sourceCodeLocation.displayLocationString()); 128 else if (this._breakpoint instanceof WI.EventBreakpoint) { 129 let displayName; 130 if (breakpoint === WI.domDebuggerManager.allAnimationFramesBreakpoint) 131 displayName = WI.UIString("All Animation Frames"); 132 else if (breakpoint === WI.domDebuggerManager.allIntervalsBreakpoint) 133 displayName = WI.UIString("All Intervals"); 134 else if (breakpoint === WI.domDebuggerManager.allListenersBreakpoint) 135 displayName = WI.UIString("All Events"); 136 else if (breakpoint === WI.domDebuggerManager.allTimeoutsBreakpoint) 137 displayName = WI.UIString("All Timeouts"); 138 else 139 displayName = breakpoint.eventName; 140 checkboxLabel.appendChild(document.createTextNode(displayName)); 141 } 128 142 129 143 let table = document.createElement("table"); … … 177 191 this._ignoreCountInput.type = "number"; 178 192 this._ignoreCountInput.min = 0; 179 this._ignoreCountInput.value = 0;193 this._ignoreCountInput.value = breakpoint.ignoreCount; 180 194 this._ignoreCountInput.addEventListener("change", this._popoverIgnoreInputChanged.bind(this)); 181 195 -
trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMDebuggerManager.js
r261340 r266074 34 34 35 35 this._listenerBreakpoints = []; 36 this._allAnimationFramesBreakpoint = null; 37 this._allIntervalsBreakpoint = null; 38 this._allListenersBreakpoint = null; 39 this._allTimeoutsBreakpoint = null; 40 36 41 this._urlBreakpoints = []; 37 38 this._allAnimationFramesBreakpointEnabledSetting = new WI.Setting("break-on-all-animation-frames", false);39 this._allAnimationFramesBreakpoint = new WI.EventBreakpoint(WI.EventBreakpoint.Type.AnimationFrame, {40 disabled: !this._allAnimationFramesBreakpointEnabledSetting.value,41 });42 43 this._allIntervalsBreakpointEnabledSetting = new WI.Setting("break-on-all-intervals", false);44 this._allIntervalsBreakpoint = new WI.EventBreakpoint(WI.EventBreakpoint.Type.Interval, {45 disabled: !this._allIntervalsBreakpointEnabledSetting.value,46 });47 48 this._allListenersBreakpointEnabledSetting = new WI.Setting("break-on-all-listeners", false);49 this._allListenersBreakpoint = new WI.EventBreakpoint(WI.EventBreakpoint.Type.Listener, {50 disabled: !this._allListenersBreakpointEnabledSetting.value,51 });52 53 this._allTimeoutsBreakpointEnabledSetting = new WI.Setting("break-on-all-timeouts", false);54 this._allTimeoutsBreakpoint = new WI.EventBreakpoint(WI.EventBreakpoint.Type.Timeout, {55 disabled: !this._allTimeoutsBreakpointEnabledSetting.value,56 });57 42 58 43 this._allRequestsBreakpointEnabledSetting = new WI.Setting("break-on-all-requests", false); … … 61 46 }); 62 47 63 WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.DisabledStateChanged, this._handleDOMBreakpointDisabledStateChanged, this); 64 WI.EventBreakpoint.addEventListener(WI.EventBreakpoint.Event.DisabledStateChanged, this._handleEventBreakpointDisabledStateChanged, this); 65 WI.URLBreakpoint.addEventListener(WI.URLBreakpoint.Event.DisabledStateChanged, this._handleURLBreakpointDisabledStateChanged, this); 48 WI.DOMBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._handleDOMBreakpointDisabledStateChanged, this); 49 50 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._handleEventBreakpointDisabledStateChanged, this); 51 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, this._handleEventBreakpointEditablePropertyChanged, this); 52 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.IgnoreCountDidChange, this._handleEventBreakpointEditablePropertyChanged, this); 53 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._handleEventBreakpointEditablePropertyChanged, this); 54 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleEventBreakpointActionsChanged, this); 55 56 WI.URLBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._handleURLBreakpointDisabledStateChanged, this); 66 57 67 58 WI.domManager.addEventListener(WI.DOMManager.Event.NodeRemoved, this._nodeRemoved, this); … … 79 70 if (existingSerializedBreakpoints) { 80 71 for (let existingSerializedBreakpoint of existingSerializedBreakpoints) 81 await objectStore.putObject(constructor. deserialize(existingSerializedBreakpoint));72 await objectStore.putObject(constructor.fromJSON(existingSerializedBreakpoint)); 82 73 } 83 74 } … … 87 78 this._restoringBreakpoints = true; 88 79 for (let serializedBreakpoint of serializedBreakpoints) { 89 let breakpoint = constructor. deserialize(serializedBreakpoint);80 let breakpoint = constructor.fromJSON(serializedBreakpoint); 90 81 91 82 const key = null; … … 106 97 if (DOMDebuggerManager.supportsEventBreakpoints() || DOMDebuggerManager.supportsEventListenerBreakpoints()) { 107 98 loadBreakpoints(WI.EventBreakpoint, WI.objectStores.eventBreakpoints, ["event-breakpoints"], (breakpoint) => { 108 // Migrate `requestAnimationFrame`, `setTimeout`, and `setInterval` global breakpoints.109 switch (breakpoint.type) {110 case WI.EventBreakpoint.Type.AnimationFrame:111 this._allAnimationFramesBreakpoint.disabled = breakpoint.disabled;112 if (!WI.settings.showAllAnimationFramesBreakpoint.value) {113 WI.settings.showAllAnimationFramesBreakpoint.value = true;114 this.addEventBreakpoint(this._allAnimationFramesBreakpoint);115 }116 WI.objectStores.eventBreakpoints.deleteObject(breakpoint);117 return;118 119 case WI.EventBreakpoint.Type.Timer:120 switch (breakpoint.eventName) {121 case "setTimeout":122 this._allTimeoutsBreakpoint.disabled = breakpoint.disabled;123 if (!WI.settings.showAllTimeoutsBreakpoint.value) {124 WI.settings.showAllTimeoutsBreakpoint.value = true;125 this.addEventBreakpoint(this._allTimeoutsBreakpoint);126 }127 break;128 129 case "setInterval":130 this._allIntervalsBreakpoint.disabled = breakpoint.disabled;131 if (!WI.settings.showAllIntervalsBreakpoint.value) {132 WI.settings.showAllIntervalsBreakpoint.value = true;133 this.addEventBreakpoint(this._allIntervalsBreakpoint);134 }135 break;136 }137 138 WI.objectStores.eventBreakpoints.deleteObject(breakpoint);139 return;140 }141 142 99 this.addEventBreakpoint(breakpoint); 143 100 }); 101 102 let loadLegacyGlobalEventBreakpoint = (type, shownSettingsKey, enabledSettingsKey) => { 103 if (!WI.Setting.migrateValue(shownSettingsKey)) 104 return; 105 106 return new WI.EventBreakpoint(type, { 107 disabled: !WI.Setting.migrateValue(enabledSettingsKey), 108 }); 109 }; 110 this._allAnimationFramesBreakpoint ??= loadLegacyGlobalEventBreakpoint(WI.EventBreakpoint.Type.AnimationFrame, "show-all-animation-frames-breakpoint", "break-on-all-animation-frames"); 111 this._allIntervalsBreakpoint ??= loadLegacyGlobalEventBreakpoint(WI.EventBreakpoint.Type.Interval, "show-all-inteverals-breakpoint", "break-on-all-intervals"); 112 this._allListenersBreakpoint ??= loadLegacyGlobalEventBreakpoint(WI.EventBreakpoint.Type.Listener, "show-all-listeners-breakpoint", "break-on-all-listeners"); 113 this._allTimeoutsBreakpoint ??= loadLegacyGlobalEventBreakpoint(WI.EventBreakpoint.Type.Timeout, "show-all-timeouts-breakpoint", "break-on-all-timeouts"); 144 114 } 145 115 … … 161 131 this._speculativelyResolveDOMBreakpointsForURL(target.mainResource.url); 162 132 163 if ( !this._allAnimationFramesBreakpoint.disabled)164 this._ updateEventBreakpoint(this._allAnimationFramesBreakpoint, target);165 166 if ( !this._allIntervalsBreakpoint.disabled)167 this._ updateEventBreakpoint(this._allIntervalsBreakpoint, target);168 169 if ( !this._allListenersBreakpoint.disabled)170 this._ updateEventBreakpoint(this._allListenersBreakpoint, target);171 172 if ( !this._allTimeoutsBreakpoint.disabled)173 this._ updateEventBreakpoint(this._allTimeoutsBreakpoint, target);133 if (this._allAnimationFramesBreakpoint && !this._allAnimationFramesBreakpoint.disabled) 134 this._setEventBreakpoint(this._allAnimationFramesBreakpoint, target); 135 136 if (this._allIntervalsBreakpoint && !this._allIntervalsBreakpoint.disabled) 137 this._setEventBreakpoint(this._allIntervalsBreakpoint, target); 138 139 if (this._allListenersBreakpoint && !this._allListenersBreakpoint.disabled) 140 this._setEventBreakpoint(this._allListenersBreakpoint, target); 141 142 if (this._allTimeoutsBreakpoint && !this._allTimeoutsBreakpoint.disabled) 143 this._setEventBreakpoint(this._allTimeoutsBreakpoint, target); 174 144 175 145 if (!this._allRequestsBreakpoint.disabled) … … 178 148 for (let breakpoint of this._listenerBreakpoints) { 179 149 if (!breakpoint.disabled) 180 this._ updateEventBreakpoint(breakpoint, target);150 this._setEventBreakpoint(breakpoint, target); 181 151 } 182 152 … … 270 240 get listenerBreakpoints() { return this._listenerBreakpoints; } 271 241 get urlBreakpoints() { return this._urlBreakpoints; } 272 273 isBreakpointSpecial(breakpoint)274 {275 return breakpoint === this._allAnimationFramesBreakpoint276 || breakpoint === this._allIntervalsBreakpoint277 || breakpoint === this._allListenersBreakpoint278 || breakpoint === this._allTimeoutsBreakpoint279 || breakpoint === this._allRequestsBreakpoint;280 }281 242 282 243 domBreakpointsForNode(node) … … 320 281 return; 321 282 322 if ( this.isBreakpointSpecial(breakpoint)) {283 if (breakpoint.special) { 323 284 this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.DOMBreakpointAdded, {breakpoint}); 324 285 return; … … 342 303 return; 343 304 344 if ( this.isBreakpointSpecial(breakpoint)) {305 if (breakpoint.special) { 345 306 breakpoint.disabled = true; 346 307 this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, {breakpoint}); … … 384 345 return false; 385 346 386 if (this.isBreakpointSpecial(breakpoint)) { 387 this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointAdded, {breakpoint}); 388 return true; 389 } 390 391 console.assert(breakpoint.type === WI.EventBreakpoint.Type.Listener, breakpoint); 392 console.assert(breakpoint.eventName, breakpoint); 393 394 if (this._listenerBreakpoints.find((existing) => existing.eventName === breakpoint.eventName)) 395 return false; 396 397 this._listenerBreakpoints.push(breakpoint); 347 console.assert(!breakpoint.special, breakpoint); 348 349 switch (breakpoint.type) { 350 case WI.EventBreakpoint.Type.AnimationFrame: 351 console.assert(!this._allAnimationFramesBreakpoint, this._allAnimationFramesBreakpoint, breakpoint); 352 this._allAnimationFramesBreakpoint = breakpoint; 353 break; 354 355 case WI.EventBreakpoint.Type.Interval: 356 console.assert(!this._allIntervalsBreakpoint, this._allIntervalsBreakpoint, breakpoint); 357 this._allIntervalsBreakpoint = breakpoint; 358 break; 359 360 case WI.EventBreakpoint.Type.Listener: 361 if (breakpoint.eventName) { 362 if (this._listenerBreakpoints.find((existing) => existing.eventName === breakpoint.eventName)) 363 return false; 364 365 this._listenerBreakpoints.push(breakpoint); 366 } else { 367 console.assert(!this._allListenersBreakpoint, this._allListenersBreakpoint, breakpoint); 368 this._allListenersBreakpoint = breakpoint; 369 } 370 break; 371 372 case WI.EventBreakpoint.Type.Timeout: 373 console.assert(!this._allTimeoutsBreakpoint, this._allTimeoutsBreakpoint, breakpoint); 374 this._allTimeoutsBreakpoint = breakpoint; 375 break; 376 } 377 378 WI.debuggerManager.addProbesForBreakpoint(breakpoint); 398 379 399 380 this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointAdded, {breakpoint}); … … 401 382 if (!breakpoint.disabled) { 402 383 for (let target of WI.targets) 403 this._ updateEventBreakpoint(breakpoint, target);384 this._setEventBreakpoint(breakpoint, target); 404 385 } 405 386 … … 416 397 return; 417 398 418 if (this.isBreakpointSpecial(breakpoint)) { 419 breakpoint.disabled = true; 420 this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointRemoved, {breakpoint}); 421 return; 422 } 423 424 console.assert(breakpoint.type === WI.EventBreakpoint.Type.Listener, breakpoint); 425 console.assert(breakpoint.eventName, breakpoint); 426 427 console.assert(this._listenerBreakpoints.includes(breakpoint), breakpoint); 428 if (!this._listenerBreakpoints.includes(breakpoint)) 429 return; 430 431 this._listenerBreakpoints.remove(breakpoint); 399 // Disable the breakpoint first, so removing actions doesn't re-add the breakpoint. 400 breakpoint.disabled = true; 401 breakpoint.clearActions(); 402 403 switch (breakpoint.type) { 404 case WI.EventBreakpoint.Type.AnimationFrame: 405 console.assert(this._allAnimationFramesBreakpoint, this._allAnimationFramesBreakpoint); 406 this._allAnimationFramesBreakpoint = null; 407 break; 408 409 case WI.EventBreakpoint.Type.Interval: 410 console.assert(this._allIntervalsBreakpoint, this._allIntervalsBreakpoint); 411 this._allIntervalsBreakpoint = null; 412 break; 413 414 case WI.EventBreakpoint.Type.Listener: 415 if (breakpoint.eventName) { 416 console.assert(this._listenerBreakpoints.includes(breakpoint), breakpoint); 417 if (!this._listenerBreakpoints.includes(breakpoint)) 418 return; 419 420 this._listenerBreakpoints.remove(breakpoint); 421 } else { 422 console.assert(this._allListenersBreakpoint, this._allListenersBreakpoint); 423 this._allListenersBreakpoint = null; 424 } 425 break; 426 427 case WI.EventBreakpoint.Type.Timeout: 428 console.assert(this._allTimeoutsBreakpoint, this._allTimeoutsBreakpoint); 429 this._allTimeoutsBreakpoint = null; 430 break; 431 } 432 432 433 433 if (!this._restoringBreakpoints) 434 434 WI.objectStores.eventBreakpoints.deleteObject(breakpoint); 435 435 436 WI.debuggerManager.removeProbesForBreakpoint(breakpoint); 437 436 438 this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointRemoved, {breakpoint}); 437 438 if (breakpoint.disabled)439 return;440 441 for (let target of WI.targets) {442 // COMPATIBILITY (iOS 12): DOMDebugger.removeEventBreakpoint did not exist.443 if (target.hasCommand("DOMDebugger.removeEventBreakpoint"))444 target.DOMDebuggerAgent.removeEventBreakpoint(breakpoint.type, breakpoint.eventName);445 else if (target.hasCommand("DOMDebugger.removeEventListenerBreakpoint")) {446 console.assert(breakpoint.type === WI.EventBreakpoint.Type.Listener);447 target.DOMDebuggerAgent.removeEventListenerBreakpoint(breakpoint.eventName);448 }449 }450 439 } 451 440 … … 461 450 return false; 462 451 463 if ( this.isBreakpointSpecial(breakpoint)) {452 if (breakpoint.special) { 464 453 this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.URLBreakpointAdded, {breakpoint}); 465 454 return true; … … 494 483 return; 495 484 496 if ( this.isBreakpointSpecial(breakpoint)) {485 if (breakpoint.special) { 497 486 breakpoint.disabled = true; 498 487 this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.URLBreakpointRemoved, {breakpoint}); … … 633 622 } 634 623 635 _updateEventBreakpoint(breakpoint, target) 636 { 637 // Worker targets do not support `requestAnimationFrame` breakpoints. 638 if (breakpoint === this._allAnimationFramesBreakpoint && target.type === WI.TargetType.Worker) 639 return; 640 641 // COMPATIBILITY (iOS 12): DOMDebugger.removeEventBreakpoint did not exist. 642 if (target.hasCommand("DOMDebugger.setEventListenerBreakpoint") && target.hasCommand("DOMDebugger.removeEventListenerBreakpoint")) { 643 console.assert(breakpoint.type === WI.EventBreakpoint.Type.Listener); 644 if (breakpoint.disabled) 645 target.DOMDebuggerAgent.removeEventListenerBreakpoint(breakpoint.eventName); 646 else { 647 if (!this._restoringBreakpoints && !WI.debuggerManager.breakpointsDisabledTemporarily) 648 WI.debuggerManager.breakpointsEnabled = true; 649 650 target.DOMDebuggerAgent.setEventListenerBreakpoint(breakpoint.eventName); 651 } 652 return; 653 } 654 655 if (!target.hasCommand("DOMDebugger.setEventBreakpoint") || !target.hasCommand("DOMDebugger.removeEventBreakpoint")) 656 return; 657 624 _commandArgumentsForEventBreakpoint(breakpoint) 625 { 658 626 let commandArguments = {}; 659 627 … … 697 665 } 698 666 699 const callback = null; 700 701 if (breakpoint.disabled) 702 target.DOMDebuggerAgent.removeEventBreakpoint.invoke(commandArguments, callback); 703 else { 667 return commandArguments; 668 } 669 670 _setEventBreakpoint(breakpoint, target) 671 { 672 console.assert(!breakpoint.disabled, breakpoint); 673 674 // Worker targets do not support `requestAnimationFrame` breakpoints. 675 if (breakpoint === this._allAnimationFramesBreakpoint && target.type === WI.TargetType.Worker) 676 return; 677 678 // COMPATIBILITY (iOS 12): DOMDebugger.setEventBreakpoint did not exist. 679 if (target.hasCommand("DOMDebugger.setEventListenerBreakpoint")) { 680 console.assert(breakpoint.type === WI.EventBreakpoint.Type.Listener); 681 704 682 if (!this._restoringBreakpoints && !WI.debuggerManager.breakpointsDisabledTemporarily) 705 683 WI.debuggerManager.breakpointsEnabled = true; 706 684 707 target.DOMDebuggerAgent.setEventBreakpoint.invoke(commandArguments, callback); 708 } 685 target.DOMDebuggerAgent.setEventListenerBreakpoint(breakpoint.eventName); 686 return; 687 } 688 689 if (!target.hasCommand("DOMDebugger.setEventBreakpoint")) 690 return; 691 692 let commandArguments = this._commandArgumentsForEventBreakpoint(breakpoint); 693 694 if (!this._restoringBreakpoints && !WI.debuggerManager.breakpointsDisabledTemporarily) 695 WI.debuggerManager.breakpointsEnabled = true; 696 697 commandArguments.options = breakpoint.optionsToProtocol(); 698 699 target.DOMDebuggerAgent.setEventBreakpoint.invoke(commandArguments); 700 } 701 702 _removeEventBreakpoint(breakpoint, target) 703 { 704 // Worker targets do not support `requestAnimationFrame` breakpoints. 705 if (breakpoint === this._allAnimationFramesBreakpoint && target.type === WI.TargetType.Worker) 706 return; 707 708 // COMPATIBILITY (iOS 12): DOMDebugger.removeEventBreakpoint did not exist. 709 if (target.hasCommand("DOMDebugger.removeEventListenerBreakpoint")) { 710 console.assert(breakpoint.type === WI.EventBreakpoint.Type.Listener); 711 target.DOMDebuggerAgent.removeEventListenerBreakpoint(breakpoint.eventName); 712 return; 713 } 714 715 if (!target.hasCommand("DOMDebugger.removeEventBreakpoint")) 716 return; 717 718 let commandArguments = this._commandArgumentsForEventBreakpoint(breakpoint); 719 720 target.DOMDebuggerAgent.removeEventBreakpoint.invoke(commandArguments); 709 721 } 710 722 … … 758 770 return; 759 771 760 for (let target of WI.targets) 761 this._updateEventBreakpoint(breakpoint, target); 762 763 switch (breakpoint) { 764 case this._allAnimationFramesBreakpoint: 765 this._allAnimationFramesBreakpointEnabledSetting.value = !breakpoint.disabled; 766 return; 767 768 case this._allIntervalsBreakpoint: 769 this._allIntervalsBreakpointEnabledSetting.value = !breakpoint.disabled; 770 return; 771 772 case this._allListenersBreakpoint: 773 this._allListenersBreakpointEnabledSetting.value = !breakpoint.disabled; 774 return; 775 776 case this._allTimeoutsBreakpoint: 777 this._allTimeoutsBreakpointEnabledSetting.value = !breakpoint.disabled; 778 return; 772 for (let target of WI.targets) { 773 if (breakpoint.disabled) 774 this._removeEventBreakpoint(breakpoint, target); 775 else 776 this._setEventBreakpoint(breakpoint, target); 779 777 } 780 778 781 779 if (!this._restoringBreakpoints) 782 780 WI.objectStores.eventBreakpoints.putObject(breakpoint); 781 } 782 783 _handleEventBreakpointEditablePropertyChanged(event) 784 { 785 let breakpoint = event.target; 786 787 // Specific event listener breakpoints are handled by `DOMManager`. 788 if (breakpoint.eventListener) 789 return; 790 791 if (!this._restoringBreakpoints) 792 WI.objectStores.eventBreakpoints.putObject(breakpoint); 793 794 if (breakpoint.disabled) 795 return; 796 797 for (let target of WI.targets) { 798 // Clear the old breakpoint from the backend before setting the new one. 799 this._removeEventBreakpoint(breakpoint, target) 800 this._setEventBreakpoint(breakpoint, target); 801 } 802 } 803 804 _handleEventBreakpointActionsChanged(event) 805 { 806 let breakpoint = event.target; 807 808 // Specific event listener breakpoints are handled by `DOMManager`. 809 if (breakpoint.eventListener) 810 return; 811 812 this._handleEventBreakpointEditablePropertyChanged(event); 813 814 WI.debuggerManager.updateProbesForBreakpoint(breakpoint); 783 815 } 784 816 -
trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js
r262302 r266074 51 51 this._pendingDocumentRequestCallbacks = null; 52 52 53 WI.EventBreakpoint.addEventListener(WI.EventBreakpoint.Event.DisabledStateChanged, this._handleEventBreakpointDisabledStateChanged, this); 53 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._handleEventBreakpointDisabledStateChanged, this); 54 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, this._handleEventBreakpointEditablePropertyChanged, this); 55 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.IgnoreCountDidChange, this._handleEventBreakpointEditablePropertyChanged, this); 56 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._handleEventBreakpointEditablePropertyChanged, this); 57 WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleEventBreakpointActionsChanged, this); 54 58 55 59 WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this); … … 125 129 return InspectorBackend.hasCommand("DOM.setBreakpointForEventListener") 126 130 && InspectorBackend.hasCommand("DOM.removeBreakpointForEventListener"); 131 } 132 133 static supportsEventListenerBreakpointConfiguration() 134 { 135 // COMPATIBILITY (iOS 14): DOM.setBreakpointForEventListener did not have an "options" parameter yet. 136 return InspectorBackend.hasCommand("DOM.setBreakpointForEventListener", "options"); 127 137 } 128 138 … … 665 675 for (let target of WI.targets) { 666 676 if (target.hasDomain("DOM")) 667 this._updateEventBreakpoint(breakpoint, target); 668 } 677 this._setEventBreakpoint(breakpoint, target); 678 } 679 680 WI.debuggerManager.addProbesForBreakpoint(breakpoint); 669 681 670 682 WI.domDebuggerManager.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointAdded, {breakpoint}); … … 680 692 target.DOMAgent.removeBreakpointForEventListener(eventListener.eventListenerId); 681 693 } 694 695 // Disable the breakpoint first, so removing actions doesn't re-add the breakpoint. 696 breakpoint.disabled = true; 697 breakpoint.clearActions(); 698 699 WI.debuggerManager.removeProbesForBreakpoint(breakpoint); 682 700 683 701 WI.domDebuggerManager.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointRemoved, {breakpoint}); … … 700 718 // Private 701 719 702 _updateEventBreakpoint(breakpoint, target) 703 { 720 _setEventBreakpoint(breakpoint, target) 721 { 722 console.assert(!breakpoint.disabled, breakpoint); 723 704 724 let eventListener = breakpoint.eventListener; 705 725 console.assert(eventListener); 706 726 707 if (breakpoint.disabled)708 target.DOMAgent.removeBreakpointForEventListener(eventListener.eventListenerId);709 else {710 727 if (!WI.debuggerManager.breakpointsDisabledTemporarily) 711 728 WI.debuggerManager.breakpointsEnabled = true; 712 729 713 target.DOMAgent.setBreakpointForEventListener(eventListener.eventListenerId); 714 } 730 target.DOMAgent.setBreakpointForEventListener.invoke({ 731 eventListenerId: eventListener.eventListenerId, 732 options: breakpoint.optionsToProtocol(), 733 }); 734 } 735 736 _removeEventBreakpoint(breakpoint, target) 737 { 738 let eventListener = breakpoint.eventListener; 739 console.assert(eventListener); 740 741 target.DOMAgent.removeBreakpointForEventListener(eventListener.eventListenerId); 715 742 } 716 743 … … 724 751 725 752 for (let target of WI.targets) { 726 if (target.hasDomain("DOM")) 727 this._updateEventBreakpoint(breakpoint, target); 728 } 753 if (!target.hasDomain("DOM")) 754 continue; 755 756 if (breakpoint.disabled) 757 this._removeEventBreakpoint(breakpoint, target); 758 else 759 this._setEventBreakpoint(breakpoint, target); 760 } 761 } 762 763 _handleEventBreakpointEditablePropertyChanged(event) 764 { 765 let breakpoint = event.target; 766 767 // Non-specific event listener breakpoints are handled by `DOMDebuggerManager`. 768 if (!breakpoint.eventListener) 769 return; 770 771 if (breakpoint.disabled) 772 return; 773 774 for (let target of WI.targets) { 775 // Clear the old breakpoint from the backend before setting the new one. 776 this._removeEventBreakpoint(breakpoint, target); 777 this._setEventBreakpoint(breakpoint, target); 778 } 779 } 780 781 _handleEventBreakpointActionsChanged(event) 782 { 783 let breakpoint = event.target; 784 785 // Non-specific event listener breakpoints are handled by `DOMDebuggerManager`. 786 if (!breakpoint.eventListener) 787 return; 788 789 this._handleEventBreakpointEditablePropertyChanged(event); 790 791 WI.debuggerManager.updateProbesForBreakpoint(breakpoint); 729 792 } 730 793 -
trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js
r261109 r266074 30 30 super(); 31 31 32 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.DisplayLocationDidChange, this._breakpointDisplayLocationDidChange, this);33 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._breakpointDisabledStateDidChange, this);34 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, this._breakpointEditablePropertyDidChange, this);35 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.IgnoreCountDidChange, this._breakpointEditablePropertyDidChange, this);36 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._breakpointEditablePropertyDidChange, this);37 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleBreakpointActionsDidChange, this);32 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._breakpointDisabledStateDidChange, this); 33 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, this._breakpointEditablePropertyDidChange, this); 34 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.IgnoreCountDidChange, this._breakpointEditablePropertyDidChange, this); 35 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._breakpointEditablePropertyDidChange, this); 36 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleBreakpointActionsDidChange, this); 37 WI.JavaScriptBreakpoint.addEventListener(WI.JavaScriptBreakpoint.Event.DisplayLocationDidChange, this._breakpointDisplayLocationDidChange, this); 38 38 39 39 WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this); … … 57 57 58 58 this._debuggerStatementsBreakpointEnabledSetting = new WI.Setting("break-on-debugger-statements", true); 59 this._debuggerStatementsBreakpoint = new WI. Breakpoint(specialBreakpointLocation, {59 this._debuggerStatementsBreakpoint = new WI.JavaScriptBreakpoint(specialBreakpointLocation, { 60 60 disabled: !this._debuggerStatementsBreakpointEnabledSetting.value, 61 61 }); … … 63 63 64 64 this._allExceptionsBreakpointEnabledSetting = new WI.Setting("break-on-all-exceptions", false); 65 this._allExceptionsBreakpoint = new WI. Breakpoint(specialBreakpointLocation, {65 this._allExceptionsBreakpoint = new WI.JavaScriptBreakpoint(specialBreakpointLocation, { 66 66 disabled: !this._allExceptionsBreakpointEnabledSetting.value, 67 67 }); … … 69 69 70 70 this._uncaughtExceptionsBreakpointEnabledSetting = new WI.Setting("break-on-uncaught-exceptions", false); 71 this._uncaughtExceptionsBreakpoint = new WI. Breakpoint(specialBreakpointLocation, {71 this._uncaughtExceptionsBreakpoint = new WI.JavaScriptBreakpoint(specialBreakpointLocation, { 72 72 disabled: !this._uncaughtExceptionsBreakpointEnabledSetting.value, 73 73 }); … … 75 75 76 76 this._assertionFailuresBreakpointEnabledSetting = new WI.Setting("break-on-assertion-failures", false); 77 this._assertionFailuresBreakpoint = new WI. Breakpoint(specialBreakpointLocation, {77 this._assertionFailuresBreakpoint = new WI.JavaScriptBreakpoint(specialBreakpointLocation, { 78 78 disabled: !this._assertionFailuresBreakpointEnabledSetting.value, 79 79 }); … … 81 81 82 82 this._allMicrotasksBreakpointEnabledSetting = new WI.Setting("break-on-all-microtasks", false); 83 this._allMicrotasksBreakpoint = new WI. Breakpoint(specialBreakpointLocation, {83 this._allMicrotasksBreakpoint = new WI.JavaScriptBreakpoint(specialBreakpointLocation, { 84 84 disabled: !this._allMicrotasksBreakpointEnabledSetting.value, 85 85 }); … … 127 127 if (existingSerializedBreakpoints) { 128 128 for (let existingSerializedBreakpoint of existingSerializedBreakpoints) 129 await WI.objectStores.breakpoints.putObject(WI. Breakpoint.fromJSON(existingSerializedBreakpoint));129 await WI.objectStores.breakpoints.putObject(WI.JavaScriptBreakpoint.fromJSON(existingSerializedBreakpoint)); 130 130 } 131 131 … … 134 134 this._restoringBreakpoints = true; 135 135 for (let serializedBreakpoint of serializedBreakpoints) { 136 let breakpoint = WI. Breakpoint.fromJSON(serializedBreakpoint);136 let breakpoint = WI.JavaScriptBreakpoint.fromJSON(serializedBreakpoint); 137 137 138 138 const key = null; … … 343 343 } 344 344 345 isBreakpointRemovable(breakpoint)346 {347 return breakpoint !== this._debuggerStatementsBreakpoint348 && breakpoint !== this._allExceptionsBreakpoint349 && breakpoint !== this._uncaughtExceptionsBreakpoint;350 }351 352 isBreakpointSpecial(breakpoint)353 {354 return !this.isBreakpointRemovable(breakpoint)355 || breakpoint === this._assertionFailuresBreakpoint356 || breakpoint === this._allMicrotasksBreakpoint;357 }358 359 isBreakpointEditable(breakpoint)360 {361 return !this.isBreakpointSpecial(breakpoint);362 }363 364 345 get breakpointsEnabled() 365 346 { … … 660 641 addBreakpoint(breakpoint) 661 642 { 662 console.assert(breakpoint instanceof WI. Breakpoint);643 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint); 663 644 if (!breakpoint) 664 645 return; 665 646 666 if ( this.isBreakpointSpecial(breakpoint)) {647 if (breakpoint.special) { 667 648 this.dispatchEventToListeners(WI.DebuggerManager.Event.BreakpointAdded, {breakpoint}); 668 649 return; … … 683 664 WI.objectStores.breakpoints.putObject(breakpoint); 684 665 685 this. _addProbesForBreakpoint(breakpoint);666 this.addProbesForBreakpoint(breakpoint); 686 667 687 668 this.dispatchEventToListeners(WI.DebuggerManager.Event.BreakpointAdded, {breakpoint}); … … 690 671 removeBreakpoint(breakpoint) 691 672 { 692 console.assert(breakpoint instanceof WI. Breakpoint);673 console.assert(breakpoint instanceof WI.JavaScriptBreakpoint); 693 674 if (!breakpoint) 694 675 return; 695 676 696 console.assert( this.isBreakpointRemovable(breakpoint));697 if (! this.isBreakpointRemovable(breakpoint))698 return; 699 700 if ( this.isBreakpointSpecial(breakpoint)) {677 console.assert(breakpoint.removable); 678 if (!breakpoint.removable) 679 return; 680 681 if (breakpoint.special) { 701 682 breakpoint.disabled = true; 702 683 this.dispatchEventToListeners(WI.DebuggerManager.Event.BreakpointRemoved, {breakpoint}); … … 722 703 WI.objectStores.breakpoints.deleteObject(breakpoint); 723 704 724 this. _removeProbesForBreakpoint(breakpoint);705 this.removeProbesForBreakpoint(breakpoint); 725 706 726 707 this.dispatchEventToListeners(WI.DebuggerManager.Event.BreakpointRemoved, {breakpoint}); … … 730 711 { 731 712 return this._nextBreakpointActionIdentifier++; 713 } 714 715 addProbesForBreakpoint(breakpoint) 716 { 717 if (this._knownProbeIdentifiersForBreakpoint.has(breakpoint)) 718 return; 719 720 this._knownProbeIdentifiersForBreakpoint.set(breakpoint, new Set); 721 722 this.updateProbesForBreakpoint(breakpoint); 723 } 724 725 removeProbesForBreakpoint(breakpoint) 726 { 727 console.assert(this._knownProbeIdentifiersForBreakpoint.has(breakpoint)); 728 729 this.updateProbesForBreakpoint(breakpoint); 730 this._knownProbeIdentifiersForBreakpoint.delete(breakpoint); 731 } 732 733 updateProbesForBreakpoint(breakpoint) 734 { 735 let knownProbeIdentifiers = this._knownProbeIdentifiersForBreakpoint.get(breakpoint); 736 if (!knownProbeIdentifiers) { 737 // Sometimes actions change before the added breakpoint is fully dispatched. 738 this.addProbesForBreakpoint(breakpoint); 739 return; 740 } 741 742 let seenProbeIdentifiers = new Set; 743 744 for (let probeAction of breakpoint.probeActions) { 745 let probeIdentifier = probeAction.id; 746 console.assert(probeIdentifier, "Probe added without breakpoint action identifier: ", breakpoint); 747 748 seenProbeIdentifiers.add(probeIdentifier); 749 if (!knownProbeIdentifiers.has(probeIdentifier)) { 750 // New probe; find or create relevant probe set. 751 knownProbeIdentifiers.add(probeIdentifier); 752 let probeSet = this._probeSetForBreakpoint(breakpoint); 753 let newProbe = new WI.Probe(probeIdentifier, breakpoint, probeAction.data); 754 this._probesByIdentifier.set(probeIdentifier, newProbe); 755 probeSet.addProbe(newProbe); 756 break; 757 } 758 759 let probe = this._probesByIdentifier.get(probeIdentifier); 760 console.assert(probe, "Probe known but couldn't be found by identifier: ", probeIdentifier); 761 // Update probe expression; if it differed, change events will fire. 762 probe.expression = probeAction.data; 763 } 764 765 // Look for missing probes based on what we saw last. 766 for (let probeIdentifier of knownProbeIdentifiers) { 767 if (seenProbeIdentifiers.has(probeIdentifier)) 768 break; 769 770 // The probe has gone missing, remove it. 771 let probeSet = this._probeSetForBreakpoint(breakpoint); 772 let probe = this._probesByIdentifier.get(probeIdentifier); 773 this._probesByIdentifier.delete(probeIdentifier); 774 knownProbeIdentifiers.delete(probeIdentifier); 775 probeSet.removeProbe(probe); 776 777 // Remove the probe set if it has become empty. 778 if (!probeSet.probes.length) { 779 this._probeSetsByBreakpoint.delete(probeSet.breakpoint); 780 probeSet.willRemove(); 781 this.dispatchEventToListeners(WI.DebuggerManager.Event.ProbeSetRemoved, {probeSet}); 782 } 783 } 732 784 } 733 785 … … 998 1050 } 999 1051 1000 _debuggerBreakpointActionType(type)1001 {1002 switch (type) {1003 case WI.BreakpointAction.Type.Log:1004 return InspectorBackend.Enum.Debugger.BreakpointActionType.Log;1005 case WI.BreakpointAction.Type.Evaluate:1006 return InspectorBackend.Enum.Debugger.BreakpointActionType.Evaluate;1007 case WI.BreakpointAction.Type.Sound:1008 return InspectorBackend.Enum.Debugger.BreakpointActionType.Sound;1009 case WI.BreakpointAction.Type.Probe:1010 return InspectorBackend.Enum.Debugger.BreakpointActionType.Probe;1011 default:1012 console.assert(false);1013 return InspectorBackend.Enum.Debugger.BreakpointActionType.Log;1014 }1015 }1016 1017 _debuggerBreakpointOptions(breakpoint)1018 {1019 let actions = breakpoint.actions;1020 actions = actions.map((action) => action.toProtocol());1021 actions = actions.filter((action) => {1022 if (action.type !== WI.BreakpointAction.Type.Log)1023 return true;1024 1025 if (!/\$\{.*?\}/.test(action.data))1026 return true;1027 1028 let lexer = new WI.BreakpointLogMessageLexer;1029 let tokens = lexer.tokenize(action.data);1030 if (!tokens)1031 return false;1032 1033 let templateLiteral = tokens.reduce((text, token) => {1034 if (token.type === WI.BreakpointLogMessageLexer.TokenType.PlainText)1035 return text + token.data.escapeCharacters("`\\");1036 if (token.type === WI.BreakpointLogMessageLexer.TokenType.Expression)1037 return text + "${" + token.data + "}";1038 return text;1039 }, "");1040 1041 action.data = "console.log(`" + templateLiteral + "`)";1042 action.type = WI.BreakpointAction.Type.Evaluate;1043 return true;1044 });1045 1046 return {1047 condition: breakpoint.condition,1048 ignoreCount: breakpoint.ignoreCount,1049 autoContinue: breakpoint.autoContinue,1050 actions,1051 };1052 }1053 1054 1052 _setBreakpoint(breakpoint, specificTarget) 1055 1053 { … … 1088 1086 if (!specificTarget) 1089 1087 breakpoint.resolved = false; 1090 1091 // Convert BreakpointAction types to DebuggerAgent protocol types.1092 // NOTE: Breakpoint.options returns new objects each time, so it is safe to modify.1093 let options = this._debuggerBreakpointOptions(breakpoint);1094 for (let action of options.actions)1095 action.type = this._debuggerBreakpointActionType(action.type);1096 1088 1097 1089 if (breakpoint.contentIdentifier) { … … 1103 1095 urlRegex: undefined, 1104 1096 columnNumber: breakpoint.sourceCodeLocation.columnNumber, 1105 options 1097 options: breakpoint.optionsToProtocol(), 1106 1098 }, didSetBreakpoint.bind(this, target)); 1107 1099 } … … 1110 1102 target.DebuggerAgent.setBreakpoint.invoke({ 1111 1103 location: {scriptId: breakpoint.scriptIdentifier, lineNumber: breakpoint.sourceCodeLocation.lineNumber, columnNumber: breakpoint.sourceCodeLocation.columnNumber}, 1112 options 1104 options: breakpoint.optionsToProtocol(), 1113 1105 }, didSetBreakpoint.bind(this, target)); 1114 1106 } else … … 1234 1226 return; 1235 1227 1236 console.assert( this.isBreakpointEditable(breakpoint));1237 if (! this.isBreakpointEditable(breakpoint))1228 console.assert(breakpoint.editable); 1229 if (!breakpoint.editable) 1238 1230 return; 1239 1231 … … 1251 1243 this._breakpointEditablePropertyDidChange(event); 1252 1244 1253 this. _updateProbesForBreakpoint(event.target);1245 this.updateProbesForBreakpoint(event.target); 1254 1246 } 1255 1247 … … 1412 1404 1413 1405 this._ignoreBreakpointDisplayLocationDidChangeEvent = false; 1414 }1415 1416 _addProbesForBreakpoint(breakpoint)1417 {1418 if (this._knownProbeIdentifiersForBreakpoint.has(breakpoint))1419 return;1420 1421 this._knownProbeIdentifiersForBreakpoint.set(breakpoint, new Set);1422 1423 this._updateProbesForBreakpoint(breakpoint);1424 }1425 1426 _removeProbesForBreakpoint(breakpoint)1427 {1428 console.assert(this._knownProbeIdentifiersForBreakpoint.has(breakpoint));1429 1430 this._updateProbesForBreakpoint(breakpoint);1431 this._knownProbeIdentifiersForBreakpoint.delete(breakpoint);1432 }1433 1434 _updateProbesForBreakpoint(breakpoint)1435 {1436 let knownProbeIdentifiers = this._knownProbeIdentifiersForBreakpoint.get(breakpoint);1437 if (!knownProbeIdentifiers) {1438 // Sometimes actions change before the added breakpoint is fully dispatched.1439 this._addProbesForBreakpoint(breakpoint);1440 return;1441 }1442 1443 let seenProbeIdentifiers = new Set;1444 1445 for (let probeAction of breakpoint.probeActions) {1446 let probeIdentifier = probeAction.id;1447 console.assert(probeIdentifier, "Probe added without breakpoint action identifier: ", breakpoint);1448 1449 seenProbeIdentifiers.add(probeIdentifier);1450 if (!knownProbeIdentifiers.has(probeIdentifier)) {1451 // New probe; find or create relevant probe set.1452 knownProbeIdentifiers.add(probeIdentifier);1453 let probeSet = this._probeSetForBreakpoint(breakpoint);1454 let newProbe = new WI.Probe(probeIdentifier, breakpoint, probeAction.data);1455 this._probesByIdentifier.set(probeIdentifier, newProbe);1456 probeSet.addProbe(newProbe);1457 break;1458 }1459 1460 let probe = this._probesByIdentifier.get(probeIdentifier);1461 console.assert(probe, "Probe known but couldn't be found by identifier: ", probeIdentifier);1462 // Update probe expression; if it differed, change events will fire.1463 probe.expression = probeAction.data;1464 }1465 1466 // Look for missing probes based on what we saw last.1467 for (let probeIdentifier of knownProbeIdentifiers) {1468 if (seenProbeIdentifiers.has(probeIdentifier))1469 break;1470 1471 // The probe has gone missing, remove it.1472 let probeSet = this._probeSetForBreakpoint(breakpoint);1473 let probe = this._probesByIdentifier.get(probeIdentifier);1474 this._probesByIdentifier.delete(probeIdentifier);1475 knownProbeIdentifiers.delete(probeIdentifier);1476 probeSet.removeProbe(probe);1477 1478 // Remove the probe set if it has become empty.1479 if (!probeSet.probes.length) {1480 this._probeSetsByBreakpoint.delete(probeSet.breakpoint);1481 probeSet.willRemove();1482 this.dispatchEventToListeners(WI.DebuggerManager.Event.ProbeSetRemoved, {probeSet});1483 }1484 }1485 1406 } 1486 1407 -
trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js
r266072 r266074 955 955 break; 956 956 957 case InspectorBackend.Enum.Timeline.EventType.ProbeSample: 957 case InspectorBackend.Enum.Timeline.EventType.ProbeSample: { 958 let probe = WI.debuggerManager.probeForIdentifier(recordPayload.data.probeId); 959 if (probe.breakpoint instanceof WI.JavaScriptBreakpoint) 960 sourceCodeLocation = probe.breakpoint.sourceCodeLocation; 961 958 962 // Pass the startTime as the endTime since this record type has no duration. 959 sourceCodeLocation = WI.debuggerManager.probeForIdentifier(recordPayload.data.probeId).breakpoint.sourceCodeLocation;960 963 return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ProbeSampleRecorded, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.probeId); 964 } 961 965 962 966 case InspectorBackend.Enum.Timeline.EventType.TimerInstall: -
trunk/Source/WebInspectorUI/UserInterface/Main.html
r261498 r266074 128 128 <link rel="stylesheet" href="Views/InputPopover.css"> 129 129 <link rel="stylesheet" href="Views/IssueTreeElement.css"> 130 <link rel="stylesheet" href="Views/JavaScriptBreakpointTreeElement.css"> 130 131 <link rel="stylesheet" href="Views/LayerDetailsSidebarPanel.css"> 131 132 <link rel="stylesheet" href="Views/LayerTreeDetailsSidebarPanel.css"> … … 350 351 <script src="Protocol/WorkerObserver.js"></script> 351 352 353 <script src="Models/Breakpoint.js"></script> 352 354 <script src="Models/BreakpointAction.js"></script> 353 355 <script src="Models/Collection.js"></script> … … 370 372 <script src="Models/BackForwardEntry.js"></script> 371 373 <script src="Models/BoxShadow.js"></script> 372 <script src="Models/Breakpoint.js"></script>373 374 <script src="Models/CPUInstrument.js"></script> 374 375 <script src="Models/CPUTimeline.js"></script> … … 417 418 <script src="Models/IndexedDatabaseObjectStoreIndex.js"></script> 418 419 <script src="Models/IssueMessage.js"></script> 420 <script src="Models/JavaScriptBreakpoint.js"></script> 419 421 <script src="Models/KeyboardShortcut.js"></script> 420 422 <script src="Models/Layer.js"></script> … … 717 719 <script src="Views/InputPopover.js"></script> 718 720 <script src="Views/IssueTreeElement.js"></script> 721 <script src="Views/JavaScriptBreakpointTreeElement.js"></script> 719 722 <script src="Views/LayerDetailsSidebarPanel.js"></script> 720 723 <script src="Views/LayerTreeDataGridNode.js"></script> -
trunk/Source/WebInspectorUI/UserInterface/Models/Breakpoint.js
r243727 r266074 26 26 WI.Breakpoint = class Breakpoint extends WI.Object 27 27 { 28 constructor(sourceCodeLocation, {contentIdentifier, disabled, condition, ignoreCount, autoContinue} = {}) 29 { 30 console.assert(sourceCodeLocation instanceof WI.SourceCodeLocation); 31 console.assert(!contentIdentifier || typeof contentIdentifier === "string"); 32 console.assert(!disabled || typeof disabled === "boolean"); 33 console.assert(!condition || typeof condition === "string"); 34 console.assert(!ignoreCount || !isNaN(ignoreCount)); 35 console.assert(!autoContinue || typeof autoContinue === "boolean"); 28 constructor({disabled, condition, ignoreCount, autoContinue} = {}) 29 { 30 console.assert(!disabled || typeof disabled === "boolean", disabled); 31 console.assert(!condition || typeof condition === "string", condition); 32 console.assert(!ignoreCount || !isNaN(ignoreCount), ignoreCount); 33 console.assert(!autoContinue || typeof autoContinue === "boolean", autoContinue); 36 34 37 35 super(); 38 36 39 this._id = null; 40 this._sourceCodeLocation = sourceCodeLocation; 41 42 let sourceCode = this._sourceCodeLocation.sourceCode; 43 if (sourceCode) { 44 this._contentIdentifier = sourceCode.contentIdentifier; 45 console.assert(!contentIdentifier || contentIdentifier === this._contentIdentifier, "The content identifier from the source code should match the given value."); 46 } else 47 this._contentIdentifier = contentIdentifier || null; 48 console.assert(this._contentIdentifier || this._isSpecial(), "There should always be a content identifier for a breakpoint."); 49 50 this._scriptIdentifier = sourceCode instanceof WI.Script ? sourceCode.id : null; 51 this._target = sourceCode instanceof WI.Script ? sourceCode.target : null; 37 // This class should not be instantiated directly. Create a concrete subclass instead. 38 console.assert(this.constructor !== WI.Breakpoint && this instanceof WI.Breakpoint); 39 52 40 this._disabled = disabled || false; 53 41 this._condition = condition || ""; … … 55 43 this._autoContinue = autoContinue || false; 56 44 this._actions = []; 57 this._resolved = false;58 59 this._sourceCodeLocation.addEventListener(WI.SourceCodeLocation.Event.LocationChanged, this._sourceCodeLocationLocationChanged, this);60 this._sourceCodeLocation.addEventListener(WI.SourceCodeLocation.Event.DisplayLocationChanged, this._sourceCodeLocationDisplayLocationChanged, this);61 45 } 62 46 63 47 // Import / Export 64 48 65 static fromJSON(json)66 {67 const sourceCode = null;68 let breakpoint = new Breakpoint(new WI.SourceCodeLocation(sourceCode, json.lineNumber || 0, json.columnNumber || 0), {69 // The 'url' fallback is for transitioning from older frontends and should be removed.70 contentIdentifier: json.contentIdentifier || json.url,71 disabled: json.disabled,72 condition: json.condition,73 ignoreCount: json.ignoreCount,74 autoContinue: json.autoContinue,75 });76 breakpoint._actions = json.actions.map((actionJSON) => WI.BreakpointAction.fromJSON(actionJSON, breakpoint));77 return breakpoint;78 }79 80 49 toJSON(key) 81 50 { 82 // The id, scriptIdentifier, target, and resolved state are tied to the current session, so don't include them for serialization.83 let json = {84 contentIdentifier: this._contentIdentifier,85 lineNumber: this._sourceCodeLocation.lineNumber,86 columnNumber: this._sourceCodeLocation.columnNumber,87 disabled: this._disabled,88 condition: this._condition,89 ignoreCount: this._ignoreCount,90 actions: this._actions.map((action) => action.toJSON()),91 autoContinue: this._autoContinue,92 };93 if (key === WI.ObjectStore.toJSONSymbol)94 json[WI.objectStores.breakpoints.keyPath] = this._contentIdentifier + ":" + this._sourceCodeLocation.lineNumber + ":" + this._sourceCodeLocation.columnNumber;51 let json = {}; 52 if (this._disabled) 53 json.disabled = this._disabled; 54 if (this.editable) { 55 if (this._condition) 56 json.condition = this._condition; 57 if (this._ignoreCount) 58 json.ignoreCount = this._ignoreCount; 59 if (this._actions.length) 60 json.actions = this._actions.map((action) => action.toJSON()); 61 if (this._autoContinue) 62 json.autoContinue = this._autoContinue; 63 } 95 64 return json; 96 65 } … … 98 67 // Public 99 68 100 get sourceCodeLocation() { return this._sourceCodeLocation; } 101 get contentIdentifier() { return this._contentIdentifier; } 102 get scriptIdentifier() { return this._scriptIdentifier; } 103 get target() { return this._target; } 104 105 get identifier() 106 { 107 return this._id; 108 } 109 110 set identifier(id) 111 { 112 this._id = id || null; 113 } 114 115 get resolved() 116 { 117 return this._resolved; 118 } 119 120 set resolved(resolved) 121 { 122 if (this._resolved === resolved) 123 return; 124 125 console.assert(!resolved || this._sourceCodeLocation.sourceCode || this._isSpecial(), "Breakpoints must have a SourceCode to be resolved.", this); 126 127 this._resolved = resolved || false; 128 129 this.dispatchEventToListeners(WI.Breakpoint.Event.ResolvedStateDidChange); 69 get special() 70 { 71 // Overridden by subclasses if needed. 72 return false; 73 } 74 75 get removable() 76 { 77 // Overridden by subclasses if needed. 78 return true; 79 } 80 81 get editable() 82 { 83 // Overridden by subclasses if needed. 84 return false; 130 85 } 131 86 … … 152 107 set condition(condition) 153 108 { 109 console.assert(this.editable, this); 110 console.assert(typeof condition === "string"); 111 154 112 if (this._condition === condition) 155 113 return; … … 162 120 get ignoreCount() 163 121 { 122 console.assert(this.editable, this); 123 164 124 return this._ignoreCount; 165 125 } … … 167 127 set ignoreCount(ignoreCount) 168 128 { 129 console.assert(this.editable, this); 130 169 131 console.assert(ignoreCount >= 0, "Ignore count cannot be negative."); 170 132 if (ignoreCount < 0) … … 181 143 get autoContinue() 182 144 { 145 console.assert(this.editable, this); 146 183 147 return this._autoContinue; 184 148 } … … 186 150 set autoContinue(cont) 187 151 { 152 console.assert(this.editable, this); 153 188 154 if (this._autoContinue === cont) 189 155 return; … … 196 162 get actions() 197 163 { 164 console.assert(this.editable, this); 165 198 166 return this._actions; 199 167 } … … 201 169 get probeActions() 202 170 { 171 console.assert(this.editable, this); 172 203 173 return this._actions.filter(function(action) { 204 174 return action.type === WI.BreakpointAction.Type.Probe; … … 209 179 { 210 180 if (this.disabled) { 211 // When cycling, clear auto-continue when going from disabled to enabled. 212 this.autoContinue = false; 181 if (this.editable) { 182 // When cycling, clear auto-continue when going from disabled to enabled. 183 this.autoContinue = false; 184 } 185 213 186 this.disabled = false; 214 187 return; 215 188 } 216 189 217 if (this.autoContinue) { 218 this.disabled = true; 219 return; 220 } 221 222 if (this.actions.length) { 223 this.autoContinue = true; 224 return; 190 if (this.editable) { 191 if (this.autoContinue) { 192 this.disabled = true; 193 return; 194 } 195 196 if (this.actions.length) { 197 this.autoContinue = true; 198 return; 199 } 225 200 } 226 201 … … 228 203 } 229 204 230 createAction(type, precedingAction, data) 231 { 205 createAction(type, {data, precedingAction} = {}) 206 { 207 console.assert(this.editable, this); 208 232 209 var newAction = new WI.BreakpointAction(this, type, data || null); 233 210 … … 250 227 recreateAction(type, actionToReplace) 251 228 { 229 console.assert(this.editable, this); 230 252 231 let index = this._actions.indexOf(actionToReplace); 253 232 console.assert(index !== -1); … … 266 245 removeAction(action) 267 246 { 247 console.assert(this.editable, this); 248 268 249 var index = this._actions.indexOf(action); 269 250 console.assert(index !== -1); … … 281 262 clearActions(type) 282 263 { 264 console.assert(this.editable, this); 265 283 266 if (!type) 284 267 this._actions = []; … … 289 272 } 290 273 291 saveIdentityToCookie(cookie) 292 { 293 cookie["breakpoint-content-identifier"] = this._contentIdentifier; 294 cookie["breakpoint-line-number"] = this._sourceCodeLocation.lineNumber; 295 cookie["breakpoint-column-number"] = this._sourceCodeLocation.columnNumber; 274 remove() 275 { 276 console.assert(this.removable, this); 277 278 // Overridden by subclasses if needed. 279 } 280 281 optionsToProtocol() 282 { 283 console.assert(this.editable, this); 284 285 let payload = {}; 286 287 if (this._condition) 288 payload.condition = this._condition; 289 290 if (this._actions.length) { 291 payload.actions = this._actions.map((action) => action.toProtocol()).filter((action) => { 292 if (action.type !== WI.BreakpointAction.Type.Log) 293 return true; 294 295 if (!/\$\{.*?\}/.test(action.data)) 296 return true; 297 298 let lexer = new WI.BreakpointLogMessageLexer; 299 let tokens = lexer.tokenize(action.data); 300 if (!tokens) 301 return false; 302 303 let templateLiteral = tokens.reduce((text, token) => { 304 if (token.type === WI.BreakpointLogMessageLexer.TokenType.PlainText) 305 return text + token.data.escapeCharacters("`\\"); 306 if (token.type === WI.BreakpointLogMessageLexer.TokenType.Expression) 307 return text + "${" + token.data + "}"; 308 return text; 309 }, ""); 310 311 action.data = "console.log(`" + templateLiteral + "`)"; 312 action.type = WI.BreakpointAction.Type.Evaluate; 313 return true; 314 }); 315 } 316 317 if (this._autoContinue) 318 payload.autoContinue = this._autoContinue; 319 320 if (this._ignoreCount) 321 payload.ignoreCount = this._ignoreCount; 322 323 return !isEmptyObject(payload) ? payload : undefined; 296 324 } 297 325 … … 300 328 breakpointActionDidChange(action) 301 329 { 330 console.assert(this.editable, this); 331 302 332 var index = this._actions.indexOf(action); 303 333 console.assert(index !== -1); … … 307 337 this.dispatchEventToListeners(WI.Breakpoint.Event.ActionsDidChange); 308 338 } 309 310 // Private311 312 _isSpecial()313 {314 return this._sourceCodeLocation.isEqual(new WI.SourceCodeLocation(null, Infinity, Infinity));315 }316 317 _sourceCodeLocationLocationChanged(event)318 {319 this.dispatchEventToListeners(WI.Breakpoint.Event.LocationDidChange, event.data);320 }321 322 _sourceCodeLocationDisplayLocationChanged(event)323 {324 this.dispatchEventToListeners(WI.Breakpoint.Event.DisplayLocationDidChange, event.data);325 }326 339 }; 327 340 … … 330 343 WI.Breakpoint.Event = { 331 344 DisabledStateDidChange: "breakpoint-disabled-state-did-change", 332 ResolvedStateDidChange: "breakpoint-resolved-state-did-change",333 345 ConditionDidChange: "breakpoint-condition-did-change", 334 346 IgnoreCountDidChange: "breakpoint-ignore-count-did-change", 335 347 ActionsDidChange: "breakpoint-actions-did-change", 336 348 AutoContinueDidChange: "breakpoint-auto-continue-did-change", 337 LocationDidChange: "breakpoint-location-did-change",338 DisplayLocationDidChange: "breakpoint-display-location-did-change",339 349 }; -
trunk/Source/WebInspectorUI/UserInterface/Models/BreakpointAction.js
r243727 r266074 28 28 constructor(breakpoint, type, data) 29 29 { 30 console.assert(breakpoint instanceof WI.Breakpoint); 31 console.assert(Object.values(WI.BreakpointAction.Type).includes(type)); 30 console.assert(breakpoint instanceof WI.Breakpoint, breakpoint); 31 console.assert(Object.values(WI.BreakpointAction.Type).includes(type), type); 32 console.assert(!data || typeof data === "string", data); 32 33 33 34 this._breakpoint = breakpoint; -
trunk/Source/WebInspectorUI/UserInterface/Models/DOMBreakpoint.js
r244279 r266074 24 24 */ 25 25 26 WI.DOMBreakpoint = class DOMBreakpoint extends WI. Object26 WI.DOMBreakpoint = class DOMBreakpoint extends WI.Breakpoint 27 27 { 28 28 constructor(domNodeOrInfo, type, {disabled} = {}) … … 31 31 console.assert(Object.values(WI.DOMBreakpoint.Type).includes(type), type); 32 32 33 super( );33 super({disabled}); 34 34 35 35 if (domNodeOrInfo instanceof WI.DOMNode) { … … 45 45 46 46 this._type = type; 47 this._disabled = disabled || false;48 47 } 49 48 50 49 // Static 51 50 52 static deserialize(serializedInfo)51 static fromJSON(json) 53 52 { 54 return new WI.DOMBreakpoint( serializedInfo, serializedInfo.type, {55 disabled: !!serializedInfo.disabled,53 return new WI.DOMBreakpoint(json, json.type, { 54 disabled: json.disabled, 56 55 }); 57 56 } … … 62 61 get url() { return this._url; } 63 62 get path() { return this._path; } 64 65 get disabled()66 {67 return this._disabled;68 }69 70 set disabled(disabled)71 {72 if (this._disabled === disabled)73 return;74 75 this._disabled = disabled;76 77 this.dispatchEventToListeners(WI.DOMBreakpoint.Event.DisabledStateChanged);78 }79 63 80 64 get domNodeIdentifier() … … 97 81 } 98 82 83 remove() 84 { 85 super.remove(); 86 87 WI.domDebuggerManager.removeDOMBreakpoint(this); 88 } 89 99 90 saveIdentityToCookie(cookie) 100 91 { … … 106 97 toJSON(key) 107 98 { 108 let json = { 109 url: this._url, 110 path: this._path, 111 type: this._type, 112 }; 113 if (this._disabled) 114 json.disabled = true; 99 let json = super.toJSON(key); 100 json.url = this._url; 101 json.path = this._path; 102 json.type = this._type; 115 103 if (key === WI.ObjectStore.toJSONSymbol) 116 104 json[WI.objectStores.domBreakpoints.keyPath] = this._url + ":" + this._path + ":" + this._type; … … 127 115 WI.DOMBreakpoint.Event = { 128 116 DOMNodeChanged: "dom-breakpoint-dom-node-changed", 129 DisabledStateChanged: "dom-breakpoint-disabled-state-changed",130 117 }; -
trunk/Source/WebInspectorUI/UserInterface/Models/EventBreakpoint.js
r248201 r266074 24 24 */ 25 25 26 WI.EventBreakpoint = class EventBreakpoint extends WI. Object26 WI.EventBreakpoint = class EventBreakpoint extends WI.Breakpoint 27 27 { 28 constructor(type, {eventName, eventListener, disabled } = {})28 constructor(type, {eventName, eventListener, disabled, actions, condition, ignoreCount, autoContinue} = {}) 29 29 { 30 super(); 30 // COMPATIBILITY (iOS 13): DOMDebugger.EventBreakpointTypes.Timer was removed. 31 if (type === "timer") { 32 switch (eventName) { 33 case "setInterval": 34 type = WI.EventBreakpoint.Type.Interval; 35 break; 36 37 case "setTimeout": 38 type = WI.EventBreakpoint.Type.Timeout; 39 break; 40 } 41 } 31 42 32 43 console.assert(Object.values(WI.EventBreakpoint.Type).includes(type), type); 44 console.assert(!eventName || type === WI.EventBreakpoint.Type.Listener, eventName); 45 console.assert(!eventListener || type === WI.EventBreakpoint.Type.Listener, eventListener); 46 47 super({disabled, condition, actions, ignoreCount, autoContinue}); 33 48 34 49 this._type = type; 35 50 this._eventName = eventName || null; 36 51 this._eventListener = eventListener || null; 37 this._disabled = disabled || false;38 52 } 39 53 40 54 // Static 41 55 42 static deserialize(serializedInfo)56 static fromJSON(json) 43 57 { 44 return new WI.EventBreakpoint(serializedInfo.type, { 45 eventName: serializedInfo.eventName, 46 disabled: !!serializedInfo.disabled, 58 let breakpoint = new WI.EventBreakpoint(json.type, { 59 eventName: json.eventName, 60 disabled: json.disabled, 61 condition: json.condition, 62 ignoreCount: json.ignoreCount, 63 autoContinue: json.autoContinue, 47 64 }); 65 breakpoint._actions = json.actions?.map((actionJSON) => WI.BreakpointAction.fromJSON(actionJSON, breakpoint)) || []; 66 return breakpoint; 48 67 } 49 68 … … 54 73 get eventListener() { return this._eventListener; } 55 74 56 get disabled()75 get special() 57 76 { 58 return this._disabled; 77 switch (this) { 78 case WI.domDebuggerManager.allAnimationFramesBreakpoint: 79 case WI.domDebuggerManager.allIntervalsBreakpoint: 80 case WI.domDebuggerManager.allListenersBreakpoint: 81 case WI.domDebuggerManager.allTimeoutsBreakpoint: 82 return true; 83 } 84 85 return super.special; 59 86 } 60 87 61 set disabled(disabled)88 get editable() 62 89 { 63 if (this._disabled === disabled) 64 return; 90 // COMPATIBILITY (iOS 14): DOM.setBreakpointForEventListener did not have an "options" parameter yet. 91 // COMPATIBILITY (iOS 14): DOMDebugger.setEventBreakpoint did not have an "options" parameter yet. 92 return (this._eventListener ? InspectorBackend.hasCommand("DOM.setBreakpointForEventListener", "options") : InspectorBackend.hasCommand("DOMDebugger.setEventBreakpoint", "options")) || super.editable; 93 } 65 94 66 this._disabled = disabled; 95 remove() 96 { 97 super.remove(); 67 98 68 this.dispatchEventToListeners(WI.EventBreakpoint.Event.DisabledStateChanged); 99 if (this._eventListener) 100 WI.domManager.removeBreakpointForEventListener(this._eventListener); 101 else 102 WI.domDebuggerManager.removeEventBreakpoint(this); 69 103 } 70 104 … … 76 110 if (this._eventListener) 77 111 cookie["event-breakpoint-event-listener"] = this._eventListener.eventListenerId; 78 if (this._disabled)79 cookie["event-breakpoint-disabled"] = this._disabled;80 112 } 81 113 82 114 toJSON(key) 83 115 { 84 let json = { 85 type: this._type, 86 }; 116 let json = super.toJSON(key); 117 json.type = this._type; 87 118 if (this._eventName) 88 119 json.eventName = this._eventName; 89 if (this._disabled)90 json.disabled = true;91 120 if (key === WI.ObjectStore.toJSONSymbol) 92 121 json[WI.objectStores.eventBreakpoints.keyPath] = this._type + (this._eventName ? ":" + this._eventName : ""); … … 100 129 Listener: "listener", 101 130 Timeout: "timeout", 102 103 // COMPATIBILITY (iOS 13): DOMDebugger.EventBreakpointTypes.Timer was removed.104 Timer: "timer",105 131 }; 106 107 WI.EventBreakpoint.Event = {108 DisabledStateChanged: "event-breakpoint-disabled-state-changed",109 }; -
trunk/Source/WebInspectorUI/UserInterface/Models/ProbeSet.js
r220119 r266074 43 43 WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceChanged, this); 44 44 WI.Probe.addEventListener(WI.Probe.Event.SampleAdded, this._sampleCollected, this); 45 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.ResolvedStateDidChange, this._breakpointResolvedStateDidChange, this);45 WI.JavaScriptBreakpoint.addEventListener(WI.JavaScriptBreakpoint.Event.ResolvedStateDidChange, this._breakpointResolvedStateDidChange, this); 46 46 } 47 47 … … 69 69 createProbe(expression) 70 70 { 71 this.breakpoint.createAction(WI.BreakpointAction.Type.Probe, null, expression);71 this.breakpoint.createAction(WI.BreakpointAction.Type.Probe, {data: expression}); 72 72 } 73 73 … … 102 102 WI.Frame.removeEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceChanged, this); 103 103 WI.Probe.removeEventListener(WI.Probe.Event.SampleAdded, this._sampleCollected, this); 104 WI. Breakpoint.removeEventListener(WI.Breakpoint.Event.ResolvedStateDidChange, this._breakpointResolvedStateDidChange, this);104 WI.JavaScriptBreakpoint.removeEventListener(WI.JavaScriptBreakpoint.Event.ResolvedStateDidChange, this._breakpointResolvedStateDidChange, this); 105 105 } 106 106 -
trunk/Source/WebInspectorUI/UserInterface/Models/URLBreakpoint.js
r244279 r266074 24 24 */ 25 25 26 WI.URLBreakpoint = class URLBreakpoint extends WI. Object26 WI.URLBreakpoint = class URLBreakpoint extends WI.Breakpoint 27 27 { 28 28 constructor(type, url, {disabled} = {}) … … 31 31 console.assert(typeof url === "string", url); 32 32 33 super( );33 super({disabled}); 34 34 35 35 this._type = type; 36 36 this._url = url; 37 this._disabled = disabled || false;38 37 } 39 38 40 39 // Static 41 40 42 static deserialize(serializedInfo)41 static fromJSON(json) 43 42 { 44 return new WI.URLBreakpoint( serializedInfo.type, serializedInfo.url, {45 disabled: !!serializedInfo.disabled,43 return new WI.URLBreakpoint(json.type, json.url, { 44 disabled: json.disabled, 46 45 }); 47 46 } … … 52 51 get url() { return this._url; } 53 52 54 get disabled()53 get special() 55 54 { 56 return this ._disabled;55 return this === WI.domDebuggerManager.allRequestsBreakpoint || super.special; 57 56 } 58 57 59 set disabled(disabled)58 remove() 60 59 { 61 if (this._disabled === disabled) 62 return; 60 super.remove(); 63 61 64 this._disabled = disabled; 65 66 this.dispatchEventToListeners(WI.URLBreakpoint.Event.DisabledStateChanged); 62 WI.domDebuggerManager.removeURLBreakpoint(this); 67 63 } 68 64 … … 75 71 toJSON(key) 76 72 { 77 let json = { 78 type: this._type, 79 url: this._url, 80 }; 81 if (this._disabled) 82 json.disabled = true; 73 let json = super.toJSON(key); 74 json.type = this._type; 75 json.url = this._url; 83 76 if (key === WI.ObjectStore.toJSONSymbol) 84 77 json[WI.objectStores.urlBreakpoints.keyPath] = this._type + ":" + this._url; … … 87 80 }; 88 81 89 WI.URLBreakpoint.Event = {90 DisabledStateChanged: "url-breakpoint-disabled-state-changed",91 };92 93 82 WI.URLBreakpoint.Type = { 94 83 Text: "text", -
trunk/Source/WebInspectorUI/UserInterface/Test.html
r259170 r266074 109 109 <script src="Protocol/WorkerObserver.js"></script> 110 110 111 <script src="Models/Breakpoint.js"></script> 111 112 <script src="Models/BreakpointAction.js"></script> 112 113 <script src="Models/Collection.js"></script> … … 127 128 <script src="Models/AnimationCollection.js"></script> 128 129 <script src="Models/BoxShadow.js"></script> 129 <script src="Models/Breakpoint.js"></script>130 130 <script src="Models/CPUInstrument.js"></script> 131 131 <script src="Models/CPUTimeline.js"></script> … … 170 170 <script src="Models/IndexedDatabaseObjectStoreIndex.js"></script> 171 171 <script src="Models/IssueMessage.js"></script> 172 <script src="Models/JavaScriptBreakpoint.js"></script> 172 173 <script src="Models/Layer.js"></script> 173 174 <script src="Models/LayoutInstrument.js"></script> -
trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js
r253402 r266074 116 116 _appendActionButtonClicked(event) 117 117 { 118 var newAction = this._action.breakpoint.createAction(this._action.type, this._action);118 var newAction = this._action.breakpoint.createAction(this._action.type, {precedingAction: this._action}); 119 119 this._delegate.breakpointActionViewAppendActionView(this, newAction); 120 120 } -
trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.css
r258809 r266074 35 35 fill: var(--breakpoint-color); 36 36 stroke: hsla(0, 0%, 10%, 0.3); 37 filter: grayscale();38 }39 40 .item.breakpoint .status > .status-image.resolved {41 filter: none;42 }43 44 body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.breakpoint.selected .status > .status-image.resolved {45 stroke: var(--selected-foreground-color);46 37 } 47 38 … … 60 51 } 61 52 62 .item.breakpoint .subtitle.formatted-location { 63 font-style: italic; 64 } 65 66 .breakpoint-debugger-statement-icon .icon { 67 content: url(../Images/TypeIcons.svg#DebuggerStatement-light); 68 } 69 70 .breakpoint-exception-icon .icon { 71 content: url(../Images/TypeIcons.svg#Exception-light); 72 } 73 74 .breakpoint-assertion-icon .icon { 75 content: url(../Images/TypeIcons.svg#Assertion-light); 76 } 77 78 .breakpoint-microtask-icon .icon { 79 content: url(../Images/TypeIcons.svg#Microtask-light); 80 } 81 82 .breakpoint-paused-icon .icon { 53 .item.breakpoint.paused .icon { 83 54 content: url(../Images/TypeIcons.svg#PausedBreakpoint-light); 84 55 } 85 56 86 /* When animating a layer on top of a tree element's icon, move the main87 icon to the icon element's background so animations are layered on top. */88 .breakpoint-generic-line-icon .icon {89 background-image: url(../Images/TypeIcons.svg#ResultLine-light);90 content: '';91 }92 93 .breakpoint-generic-line-icon .icon > span {94 position: absolute;95 top: 0;96 right: 0;97 bottom: 0;98 left: 0;99 100 border-radius: 50%;101 transform: scale(0);102 transition: none;103 background-color: hsl(216, 30%, 42%);104 }105 106 .data-updated.breakpoint-generic-line-icon .icon > span {107 border-radius: 0;108 transform: scale(0.85);109 transition: all .4s ease-out;110 background-color: hsla(216, 30%, 42%, 0.1);111 }112 113 57 @media (prefers-color-scheme: dark) { 114 .breakpoint-debugger-statement-icon .icon { 115 content: url(../Images/TypeIcons.svg#DebuggerStatement-dark); 116 } 117 118 .breakpoint-exception-icon .icon { 119 content: url(../Images/TypeIcons.svg#Exception-dark); 120 } 121 122 .breakpoint-assertion-icon .icon { 123 content: url(../Images/TypeIcons.svg#Assertion-dark); 124 } 125 126 .breakpoint-microtask-icon .icon { 127 content: url(../Images/TypeIcons.svg#Microtask-dark); 128 } 129 130 .breakpoint-paused-icon .icon { 58 .item.breakpoint.paused .icon { 131 59 content: url(../Images/TypeIcons.svg#PausedBreakpoint-dark); 132 60 } 133 134 .breakpoint-generic-line-icon .icon {135 background-image: url(../Images/TypeIcons.svg#ResultLine-dark);136 }137 138 61 } -
trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.js
r249291 r266074 26 26 WI.BreakpointTreeElement = class BreakpointTreeElement extends WI.GeneralTreeElement 27 27 { 28 constructor(breakpoint, {className ,title} = {})28 constructor(breakpoint, {classNames, title, subtitle} = {}) 29 29 { 30 30 console.assert(breakpoint instanceof WI.Breakpoint); 31 31 32 if (!className) 33 className = WI.BreakpointTreeElement.GenericLineIconStyleClassName; 34 35 const subtitle = null; 36 super(["breakpoint", className], title, subtitle, breakpoint); 32 if (!Array.isArray(classNames)) 33 classNames = []; 34 classNames.push("breakpoint"); 35 36 super(classNames, title, subtitle, breakpoint); 37 38 // This class should not be instantiated directly. Create a concrete subclass instead. 39 console.assert(this.constructor !== WI.BreakpointTreeElement && this instanceof WI.BreakpointTreeElement); 37 40 38 41 this._breakpoint = breakpoint; … … 40 43 41 44 this._listenerSet = new WI.EventListenerSet(this, "BreakpointTreeElement listeners"); 42 if (!title) 43 this._listenerSet.register(breakpoint, WI.Breakpoint.Event.LocationDidChange, this._breakpointLocationDidChange); 44 this._listenerSet.register(breakpoint, WI.Breakpoint.Event.DisabledStateDidChange, this._updateStatus); 45 this._listenerSet.register(breakpoint, WI.Breakpoint.Event.AutoContinueDidChange, this._updateStatus); 46 this._listenerSet.register(breakpoint, WI.Breakpoint.Event.ResolvedStateDidChange, this._updateStatus); 47 this._listenerSet.register(WI.debuggerManager, WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._updateStatus); 45 this._listenerSet.register(breakpoint, WI.Breakpoint.Event.DisabledStateDidChange, this.updateStatus); 46 this._listenerSet.register(breakpoint, WI.Breakpoint.Event.AutoContinueDidChange, this.updateStatus); 47 this._listenerSet.register(WI.debuggerManager, WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this.updateStatus); 48 48 this._listenerSet.register(WI.debuggerManager, WI.DebuggerManager.Event.ProbeSetAdded, this._probeSetAdded); 49 49 this._listenerSet.register(WI.debuggerManager, WI.DebuggerManager.Event.ProbeSetRemoved, this._probeSetRemoved); … … 56 56 57 57 if (!title) 58 this. _updateTitles();59 this. _updateStatus();58 this.updateTitles(); 59 this.updateStatus(); 60 60 61 61 this._iconAnimationLayerElement = document.createElement("span"); … … 69 69 { 70 70 return this._breakpoint; 71 }72 73 get filterableData()74 {75 return {text: [this.breakpoint.contentIdentifier]};76 71 } 77 72 … … 83 78 this.__deletedViaDeleteKeyboardShortcut = true; 84 79 85 if ( WI.debuggerManager.isBreakpointRemovable(this._breakpoint)) {86 WI.debuggerManager.removeBreakpoint(this._breakpoint);80 if (this._breakpoint.removable) { 81 this._breakpoint.remove(); 87 82 return true; 88 83 } … … 135 130 } 136 131 137 // Private 138 139 _updateTitles() 140 { 141 var sourceCodeLocation = this._breakpoint.sourceCodeLocation; 142 143 var displayLineNumber = sourceCodeLocation.displayLineNumber; 144 var displayColumnNumber = sourceCodeLocation.displayColumnNumber; 145 if (displayColumnNumber > 0) 146 this.mainTitle = WI.UIString("Line %d:%d").format(displayLineNumber + 1, displayColumnNumber + 1); // The user visible line and column numbers are 1-based. 147 else 148 this.mainTitle = WI.UIString("Line %d").format(displayLineNumber + 1); // The user visible line number is 1-based. 149 150 if (sourceCodeLocation.hasMappedLocation()) { 151 this.subtitle = sourceCodeLocation.formattedLocationString(); 152 153 if (sourceCodeLocation.hasFormattedLocation()) 154 this.subtitleElement.classList.add(WI.BreakpointTreeElement.FormattedLocationStyleClassName); 155 else 156 this.subtitleElement.classList.remove(WI.BreakpointTreeElement.FormattedLocationStyleClassName); 157 158 this.tooltip = this.mainTitle + " \u2014 " + WI.UIString("originally %s").format(sourceCodeLocation.originalLocationString()); 159 } 160 } 161 162 _updateStatus() 132 // Protected 133 134 get listenerSet() { return this._listenerSet; } 135 136 updateStatus() 163 137 { 164 138 if (!this.status) … … 166 140 167 141 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageDisabledStyleClassName, this._breakpoint.disabled); 168 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageAutoContinueStyleClassName, this._breakpoint.autoContinue); 169 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageResolvedStyleClassName, this._breakpoint.resolved && WI.debuggerManager.breakpointsEnabled); 170 } 142 if (this._breakpoint.editable) 143 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageAutoContinueStyleClassName, this._breakpoint.autoContinue); 144 } 145 146 updateTitles() 147 { 148 // Overridden by subclasses if needed. 149 } 150 151 // Private 171 152 172 153 _addProbeSet(probeSet) … … 231 212 } 232 213 233 _breakpointLocationDidChange(event)234 {235 console.assert(event.target === this._breakpoint);236 237 // The Breakpoint has a new display SourceCode. The sidebar will remove us, and ondetach() will clear listeners.238 if (event.data.oldDisplaySourceCode === this._breakpoint.displaySourceCode)239 return;240 241 this._updateTitles();242 }243 244 214 _statusImageElementMouseDown(event) 245 215 { … … 254 224 }; 255 225 256 WI.BreakpointTreeElement.GenericLineIconStyleClassName = "breakpoint-generic-line-icon";257 226 WI.BreakpointTreeElement.StatusImageElementStyleClassName = "status-image"; 258 WI.BreakpointTreeElement.StatusImageResolvedStyleClassName = "resolved";259 227 WI.BreakpointTreeElement.StatusImageAutoContinueStyleClassName = "auto-continue"; 260 228 WI.BreakpointTreeElement.StatusImageDisabledStyleClassName = "disabled"; 261 WI.BreakpointTreeElement.FormattedLocationStyleClassName = "formatted-location";262 229 WI.BreakpointTreeElement.ProbeDataUpdatedStyleClassName = "data-updated"; 263 230 -
trunk/Source/WebInspectorUI/UserInterface/Views/CallFrameTreeElement.js
r259738 r266074 108 108 } 109 109 110 populateContextMenu(contextMenu, event) 111 { 112 if (this._callFrame.sourceCodeLocation) 113 WI.appendContextMenuItemsForSourceCode(contextMenu, this._callFrame.sourceCodeLocation); 114 115 super.populateContextMenu(contextMenu, event); 116 } 117 110 118 // Private 111 119 -
trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js
r255396 r266074 94 94 } 95 95 96 if (representedObject instanceof WI. Breakpoint || representedObject instanceof WI.IssueMessage) {96 if (representedObject instanceof WI.JavaScriptBreakpoint || representedObject instanceof WI.IssueMessage) { 97 97 if (representedObject.sourceCodeLocation) 98 98 return WI.ContentView.createFromRepresentedObject(representedObject.sourceCodeLocation.displaySourceCode, extraArguments); … … 235 235 return representedObject.mainResource; 236 236 237 if (representedObject instanceof WI. Breakpoint || representedObject instanceof WI.IssueMessage) {237 if (representedObject instanceof WI.JavaScriptBreakpoint || representedObject instanceof WI.IssueMessage) { 238 238 if (representedObject.sourceCodeLocation) 239 239 return representedObject.sourceCodeLocation.displaySourceCode; … … 280 280 if (representedObject instanceof WI.Timeline) 281 281 return true; 282 if (representedObject instanceof WI. Breakpoint || representedObject instanceof WI.IssueMessage)282 if (representedObject instanceof WI.JavaScriptBreakpoint || representedObject instanceof WI.IssueMessage) 283 283 return representedObject.sourceCodeLocation; 284 284 if (representedObject instanceof WI.LocalResourceOverride) -
trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
r264669 r266074 119 119 } else { 120 120 contextMenu.appendItem(WI.UIString("Add Breakpoint"), () => { 121 WI.debuggerManager.addBreakpoint(new WI. Breakpoint(location));121 WI.debuggerManager.addBreakpoint(new WI.JavaScriptBreakpoint(location)); 122 122 }); 123 123 } -
trunk/Source/WebInspectorUI/UserInterface/Views/DOMBreakpointTreeElement.css
r256774 r266074 24 24 */ 25 25 26 . breakpoint.dom.breakpoint-for-subtree-modified:not(.breakpoint-paused-icon) .icon {26 .item.breakpoint.dom.subtree-modified:not(.paused) .icon { 27 27 content: url(../Images/TypeIcons.svg#DOMBreakpointSubtreeModified-light); 28 28 } 29 29 30 . breakpoint.dom.breakpoint-for-attribute-modified:not(.breakpoint-paused-icon) .icon {30 .item.breakpoint.dom.attribute-modified:not(.paused) .icon { 31 31 content: url(../Images/TypeIcons.svg#DOMBreakpointAttributeModified-light); 32 32 } 33 33 34 . breakpoint.dom.breakpoint-for-node-removed:not(.breakpoint-paused-icon) .icon {34 .item.breakpoint.dom.node-removed:not(.paused) .icon { 35 35 content: url(../Images/TypeIcons.svg#DOMBreakpointNodeRemoved-light); 36 36 } 37 37 38 38 @media (prefers-color-scheme: dark) { 39 . breakpoint.dom.breakpoint-for-subtree-modified:not(.breakpoint-paused-icon) .icon {39 .item.breakpoint.dom.subtree-modified:not(.paused) .icon { 40 40 content: url(../Images/TypeIcons.svg#DOMBreakpointSubtreeModified-dark); 41 41 } 42 42 43 . breakpoint.dom.breakpoint-for-attribute-modified:not(.breakpoint-paused-icon) .icon {43 .item.breakpoint.dom.attribute-modified:not(.paused) .icon { 44 44 content: url(../Images/TypeIcons.svg#DOMBreakpointAttributeModified-dark); 45 45 } 46 46 47 . breakpoint.dom.breakpoint-for-node-removed:not(.breakpoint-paused-icon) .icon {47 .item.breakpoint.dom.node-removed:not(.paused) .icon { 48 48 content: url(../Images/TypeIcons.svg#DOMBreakpointNodeRemoved-dark); 49 49 } -
trunk/Source/WebInspectorUI/UserInterface/Views/DOMBreakpointTreeElement.js
r249291 r266074 24 24 */ 25 25 26 WI.DOMBreakpointTreeElement = class DOMBreakpointTreeElement extends WI. GeneralTreeElement26 WI.DOMBreakpointTreeElement = class DOMBreakpointTreeElement extends WI.BreakpointTreeElement 27 27 { 28 constructor(breakpoint, {className , title} = {})28 constructor(breakpoint, {classNames, title} = {}) 29 29 { 30 30 console.assert(breakpoint instanceof WI.DOMBreakpoint); 31 31 32 let classNames = ["breakpoint", "dom", `breakpoint-for-${breakpoint.type}`];33 if (className)34 classNames.push(className);32 if (!Array.isArray(classNames)) 33 classNames = []; 34 classNames.push("dom", breakpoint.type); 35 35 36 36 if (!title) 37 37 title = WI.DOMBreakpointTreeElement.displayNameForType(breakpoint.type); 38 38 39 const subtitle = null; 40 super(classNames, title, subtitle, breakpoint); 41 42 this.status = WI.ImageUtilities.useSVGSymbol("Images/Breakpoint.svg"); 43 this.status.className = WI.BreakpointTreeElement.StatusImageElementStyleClassName; 44 45 this.tooltipHandledSeparately = true; 39 super(breakpoint, {classNames, title}); 46 40 } 47 41 … … 62 56 } 63 57 } 64 65 // Protected66 67 onattach()68 {69 super.onattach();70 71 this.representedObject.addEventListener(WI.DOMBreakpoint.Event.DisabledStateChanged, this._updateStatus, this);72 WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._updateStatus, this);73 74 this._boundStatusImageElementClicked = this._statusImageElementClicked.bind(this);75 this._boundStatusImageElementFocused = this._statusImageElementFocused.bind(this);76 this._boundStatusImageElementMouseDown = this._statusImageElementMouseDown.bind(this);77 78 this.status.addEventListener("click", this._boundStatusImageElementClicked);79 this.status.addEventListener("focus", this._boundStatusImageElementFocused);80 this.status.addEventListener("mousedown", this._boundStatusImageElementMouseDown);81 82 this._updateStatus();83 }84 85 ondetach()86 {87 super.ondetach();88 89 this.representedObject.removeEventListener(null, null, this);90 WI.debuggerManager.removeEventListener(null, null, this);91 92 this.status.removeEventListener("click", this._boundStatusImageElementClicked);93 this.status.removeEventListener("focus", this._boundStatusImageElementFocused);94 this.status.removeEventListener("mousedown", this._boundStatusImageElementMouseDown);95 96 this._boundStatusImageElementClicked = null;97 this._boundStatusImageElementFocused = null;98 this._boundStatusImageElementMouseDown = null;99 }100 101 ondelete()102 {103 // We set this flag so that TreeOutlines that will remove this104 // BreakpointTreeElement will know whether it was deleted from105 // within the TreeOutline or from outside it (e.g. TextEditor).106 this.__deletedViaDeleteKeyboardShortcut = true;107 108 WI.domDebuggerManager.removeDOMBreakpoint(this.representedObject);109 110 return true;111 }112 113 onenter()114 {115 this._toggleBreakpoint();116 return true;117 }118 119 onspace()120 {121 this._toggleBreakpoint();122 return true;123 }124 125 populateContextMenu(contextMenu, event)126 {127 let breakpoint = this.representedObject;128 let label = breakpoint.disabled ? WI.UIString("Enable Breakpoint") : WI.UIString("Disable Breakpoint");129 contextMenu.appendItem(label, this._toggleBreakpoint.bind(this));130 131 contextMenu.appendItem(WI.UIString("Delete Breakpoint"), function() {132 WI.domDebuggerManager.removeDOMBreakpoint(breakpoint);133 });134 }135 136 // Private137 138 _statusImageElementClicked(event)139 {140 this._toggleBreakpoint();141 }142 143 _statusImageElementFocused(event)144 {145 // Prevent tree outline focus.146 event.stopPropagation();147 }148 149 _statusImageElementMouseDown(event)150 {151 // Prevent tree element selection.152 event.stopPropagation();153 }154 155 _toggleBreakpoint()156 {157 this.representedObject.disabled = !this.representedObject.disabled;158 }159 160 _updateStatus()161 {162 if (!this.status)163 return;164 165 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageDisabledStyleClassName, this.representedObject.disabled);166 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageResolvedStyleClassName, WI.debuggerManager.breakpointsEnabled);167 }168 58 }; -
trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeContentView.js
r262302 r266074 96 96 WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, this._domBreakpointAddedOrRemoved, this); 97 97 98 WI.DOMBreakpoint.addEventListener(WI. DOMBreakpoint.Event.DisabledStateChanged, this._handleDOMBreakpointDisabledStateChanged, this);98 WI.DOMBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._handleDOMBreakpointDisabledStateChanged, this); 99 99 WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.DOMNodeChanged, this._handleDOMBreakpointDOMNodeChanged, this); 100 100 -
trunk/Source/WebInspectorUI/UserInterface/Views/EventBreakpointTreeElement.css
r257757 r266074 24 24 */ 25 25 26 . breakpoint.event.breakpoint-for-animation-frame:not(.breakpoint-paused-icon) .icon {26 .item.breakpoint.event.animation-frame:not(.paused) .icon { 27 27 content: url(../Images/TypeIcons.svg#EventBreakpointAnimationFrame-light); 28 28 } 29 29 30 . breakpoint.event.breakpoint-for-interval:not(.breakpoint-paused-icon) .icon {30 .item.breakpoint.event.interval:not(.paused) .icon { 31 31 content: url(../Images/TypeIcons.svg#EventBreakpointInterval-light); 32 32 } 33 33 34 . breakpoint.event.breakpoint-for-listener:not(.breakpoint-paused-icon) .icon {34 .item.breakpoint.event.listener:not(.paused) .icon { 35 35 content: url(../Images/TypeIcons.svg#EventBreakpointListener-light); 36 36 } 37 37 38 . breakpoint.event.breakpoint-for-timeout:not(.breakpoint-paused-icon) .icon {38 .item.breakpoint.event.timeout:not(.paused) .icon { 39 39 content: url(../Images/TypeIcons.svg#EventBreakpointTimeout-light); 40 40 } 41 41 42 42 @media(prefers-color-scheme: dark) { 43 . breakpoint.event.breakpoint-for-animation-frame:not(.breakpoint-paused-icon) .icon {43 .item.breakpoint.event.animation-frame:not(.paused) .icon { 44 44 content: url(../Images/TypeIcons.svg#EventBreakpointAnimationFrame-dark); 45 45 } 46 47 . breakpoint.event.breakpoint-for-interval:not(.breakpoint-paused-icon) .icon {46 47 .item.breakpoint.event.interval:not(.paused) .icon { 48 48 content: url(../Images/TypeIcons.svg#EventBreakpointInterval-dark); 49 49 } 50 51 . breakpoint.event.breakpoint-for-listener:not(.breakpoint-paused-icon) .icon {50 51 .item.breakpoint.event.listener:not(.paused) .icon { 52 52 content: url(../Images/TypeIcons.svg#EventBreakpointListener-dark); 53 53 } 54 55 . breakpoint.event.breakpoint-for-timeout:not(.breakpoint-paused-icon) .icon {54 55 .item.breakpoint.event.timeout:not(.paused) .icon { 56 56 content: url(../Images/TypeIcons.svg#EventBreakpointTimeout-dark); 57 } 57 } 58 58 } -
trunk/Source/WebInspectorUI/UserInterface/Views/EventBreakpointTreeElement.js
r249291 r266074 24 24 */ 25 25 26 WI.EventBreakpointTreeElement = class EventBreakpointTreeElement extends WI. GeneralTreeElement26 WI.EventBreakpointTreeElement = class EventBreakpointTreeElement extends WI.BreakpointTreeElement 27 27 { 28 constructor(breakpoint, {className , title} = {})28 constructor(breakpoint, {classNames, title} = {}) 29 29 { 30 30 console.assert(breakpoint instanceof WI.EventBreakpoint); 31 31 32 let classNames = ["breakpoint", "event", `breakpoint-for-${breakpoint.type}`];33 if (className)34 classNames.push(className);32 if (!Array.isArray(classNames)) 33 classNames = []; 34 classNames.push("event", breakpoint.type); 35 35 36 36 if (!title) 37 37 title = breakpoint.eventName; 38 38 39 const subtitle = null; 40 super(classNames, title, subtitle, breakpoint); 41 42 this.status = WI.ImageUtilities.useSVGSymbol("Images/Breakpoint.svg"); 43 this.status.className = WI.BreakpointTreeElement.StatusImageElementStyleClassName; 44 45 this.tooltipHandledSeparately = true; 46 } 47 48 // Protected 49 50 onattach() 51 { 52 super.onattach(); 53 54 this.representedObject.addEventListener(WI.EventBreakpoint.Event.DisabledStateChanged, this._updateStatus, this); 55 WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._updateStatus, this); 56 57 this._boundStatusImageElementClicked = this._statusImageElementClicked.bind(this); 58 this._boundStatusImageElementFocused = this._statusImageElementFocused.bind(this); 59 this._boundStatusImageElementMouseDown = this._statusImageElementMouseDown.bind(this); 60 61 this.status.addEventListener("click", this._boundStatusImageElementClicked); 62 this.status.addEventListener("focus", this._boundStatusImageElementFocused); 63 this.status.addEventListener("mousedown", this._boundStatusImageElementMouseDown); 64 65 this._updateStatus(); 66 } 67 68 ondetach() 69 { 70 super.ondetach(); 71 72 this.representedObject.removeEventListener(null, null, this); 73 WI.debuggerManager.removeEventListener(null, null, this); 74 75 this.status.removeEventListener("click", this._boundStatusImageElementClicked); 76 this.status.removeEventListener("focus", this._boundStatusImageElementFocused); 77 this.status.removeEventListener("mousedown", this._boundStatusImageElementMouseDown); 78 79 this._boundStatusImageElementClicked = null; 80 this._boundStatusImageElementFocused = null; 81 this._boundStatusImageElementMouseDown = null; 82 } 83 84 ondelete() 85 { 86 // We set this flag so that TreeOutlines that will remove this 87 // BreakpointTreeElement will know whether it was deleted from 88 // within the TreeOutline or from outside it (e.g. TextEditor). 89 this.__deletedViaDeleteKeyboardShortcut = true; 90 91 if (this.representedObject.eventListener) 92 WI.domManager.removeBreakpointForEventListener(this.representedObject.eventListener); 93 else 94 WI.domDebuggerManager.removeEventBreakpoint(this.representedObject); 95 96 return true; 97 } 98 99 onenter() 100 { 101 this._toggleBreakpoint(); 102 return true; 103 } 104 105 onspace() 106 { 107 this._toggleBreakpoint(); 108 return true; 109 } 110 111 populateContextMenu(contextMenu, event) 112 { 113 let breakpoint = this.representedObject; 114 115 let label = breakpoint.disabled ? WI.UIString("Enable Breakpoint") : WI.UIString("Disable Breakpoint"); 116 contextMenu.appendItem(label, this._toggleBreakpoint.bind(this)); 117 118 contextMenu.appendItem(WI.UIString("Delete Breakpoint"), () => { 119 if (breakpoint.eventListener) 120 WI.domManager.removeBreakpointForEventListener(breakpoint.eventListener); 121 else 122 WI.domDebuggerManager.removeEventBreakpoint(breakpoint); 123 }); 124 } 125 126 // Private 127 128 _statusImageElementClicked(event) 129 { 130 this._toggleBreakpoint(); 131 } 132 133 _statusImageElementFocused(event) 134 { 135 // Prevent tree outline focus. 136 event.stopPropagation(); 137 } 138 139 _statusImageElementMouseDown(event) 140 { 141 // Prevent tree element selection. 142 event.stopPropagation(); 143 } 144 145 _toggleBreakpoint() 146 { 147 this.representedObject.disabled = !this.representedObject.disabled; 148 } 149 150 _updateStatus() 151 { 152 if (!this.status) 153 return; 154 155 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageDisabledStyleClassName, this.representedObject.disabled); 156 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageResolvedStyleClassName, WI.debuggerManager.breakpointsEnabled); 39 super(breakpoint, {classNames, title}); 157 40 } 158 41 }; -
trunk/Source/WebInspectorUI/UserInterface/Views/EventListenerSectionGroup.css
r224002 r266074 35 35 margin: 0; 36 36 } 37 38 .event-listener-section > .content input[type="checkbox"] + .go-to-arrow { 39 vertical-align: -2px; 40 } 41 42 .event-listener-section > .content input[type="checkbox"]:not(:checked) + .go-to-arrow { 43 display: none; 44 } -
trunk/Source/WebInspectorUI/UserInterface/Views/EventListenerSectionGroup.js
r248765 r266074 73 73 74 74 if (WI.DOMManager.supportsEventListenerBreakpoints()) { 75 this._eventListenerBreakpointToggleElement = document.createElement("input"); 75 let toggleContainer = document.createElement("span"); 76 77 this._eventListenerBreakpointToggleElement = toggleContainer.appendChild(document.createElement("input")); 76 78 this._eventListenerBreakpointToggleElement.type = "checkbox"; 77 79 this._updateBreakpointToggle(); … … 81 83 }); 82 84 85 if (WI.DOMManager.supportsEventListenerBreakpointConfiguration()) { 86 let revealBreakpointGoToArrow = toggleContainer.appendChild(WI.createGoToArrowButton()); 87 revealBreakpointGoToArrow.title = WI.UIString("Reveal in Sources Tab"); 88 revealBreakpointGoToArrow.addEventListener("click", (event) => { 89 console.assert(this.hasEventListenerBreakpoint); 90 91 let breakpointToSelect = WI.domManager.breakpointForEventListenerId(this._eventListener.eventListenerId); 92 console.assert(breakpointToSelect); 93 94 WI.showSourcesTab({breakpointToSelect}); 95 }); 96 } 97 83 98 let toggleLabel = document.createElement("span"); 84 99 toggleLabel.textContent = WI.UIString("Breakpoint"); … … 87 102 }); 88 103 89 rows.push(new WI.DetailsSectionSimpleRow(toggleLabel, t his._eventListenerBreakpointToggleElement));104 rows.push(new WI.DetailsSectionSimpleRow(toggleLabel, toggleContainer)); 90 105 } 91 106 } -
trunk/Source/WebInspectorUI/UserInterface/Views/JavaScriptBreakpointTreeElement.css
r266073 r266074 24 24 */ 25 25 26 .item.breakpoint .status { 27 position: relative; 28 } 29 30 .item.breakpoint .status > .status-image { 31 width: 23px; 32 height: 12px; 33 margin-top: 2px; 34 35 fill: var(--breakpoint-color); 36 stroke: hsla(0, 0%, 10%, 0.3); 26 .item.breakpoint.javascript .status > .status-image { 37 27 filter: grayscale(); 38 28 } 39 29 40 .item.breakpoint .status > .status-image.resolved {30 .item.breakpoint.javascript .status > .status-image.resolved { 41 31 filter: none; 42 32 } 43 33 44 body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.breakpoint. selected .status > .status-image.resolved {34 body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.breakpoint.javascript.selected .status > .status-image.resolved { 45 35 stroke: var(--selected-foreground-color); 46 36 } 47 37 48 .item.breakpoint .status > .status-image.auto-continue::after { 49 position: absolute; 50 right: 3px; 51 width: 3px; 52 height: 12px; 53 content: ""; 54 -webkit-clip-path: polygon(0 20%, 100% 50%, 0 80%); 55 background-color: var(--selected-foreground-color); 56 } 57 58 .item.breakpoint .status > .status-image.disabled { 59 fill: var(--breakpoint-color-disabled); 60 } 61 62 .item.breakpoint .subtitle.formatted-location { 38 .item.breakpoint.javascript .subtitle.formatted-location { 63 39 font-style: italic; 64 }65 66 .breakpoint-debugger-statement-icon .icon {67 content: url(../Images/TypeIcons.svg#DebuggerStatement-light);68 }69 70 .breakpoint-exception-icon .icon {71 content: url(../Images/TypeIcons.svg#Exception-light);72 }73 74 .breakpoint-assertion-icon .icon {75 content: url(../Images/TypeIcons.svg#Assertion-light);76 }77 78 .breakpoint-microtask-icon .icon {79 content: url(../Images/TypeIcons.svg#Microtask-light);80 }81 82 .breakpoint-paused-icon .icon {83 content: url(../Images/TypeIcons.svg#PausedBreakpoint-light);84 40 } 85 41 86 42 /* When animating a layer on top of a tree element's icon, move the main 87 43 icon to the icon element's background so animations are layered on top. */ 88 . breakpoint-generic-line-icon.icon {44 .item.breakpoint.javascript.line .icon { 89 45 background-image: url(../Images/TypeIcons.svg#ResultLine-light); 90 46 content: ''; 91 47 } 92 48 93 . breakpoint-generic-line-icon.icon > span {49 .item.breakpoint.javascript.line .icon > span { 94 50 position: absolute; 95 51 top: 0; … … 104 60 } 105 61 106 .data-updated. breakpoint-generic-line-icon.icon > span {62 .data-updated.item.breakpoint.javascript.line .icon > span { 107 63 border-radius: 0; 108 64 transform: scale(0.85); … … 111 67 } 112 68 69 .item.breakpoint.javascript.debugger-statement .icon { 70 content: url(../Images/TypeIcons.svg#DebuggerStatement-light); 71 } 72 73 .item.breakpoint.javascript.exception .icon { 74 content: url(../Images/TypeIcons.svg#Exception-light); 75 } 76 77 .item.breakpoint.javascript.assertion .icon { 78 content: url(../Images/TypeIcons.svg#Assertion-light); 79 } 80 81 .item.breakpoint.javascript.microtask .icon { 82 content: url(../Images/TypeIcons.svg#Microtask-light); 83 } 84 113 85 @media (prefers-color-scheme: dark) { 114 .breakpoint-debugger-statement-icon .icon { 86 .item.breakpoint.javascript.line .icon { 87 background-image: url(../Images/TypeIcons.svg#ResultLine-dark); 88 } 89 90 .item.breakpoint.javascript.debugger-statement .icon { 115 91 content: url(../Images/TypeIcons.svg#DebuggerStatement-dark); 116 92 } 117 118 . breakpoint-exception-icon .icon {93 94 .item.breakpoint.javascript.exception .icon { 119 95 content: url(../Images/TypeIcons.svg#Exception-dark); 120 96 } 121 97 122 . breakpoint-assertion-icon .icon {98 .item.breakpoint.javascript.assertion .icon { 123 99 content: url(../Images/TypeIcons.svg#Assertion-dark); 124 100 } 125 101 126 . breakpoint-microtask-icon.icon {102 .item.breakpoint.javascript.microtask .icon { 127 103 content: url(../Images/TypeIcons.svg#Microtask-dark); 128 104 } 129 130 .breakpoint-paused-icon .icon {131 content: url(../Images/TypeIcons.svg#PausedBreakpoint-dark);132 }133 134 .breakpoint-generic-line-icon .icon {135 background-image: url(../Images/TypeIcons.svg#ResultLine-dark);136 }137 138 105 } -
trunk/Source/WebInspectorUI/UserInterface/Views/ProbeDetailsSidebarPanel.js
r236845 r266074 69 69 70 70 inspectedProbeSets.sort(function sortBySourceLocation(aProbeSet, bProbeSet) { 71 if (!(aProbeSet instanceof WI.JavaScriptBreakpoint)) 72 return 1; 73 if (!(bProbeSet instanceof WI.JavaScriptBreakpoint)) 74 return -1; 75 71 76 var aLocation = aProbeSet.breakpoint.sourceCodeLocation; 72 77 var bLocation = bProbeSet.breakpoint.sourceCodeLocation; -
trunk/Source/WebInspectorUI/UserInterface/Views/ProbeSetDetailsSection.js
r262848 r266074 31 31 console.assert(probeSet instanceof WI.ProbeSet, "Invalid ProbeSet argument:", probeSet); 32 32 33 let title = ""; 34 if (probeSet.breakpoint instanceof WI.EventBreakpoint) { 35 if (probeSet.breakpoint === WI.domDebuggerManager.allAnimationFramesBreakpoint) 36 title = WI.UIString("All Animation Frames"); 37 else if (probeSet.breakpoint === WI.domDebuggerManager.allIntervalsBreakpoint) 38 title = WI.UIString("All Intervals"); 39 else if (probeSet.breakpoint === WI.domDebuggerManager.allListenersBreakpoint) 40 title = WI.UIString("All Events"); 41 else if (probeSet.breakpoint === WI.domDebuggerManager.allTimeoutsBreakpoint) 42 title = WI.UIString("All Timeouts"); 43 else 44 title = probeSet.breakpoint.eventName; 45 } 46 33 47 var optionsElement = document.createElement("div"); 34 48 var dataGrid = new WI.ProbeSetDataGrid(probeSet); … … 39 53 var probeSectionGroup = new WI.DetailsSectionGroup([singletonRow]); 40 54 41 super("probe", "", [probeSectionGroup], optionsElement);55 super("probe", title, [probeSectionGroup], optionsElement); 42 56 43 57 this.element.classList.add("probe-set"); … … 66 80 this._listenerSet.register(this._probeSet, WI.ProbeSet.Event.SamplesCleared, this._probeSetSamplesChanged); 67 81 68 // Update the source link when the breakpoint's resolved state changes, 69 // so that it can become a live location link when possible. 70 this._updateLinkElement(); 71 this._listenerSet.register(this._probeSet.breakpoint, WI.Breakpoint.Event.ResolvedStateDidChange, this._updateLinkElement); 82 if (this._probeSet.breakpoint instanceof WI.JavaScriptBreakpoint) { 83 // Update the source link when the breakpoint's resolved state changes, 84 // so that it can become a live location link when possible. 85 this._updateLinkElement(); 86 this._listenerSet.register(this._probeSet.breakpoint, WI.JavaScriptBreakpoint.Event.ResolvedStateDidChange, this._updateLinkElement); 87 } 72 88 73 89 this._listenerSet.install(); -
trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js
r262302 r266074 67 67 68 68 if (this._supportsDebugging) { 69 WI.Breakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._breakpointStatusDidChange, this); 70 WI.Breakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._breakpointStatusDidChange, this); 71 WI.Breakpoint.addEventListener(WI.Breakpoint.Event.ResolvedStateDidChange, this._breakpointStatusDidChange, this); 72 WI.Breakpoint.addEventListener(WI.Breakpoint.Event.LocationDidChange, this._updateBreakpointLocation, this); 69 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._breakpointStatusDidChange, this); 70 WI.JavaScriptBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._breakpointStatusDidChange, this); 71 72 WI.JavaScriptBreakpoint.addEventListener(WI.JavaScriptBreakpoint.Event.ResolvedStateDidChange, this._breakpointStatusDidChange, this); 73 WI.JavaScriptBreakpoint.addEventListener(WI.JavaScriptBreakpoint.Event.LocationDidChange, this._updateBreakpointLocation, this); 73 74 74 75 WI.targetManager.addEventListener(WI.TargetManager.Event.TargetAdded, this._targetAdded, this); … … 168 169 { 169 170 if (this._supportsDebugging) { 170 WI. Breakpoint.removeEventListener(null, null, this);171 WI.JavaScriptBreakpoint.removeEventListener(null, null, this); 171 172 WI.debuggerManager.removeEventListener(null, null, this); 172 173 WI.targetManager.removeEventListener(null, null, this); … … 1306 1307 var unformattedLineInfo = this._unformattedLineInfoForEditorLineInfo(editorLineInfo); 1307 1308 var sourceCodeLocation = this._sourceCode.createSourceCodeLocation(unformattedLineInfo.lineNumber, unformattedLineInfo.columnNumber); 1308 var breakpoint = new WI. Breakpoint(sourceCodeLocation);1309 var breakpoint = new WI.JavaScriptBreakpoint(sourceCodeLocation); 1309 1310 1310 1311 var lineInfo = this._editorLineInfoForSourceCodeLocation(breakpoint.sourceCodeLocation); -
trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js
r266072 r266074 170 170 console.assert(selectedTreeElement.selected); 171 171 172 if (! WI.debuggerManager.isBreakpointRemovable(selectedTreeElement.representedObject)) {172 if (!selectedTreeElement.representedObject.removable) { 173 173 let treeElementToSelect = selectedTreeElement.nextSelectableSibling; 174 174 if (treeElementToSelect) { … … 327 327 WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.WaitingToPause, this._handleDebuggerWaitingToPause, this); 328 328 329 WI. Breakpoint.addEventListener(WI.Breakpoint.Event.DisplayLocationDidChange, this._handleDebuggerObjectDisplayLocationDidChange, this);329 WI.JavaScriptBreakpoint.addEventListener(WI.JavaScriptBreakpoint.Event.DisplayLocationDidChange, this._handleDebuggerObjectDisplayLocationDidChange, this); 330 330 WI.IssueMessage.addEventListener(WI.IssueMessage.Event.DisplayLocationDidChange, this._handleDebuggerObjectDisplayLocationDidChange, this); 331 331 … … 389 389 390 390 if (WI.domDebuggerManager.supported) { 391 if (WI. settings.showAllAnimationFramesBreakpoint.value)392 WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint);393 394 if (WI. settings.showAllTimeoutsBreakpoint.value)395 WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint);396 397 if (WI. settings.showAllIntervalsBreakpoint.value)398 WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint);399 400 if (WI. settings.showAllListenersBreakpoint.value)401 WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allListenersBreakpoint);391 if (WI.domDebuggerManager.allAnimationFramesBreakpoint) 392 this._addBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint); 393 394 if (WI.domDebuggerManager.allTimeoutsBreakpoint) 395 this._addBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint); 396 397 if (WI.domDebuggerManager.allIntervalsBreakpoint) 398 this._addBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint); 399 400 if (WI.domDebuggerManager.allListenersBreakpoint) 401 this._addBreakpoint(WI.domDebuggerManager.allListenersBreakpoint); 402 402 403 403 for (let eventBreakpoint of WI.domDebuggerManager.listenerBreakpoints) … … 454 454 WI.debuggerManager.removeEventListener(null, null, this); 455 455 WI.domDebuggerManager.removeEventListener(null, null, this); 456 WI. Breakpoint.removeEventListener(null, null, this);456 WI.JavaScriptBreakpoint.removeEventListener(null, null, this); 457 457 WI.IssueMessage.removeEventListener(null, null, this); 458 458 WI.DOMBreakpoint.removeEventListener(null, null, this); … … 1203 1203 (treeElement) => treeElement.representedObject === WI.debuggerManager.uncaughtExceptionsBreakpoint, 1204 1204 (treeElement) => treeElement.representedObject === WI.debuggerManager.assertionFailuresBreakpoint, 1205 (treeElement) => treeElement instanceof WI. BreakpointTreeElement || treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement,1205 (treeElement) => treeElement instanceof WI.JavaScriptBreakpointTreeElement || treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement, 1206 1206 (treeElement) => treeElement.representedObject === WI.debuggerManager.allMicrotasksBreakpoint, 1207 1207 (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allAnimationFramesBreakpoint, … … 1226 1226 } 1227 1227 1228 if (a instanceof WI. BreakpointTreeElement && b instanceof WI.BreakpointTreeElement)1229 return this._compare BreakpointTreeElements(a, b);1228 if (a instanceof WI.JavaScriptBreakpointTreeElement && b instanceof WI.JavaScriptBreakpointTreeElement) 1229 return this._compareJavaScriptBreakpointTreeElements(a, b); 1230 1230 1231 1231 return a.mainTitle.extendedLocaleCompare(b.mainTitle) || a.subtitle.extendedLocaleCompare(b.subtitle); … … 1235 1235 } 1236 1236 1237 _compare BreakpointTreeElements(a, b)1237 _compareJavaScriptBreakpointTreeElements(a, b) 1238 1238 { 1239 1239 if (!a.representedObject || !b.representedObject) … … 1253 1253 return null; 1254 1254 1255 let constructor = WI. BreakpointTreeElement;1255 let constructor = WI.JavaScriptBreakpointTreeElement; 1256 1256 let options = {}; 1257 1257 let parentTreeElement = this._breakpointsTreeOutline; … … 1271 1271 1272 1272 if (breakpoint === WI.debuggerManager.debuggerStatementsBreakpoint) { 1273 options.className = "breakpoint-debugger-statement-icon";1273 options.classNames = ["debugger-statement"]; 1274 1274 options.title = WI.UIString("Debugger Statements"); 1275 1275 } else if (breakpoint === WI.debuggerManager.allExceptionsBreakpoint) { 1276 options.className = "breakpoint-exception-icon";1276 options.classNames = ["exception"]; 1277 1277 options.title = WI.repeatedUIString.allExceptions(); 1278 1278 } else if (breakpoint === WI.debuggerManager.uncaughtExceptionsBreakpoint) { 1279 options.className = "breakpoint-exception-icon";1279 options.classNames = ["exception"]; 1280 1280 options.title = WI.repeatedUIString.uncaughtExceptions(); 1281 1281 } else if (breakpoint === WI.debuggerManager.assertionFailuresBreakpoint) { 1282 options.className = "breakpoint-assertion-icon";1282 options.classNames = ["assertion"]; 1283 1283 options.title = WI.repeatedUIString.assertionFailures(); 1284 1284 } else if (breakpoint === WI.debuggerManager.allMicrotasksBreakpoint) { 1285 options.className = "breakpoint-microtask-icon";1285 options.classNames = ["microtask"]; 1286 1286 options.title = WI.UIString("All Microtasks"); 1287 1287 } else if (breakpoint instanceof WI.DOMBreakpoint) { … … 1366 1366 { 1367 1367 for (let breakpoint of breakpoints) { 1368 if ( WI.debuggerManager.isBreakpointRemovable(breakpoint))1368 if (breakpoint.removable) 1369 1369 WI.debuggerManager.removeBreakpoint(breakpoint); 1370 1370 } … … 1385 1385 let breakpoints = []; 1386 1386 for (let child of treeElement.children) { 1387 console.assert(child instanceof WI. BreakpointTreeElement);1387 console.assert(child instanceof WI.JavaScriptBreakpointTreeElement); 1388 1388 let breakpoint = child.breakpoint; 1389 1389 console.assert(breakpoint); … … 1405 1405 issueTreeElement = new WI.IssueTreeElement(issueMessage); 1406 1406 1407 parentTreeElement.insertChild(issueTreeElement, insertionIndexForObjectInListSortedByFunction(issueTreeElement, parentTreeElement.children, this._compare BreakpointTreeElements));1407 parentTreeElement.insertChild(issueTreeElement, insertionIndexForObjectInListSortedByFunction(issueTreeElement, parentTreeElement.children, this._compareJavaScriptBreakpointTreeElements)); 1408 1408 if (parentTreeElement.children.length === 1) 1409 1409 parentTreeElement.expand(); … … 1552 1552 1553 1553 let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allAnimationFramesBreakpoint, { 1554 className : "breakpoint-paused-icon",1554 classNames: ["paused"], 1555 1555 title: WI.UIString("requestAnimationFrame Fired"), 1556 1556 }); … … 1597 1597 1598 1598 let breakpoint = WI.debuggerManager.breakpointForIdentifier(pauseData.breakpointId); 1599 let breakpointTreeElement = new WI. BreakpointTreeElement(breakpoint, {1600 className : "breakpoint-paused-icon",1599 let breakpointTreeElement = new WI.JavaScriptBreakpointTreeElement(breakpoint, { 1600 classNames: ["paused"], 1601 1601 title: WI.UIString("Triggered Breakpoint"), 1602 1602 }); … … 1647 1647 let type = WI.DOMBreakpointTreeElement.displayNameForType(domBreakpoint.type); 1648 1648 let domBreakpointTreeElement = new WI.DOMBreakpointTreeElement(domBreakpoint, { 1649 className : "breakpoint-paused-icon",1649 classNames: ["paused"], 1650 1650 title: type, 1651 1651 }); … … 1717 1717 1718 1718 let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(eventBreakpoint, { 1719 className : "breakpoint-paused-icon",1719 classNames: ["paused"], 1720 1720 title: WI.UIString("\u201C%s\u201D Event Fired").format(pauseData.eventName), 1721 1721 }); … … 1760 1760 1761 1761 let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allIntervalsBreakpoint, { 1762 className : "breakpoint-paused-icon",1762 classNames: ["paused"], 1763 1763 title: WI.UIString("setInterval Fired"), 1764 1764 }); … … 1804 1804 1805 1805 let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(eventBreakpoint, { 1806 className : "breakpoint-paused-icon",1806 classNames: ["paused"], 1807 1807 title: WI.UIString("%s Fired").format(pauseData.eventName), 1808 1808 }); … … 1820 1820 1821 1821 let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allTimeoutsBreakpoint, { 1822 className : "breakpoint-paused-icon",1822 classNames: ["paused"], 1823 1823 title: WI.UIString("setTimeout Fired"), 1824 1824 }); … … 1846 1846 1847 1847 let urlBreakpointTreeElement = new WI.URLBreakpointTreeElement(urlBreakpoint, { 1848 className : "breakpoint-paused-icon",1848 classNames: ["paused"], 1849 1849 title: WI.UIString("Triggered URL Breakpoint"), 1850 1850 }); … … 1952 1952 } 1953 1953 1954 if (treeElement instanceof WI. BreakpointTreeElement) {1954 if (treeElement instanceof WI.JavaScriptBreakpointTreeElement) { 1955 1955 let breakpoint = treeElement.breakpoint; 1956 if ( WI.debuggerManager.isBreakpointSpecial(breakpoint))1956 if (breakpoint.special) 1957 1957 return; 1958 1958 … … 1983 1983 break; 1984 1984 1985 case WI.domDebuggerManager.allAnimationFramesBreakpoint:1986 setting = WI.settings.showAllAnimationFramesBreakpoint;1987 break;1988 1989 case WI.domDebuggerManager.allIntervalsBreakpoint:1990 setting = WI.settings.showAllIntervalsBreakpoint;1991 break;1992 1993 case WI.domDebuggerManager.allListenersBreakpoint:1994 setting = WI.settings.showAllListenersBreakpoint;1995 break;1996 1997 1985 case WI.domDebuggerManager.allRequestsBreakpoint: 1998 1986 setting = WI.settings.showAllRequestsBreakpoint; 1999 1987 break; 2000 2001 case WI.domDebuggerManager.allTimeoutsBreakpoint:2002 setting = WI.settings.showAllTimeoutsBreakpoint;2003 break;2004 1988 } 2005 1989 … … 2010 1994 let selectedTreeElement = this._breakpointsTreeOutline.selectedTreeElement; 2011 1995 if (selectedTreeElement) { 2012 if (selectedTreeElement.representedObject === WI.debuggerManager.assertionFailuresBreakpoint || ! WI.debuggerManager.isBreakpointRemovable(selectedTreeElement.representedObject)) {1996 if (selectedTreeElement.representedObject === WI.debuggerManager.assertionFailuresBreakpoint || !selectedTreeElement.representedObject.removable) { 2013 1997 const skipUnrevealed = true; 2014 1998 const dontPopulate = true; … … 2054 2038 2055 2039 if (WI.DOMDebuggerManager.supportsEventBreakpoints() || WI.DOMDebuggerManager.supportsEventListenerBreakpoints()) { 2056 function addToggleForSpecialEventBreakpoint( breakpoint, label, checked) {2040 function addToggleForSpecialEventBreakpoint(label, breakpoint, type) { 2057 2041 contextMenu.appendCheckboxItem(label, () => { 2058 if ( checked)2042 if (breakpoint) 2059 2043 WI.domDebuggerManager.removeEventBreakpoint(breakpoint); 2060 else { 2061 breakpoint.disabled = false; 2062 WI.domDebuggerManager.addEventBreakpoint(breakpoint); 2063 } 2064 }, checked); 2065 } 2066 2067 addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint, WI.UIString("All Animation Frames"), WI.settings.showAllAnimationFramesBreakpoint.value); 2068 addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint, WI.UIString("All Timeouts"), WI.settings.showAllTimeoutsBreakpoint.value); 2069 addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint, WI.UIString("All Intervals"), WI.settings.showAllIntervalsBreakpoint.value); 2044 else 2045 WI.domDebuggerManager.addEventBreakpoint(new WI.EventBreakpoint(type)); 2046 }, !!breakpoint); 2047 } 2048 2049 addToggleForSpecialEventBreakpoint(WI.UIString("All Animation Frames"), WI.domDebuggerManager.allAnimationFramesBreakpoint, WI.EventBreakpoint.Type.AnimationFrame); 2050 addToggleForSpecialEventBreakpoint(WI.UIString("All Timeouts"), WI.domDebuggerManager.allTimeoutsBreakpoint, WI.EventBreakpoint.Type.Timeout); 2051 addToggleForSpecialEventBreakpoint(WI.UIString("All Intervals"), WI.domDebuggerManager.allIntervalsBreakpoint, WI.EventBreakpoint.Type.Interval); 2070 2052 2071 2053 contextMenu.appendSeparator(); 2072 2054 2073 2055 if (WI.DOMDebuggerManager.supportsAllListenersBreakpoint()) 2074 addToggleForSpecialEventBreakpoint(WI. domDebuggerManager.allListenersBreakpoint, WI.UIString("All Events"), WI.settings.showAllListenersBreakpoint.value);2056 addToggleForSpecialEventBreakpoint(WI.UIString("All Events"), WI.domDebuggerManager.allListenersBreakpoint, WI.EventBreakpoint.Type.Listener); 2075 2057 2076 2058 contextMenu.appendItem(WI.UIString("Event Breakpoint\u2026"), () => { … … 2423 2405 let oldDebuggerTreeElement = null; 2424 2406 let newDebuggerTreeElement = null; 2425 if (debuggerObject instanceof WI. Breakpoint) {2407 if (debuggerObject instanceof WI.JavaScriptBreakpoint) { 2426 2408 oldDebuggerTreeElement = this._breakpointsTreeOutline.findTreeElement(debuggerObject); 2427 2409 if (oldDebuggerTreeElement) -
trunk/Source/WebInspectorUI/UserInterface/Views/TextResourceContentView.js
r253241 r266074 99 99 { 100 100 let objects = WI.debuggerManager.probeSets.filter(function(probeSet) { 101 return this._resource.contentIdentifier === probeSet.breakpoint.contentIdentifier;101 return !(probeSet.breakpoint instanceof WI.JavaScriptBreakpoint) || this._resource.contentIdentifier === probeSet.breakpoint.contentIdentifier; 102 102 }, this); 103 103 … … 320 320 { 321 321 var breakpoint = event.data.probeSet.breakpoint; 322 if ( breakpoint.sourceCodeLocation.sourceCode === this.resource)322 if (!(breakpoint instanceof WI.JavaScriptBreakpoint) || breakpoint.sourceCodeLocation.sourceCode === this.resource) 323 323 this.dispatchEventToListeners(WI.ContentView.Event.SupplementalRepresentedObjectsDidChange); 324 324 } -
trunk/Source/WebInspectorUI/UserInterface/Views/URLBreakpointTreeElement.css
r256774 r266074 24 24 */ 25 25 26 . breakpoint.url .subtitle {26 .item.breakpoint.url .subtitle { 27 27 font-family: Menlo, monospace; 28 28 } 29 29 30 . breakpoint.url:not(.breakpoint-paused-icon) .icon {30 .item.breakpoint.url:not(.paused) .icon { 31 31 content: url(../Images/TypeIcons.svg#URLBreakpoint-light); 32 32 } 33 33 34 34 @media (prefers-color-scheme: dark) { 35 . breakpoint.url:not(.breakpoint-paused-icon) .icon {35 .item.breakpoint.url:not(.paused) .icon { 36 36 content: url(../Images/TypeIcons.svg#URLBreakpoint-dark); 37 37 } -
trunk/Source/WebInspectorUI/UserInterface/Views/URLBreakpointTreeElement.js
r249291 r266074 24 24 */ 25 25 26 WI.URLBreakpointTreeElement = class URLBreakpointTreeElement extends WI. GeneralTreeElement26 WI.URLBreakpointTreeElement = class URLBreakpointTreeElement extends WI.BreakpointTreeElement 27 27 { 28 constructor(breakpoint, {className , title} = {})28 constructor(breakpoint, {classNames, title} = {}) 29 29 { 30 30 console.assert(breakpoint instanceof WI.URLBreakpoint); 31 31 32 let classNames = ["breakpoint", "url"];33 if (className)34 classNames.push(className);32 if (!Array.isArray(classNames)) 33 classNames = []; 34 classNames.push("url"); 35 35 36 36 let subtitle; … … 43 43 } 44 44 45 super(classNames, title, subtitle, breakpoint); 46 47 this.status = WI.ImageUtilities.useSVGSymbol("Images/Breakpoint.svg"); 48 this.status.className = WI.BreakpointTreeElement.StatusImageElementStyleClassName; 49 50 this.tooltipHandledSeparately = true; 51 } 52 53 // Protected 54 55 onattach() 56 { 57 super.onattach(); 58 59 this.representedObject.addEventListener(WI.URLBreakpoint.Event.DisabledStateChanged, this._updateStatus, this); 60 WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._updateStatus, this); 61 62 this._boundStatusImageElementClicked = this._statusImageElementClicked.bind(this); 63 this._boundStatusImageElementFocused = this._statusImageElementFocused.bind(this); 64 this._boundStatusImageElementMouseDown = this._statusImageElementMouseDown.bind(this); 65 66 this.status.addEventListener("click", this._boundStatusImageElementClicked); 67 this.status.addEventListener("focus", this._boundStatusImageElementFocused); 68 this.status.addEventListener("mousedown", this._boundStatusImageElementMouseDown); 69 70 this._updateStatus(); 71 } 72 73 ondetach() 74 { 75 super.ondetach(); 76 77 this.representedObject.removeEventListener(null, null, this); 78 WI.debuggerManager.removeEventListener(null, null, this); 79 80 this.status.removeEventListener("click", this._boundStatusImageElementClicked); 81 this.status.removeEventListener("focus", this._boundStatusImageElementFocused); 82 this.status.removeEventListener("mousedown", this._boundStatusImageElementMouseDown); 83 84 this._boundStatusImageElementClicked = null; 85 this._boundStatusImageElementFocused = null; 86 this._boundStatusImageElementMouseDown = null; 87 } 88 89 ondelete() 90 { 91 // We set this flag so that TreeOutlines that will remove this 92 // BreakpointTreeElement will know whether it was deleted from 93 // within the TreeOutline or from outside it (e.g. TextEditor). 94 this.__deletedViaDeleteKeyboardShortcut = true; 95 96 WI.domDebuggerManager.removeURLBreakpoint(this.representedObject); 97 98 return true; 99 } 100 101 onenter() 102 { 103 this._toggleBreakpoint(); 104 return true; 105 } 106 107 onspace() 108 { 109 this._toggleBreakpoint(); 110 return true; 111 } 112 113 populateContextMenu(contextMenu, event) 114 { 115 let breakpoint = this.representedObject; 116 let label = breakpoint.disabled ? WI.UIString("Enable Breakpoint") : WI.UIString("Disable Breakpoint"); 117 contextMenu.appendItem(label, this._toggleBreakpoint.bind(this)); 118 119 contextMenu.appendItem(WI.UIString("Delete Breakpoint"), () => { 120 WI.domDebuggerManager.removeURLBreakpoint(breakpoint); 121 }); 122 } 123 124 // Private 125 126 _statusImageElementClicked(event) 127 { 128 this._toggleBreakpoint(); 129 } 130 131 _statusImageElementFocused(event) 132 { 133 // Prevent tree outline focus. 134 event.stopPropagation(); 135 } 136 137 _statusImageElementMouseDown(event) 138 { 139 // Prevent tree element selection. 140 event.stopPropagation(); 141 } 142 143 _toggleBreakpoint() 144 { 145 this.representedObject.disabled = !this.representedObject.disabled; 146 } 147 148 _updateStatus() 149 { 150 if (!this.status) 151 return; 152 153 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageDisabledStyleClassName, this.representedObject.disabled); 154 this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageResolvedStyleClassName, WI.debuggerManager.breakpointsEnabled); 45 super(breakpoint, {classNames, title, subtitle}); 155 46 } 156 47 };
Note:
See TracChangeset
for help on using the changeset viewer.