Changeset 236540 in webkit


Ignore:
Timestamp:
Sep 26, 2018 11:24:39 PM (6 years ago)
Author:
Devin Rousso
Message:

Web Inspector: Hide DOM and XHR breakpoint sections when they are empty
https://bugs.webkit.org/show_bug.cgi?id=182406
<rdar://problem/37131512>

Reviewed by Joseph Pecoraro.

Source/WebInspectorUI:

Combine all breakpoint sections (e.g. DOM, XHR, and Event) into the main "Breakpoints"
section, including all the various "+" buttons for creating different types of breakpoints.

Global breakpoints (except "All Exceptions" and "Uncaught Exceptions") are now deletable,
and can be re-added via the "+" button of the "Breakpoints" section. Deletable global
breakpoints (e.g. "Assertion Failures" and "All Requests") are able to remain visible while
disabled, and will only be hidden when the user specifically deletes them.

  • Localizations/en.lproj/localizedStrings.js:
  • UserInterface/Base/Setting.js:
  • UserInterface/Main.html:
  • UserInterface/Controllers/DOMBreakpointTreeController.js: Removed.
  • UserInterface/Controllers/EventBreakpointTreeController.js: Removed.
  • UserInterface/Controllers/XHRBreakpointTreeController.js: Removed.
  • UserInterface/Controllers/DebuggerManager.js:

(WI.DebuggerManager.prototype.get uncaughtExceptionsBreakpoint): Added.
(WI.DebuggerManager.prototype.get assertionFailuresBreakpoint): Added.
(WI.DebuggerManager.prototype.isBreakpointRemovable):
(WI.DebuggerManager.prototype.isBreakpointSpecial): Added.
(WI.DebuggerManager.prototype.isBreakpointEditable):
(WI.DebuggerManager.prototype.addBreakpoint):
(WI.DebuggerManager.prototype.removeBreakpoint):
(WI.DebuggerManager.prototype.initializeTarget):
(WI.DebuggerManager.prototype._breakpointDisabledStateDidChange):
(WI.DebuggerManager.prototype._updateBreakOnExceptionsState):
(WI.DebuggerManager.prototype.get allUncaughtExceptionsBreakpoint): Deleted.
(WI.DebuggerManager.prototype.get assertionsBreakpoint): Deleted.

  • UserInterface/Controllers/DOMDebuggerManager.js:

(WI.DOMDebuggerManager.prototype.isBreakpointSpecial): Added.
(WI.DOMDebuggerManager.prototype.addDOMBreakpoint):
(WI.DOMDebuggerManager.prototype.removeDOMBreakpoint):
(WI.DOMDebuggerManager.prototype.addEventBreakpoint):
(WI.DOMDebuggerManager.prototype.removeEventBreakpoint):
(WI.DOMDebuggerManager.prototype.addXHRBreakpoint):
(WI.DOMDebuggerManager.prototype.removeXHRBreakpoint):
(WI.DOMDebuggerManager.prototype.isBreakpointRemovable): Deleted.
Always fire add/remove events, including for special breakpoints, so that any listeners will
be able to adjust accordingly. Even though special breakpoints don't get stored in the lists
held by each manager, we are still able to enable/disable them, and that should be reported.

  • UserInterface/Views/DebuggerSidebarPanel.js:

(WI.DebuggerSidebarPanel):
(WI.DebuggerSidebarPanel.prototype.closed):
(WI.DebuggerSidebarPanel.prototype.saveStateToCookie):
(WI.DebuggerSidebarPanel.prototype.restoreStateFromCookie.revealAndSelect):
(WI.DebuggerSidebarPanel.prototype.restoreStateFromCookie):
(WI.DebuggerSidebarPanel.prototype.willDismissPopover):
(WI.DebuggerSidebarPanel.prototype._addBreakpoint):
(WI.DebuggerSidebarPanel.prototype._removeBreakpoint): Added.
(WI.DebuggerSidebarPanel.prototype._addTreeElementForSourceCodeToTreeOutline):
(WI.DebuggerSidebarPanel.prototype._mainResourceDidChange):
(WI.DebuggerSidebarPanel.prototype._breakpointRemoved):
(WI.DebuggerSidebarPanel.prototype._removeDebuggerTreeElement):
(WI.DebuggerSidebarPanel.prototype._treeSelectionDidChange):
(WI.DebuggerSidebarPanel.prototype._addTreeElement.comparator): Added.
(WI.DebuggerSidebarPanel.prototype._addTreeElement): Added.
(WI.DebuggerSidebarPanel.prototype._updatePauseReasonSection):
(WI.DebuggerSidebarPanel.prototype._domBreakpointResolvedStateDidChange): Added.
(WI.DebuggerSidebarPanel.prototype._handleBreakpointElementAddedOrRemoved): Added.
(WI.DebuggerSidebarPanel.prototype._handleCreateBreakpointClicked): Added.
(WI.DebuggerSidebarPanel.prototype._compareTopLevelTreeElements.isSpecialBreakpoint): Deleted.
(WI.DebuggerSidebarPanel.prototype._compareTopLevelTreeElements): Deleted.
(WI.DebuggerSidebarPanel.prototype._domBreakpointAddedOrRemoved): Deleted.
(WI.DebuggerSidebarPanel.prototype._eventBreakpointAddedOrRemoved): Deleted.
(WI.DebuggerSidebarPanel.prototype._addEventBreakpointButtonClicked): Deleted.
(WI.DebuggerSidebarPanel.prototype._addXHRBreakpointButtonClicked): Deleted.

  • UserInterface/Views/DebuggerSidebarPanel.css:

(.sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node .titles): Deleted.
(.sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node .icon): Deleted.
(.sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node:not(:hover, .selected) .status .go-to-arrow): Deleted.
(.sidebar > .panel.navigation.debugger .details-section.xhr-breakpoints .item.breakpoint .subtitle): Deleted.
Unify the logic for adding/removing breakpoints of all types.

  • UserInterface/Views/BreakpointTreeElement.js:

(WI.BreakpointTreeElement):
(WI.BreakpointTreeElement.prototype.ondelete):

  • UserInterface/Views/DOMBreakpointTreeElement.js:

(WI.DOMBreakpointTreeElement):
(WI.DOMBreakpointTreeElement.prototype.ondelete):

  • UserInterface/Views/DOMNodeTreeElement.js:

(WI.DOMNodeTreeElement):
(WI.DOMNodeTreeElement.prototype.ondelete):
(WI.DOMNodeTreeElement.prototype.populateContextMenu):

  • UserInterface/Views/EventBreakpointTreeElement.js:

(WI.EventBreakpointTreeElement):
(WI.EventBreakpointTreeElement.prototype.ondelete):
(WI.EventBreakpointTreeElement.prototype.populateContextMenu):

  • UserInterface/Views/XHRBreakpointTreeElement.js:

(WI.XHRBreakpointTreeElement):
(WI.XHRBreakpointTreeElement.prototype.ondelete):
(WI.XHRBreakpointTreeElement.prototype.populateContextMenu):

  • UserInterface/Views/XHRBreakpointTreeElement.css: Added.

(.breakpoint.xhr .subtitle):
Add/remove checks for whether the associated breakpoint can be deleted.

  • UserInterface/Views/DOMNodeTreeElement.css: Added.

(.tree-outline .item.dom-node .titles):
(.tree-outline .item.dom-node .icon):
(.tree-outline .item.dom-node:not(:hover, .selected) .status .go-to-arrow):

  • UserInterface/Views/ContextMenuUtilities.js:

(WI.appendContextMenuItemsForDOMNode):
(WI.appendContextMenuItemsForDOMNodeBreakpoints): Added.

  • UserInterface/Views/DOMTreeElement.js:

(WI.DOMTreeElement.prototype._statusImageContextmenu):

  • UserInterface/Views/XHRBreakpointPopover.js:

(WI.XHRBreakpointPopover):
(WI.XHRBreakpointPopover.prototype.get breakpoint): Added.
(WI.XHRBreakpointPopover.prototype.show):
(WI.XHRBreakpointPopover.prototype.dismiss): Added.
(WI.XHRBreakpointPopover.prototype._createEditor):
(WI.XHRBreakpointPopover.prototype._updateEditor):
(WI.XHRBreakpointPopover.prototype.get result): Deleted.
(WI.XHRBreakpointPopover.prototype.get type): Deleted.
(WI.XHRBreakpointPopover.prototype.get value): Deleted.
Drive-by: remove the erroneous usage of WI.InputPopover.Result.

LayoutTests:

  • inspector/debugger/break-on-uncaught-exception-throw-in-promise.html:
  • inspector/debugger/break-on-uncaught-exception.html:
  • inspector/debugger/breakpoints-disabled-expected.txt:
  • inspector/debugger/breakpoints-disabled.html:
  • inspector/debugger/pause-reason.html:
  • inspector/debugger/setPauseOnAssertions.html:
  • inspector/worker/debugger-pause.html:
Location:
trunk
Files:
3 deleted
24 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r236539 r236540  
     12018-09-26  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Hide DOM and XHR breakpoint sections when they are empty
     4        https://bugs.webkit.org/show_bug.cgi?id=182406
     5        <rdar://problem/37131512>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * inspector/debugger/break-on-uncaught-exception-throw-in-promise.html:
     10        * inspector/debugger/break-on-uncaught-exception.html:
     11        * inspector/debugger/breakpoints-disabled-expected.txt:
     12        * inspector/debugger/breakpoints-disabled.html:
     13        * inspector/debugger/pause-reason.html:
     14        * inspector/debugger/setPauseOnAssertions.html:
     15        * inspector/worker/debugger-pause.html:
     16
    1172018-09-26  Devin Rousso  <drousso@apple.com>
    218
  • trunk/LayoutTests/inspector/debugger/break-on-uncaught-exception-throw-in-promise.html

    r220119 r236540  
    1515    // FIXME: <https://webkit.org/b/147502> Uncaught Exception in promise does not trigger break on uncaught exception breakpoint
    1616
    17     WI.debuggerManager.allUncaughtExceptionsBreakpoint.disabled = false;
     17    WI.debuggerManager.uncaughtExceptionsBreakpoint.disabled = false;
    1818
    1919    let suite = InspectorTest.createAsyncSuite("BreakOnUncaughtException.Promise");
  • trunk/LayoutTests/inspector/debugger/break-on-uncaught-exception.html

    r220119 r236540  
    99function test()
    1010{
    11     WI.debuggerManager.allUncaughtExceptionsBreakpoint.disabled = false;
     11    WI.debuggerManager.uncaughtExceptionsBreakpoint.disabled = false;
    1212
    1313    let suite = InspectorTest.createAsyncSuite("BreakOnUncaughtException");
  • trunk/LayoutTests/inspector/debugger/breakpoints-disabled-expected.txt

    r209311 r236540  
    88
    99== Running test suite: BreakpointsDisabled
    10 -- Running test case: AssertionsBreakpoint
     10-- Running test case: AssertionFailuresBreakpoint
    1111PASS: Should not pause.
    1212
    13 -- Running test case: AllUncaughtExceptionsBreakpoint
     13-- Running test case: UncaughtExceptionsBreakpoint
    1414PASS: Should not pause.
    1515
  • trunk/LayoutTests/inspector/debugger/breakpoints-disabled.html

    r220119 r236540  
    3838    }
    3939
    40     addTestCase("AssertionsBreakpoint", "Should not pause on assertion failure.", "assertFalse()", WI.debuggerManager.assertionsBreakpoint);
    41     addTestCase("AllUncaughtExceptionsBreakpoint", "Should not pause on uncaught exception.", "doThrow()", WI.debuggerManager.allUncaughtExceptionsBreakpoint);
     40    addTestCase("AssertionFailuresBreakpoint", "Should not pause on assertion failure.", "assertFalse()", WI.debuggerManager.assertionFailuresBreakpoint);
     41    addTestCase("UncaughtExceptionsBreakpoint", "Should not pause on uncaught exception.", "doThrow()", WI.debuggerManager.uncaughtExceptionsBreakpoint);
    4242    addTestCase("AllExceptionsBreakpoint", "Should not pause on caught exception.", "testCatch()", WI.debuggerManager.allExceptionsBreakpoint);
    4343
  • trunk/LayoutTests/inspector/debugger/pause-reason.html

    r220119 r236540  
    1111{
    1212    WI.debuggerManager.allExceptionsBreakpoint.disabled = false;
    13     WI.debuggerManager.assertionsBreakpoint.disabled = false;
     13    WI.debuggerManager.assertionFailuresBreakpoint.disabled = false;
    1414
    1515    for (let script of WI.debuggerManager.dataForTarget(WI.mainTarget).scripts) {
  • trunk/LayoutTests/inspector/debugger/setPauseOnAssertions.html

    r220119 r236540  
    2020        description: "Do not pause on assertions when disabled.",
    2121        test(resolve, reject) {
    22             WI.debuggerManager.assertionsBreakpoint.disabled = true;
     22            WI.debuggerManager.assertionFailuresBreakpoint.disabled = true;
    2323
    2424            let listener = WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
     
    3939        description: "Pause on assertions when enabled.",
    4040        test(resolve, reject) {
    41             WI.debuggerManager.assertionsBreakpoint.disabled = false;
     41            WI.debuggerManager.assertionFailuresBreakpoint.disabled = false;
    4242
    4343            let didPause = false;
  • trunk/LayoutTests/inspector/worker/debugger-pause.html

    r234945 r236540  
    3636    }
    3737
    38     WI.debuggerManager.allUncaughtExceptionsBreakpoint.disabled = false;
    39     WI.debuggerManager.assertionsBreakpoint.disabled = false;
     38    WI.debuggerManager.uncaughtExceptionsBreakpoint.disabled = false;
     39    WI.debuggerManager.assertionFailuresBreakpoint.disabled = false;
    4040
    4141
  • trunk/Source/WebInspectorUI/ChangeLog

    r236539 r236540  
     12018-09-26  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Hide DOM and XHR breakpoint sections when they are empty
     4        https://bugs.webkit.org/show_bug.cgi?id=182406
     5        <rdar://problem/37131512>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        Combine all breakpoint sections (e.g. DOM, XHR, and Event) into the main "Breakpoints"
     10        section, including all the various "+" buttons for creating different types of breakpoints.
     11
     12        Global breakpoints (except "All Exceptions" and "Uncaught Exceptions") are now deletable,
     13        and can be re-added via the "+" button of the "Breakpoints" section. Deletable global
     14        breakpoints (e.g. "Assertion Failures" and "All Requests") are able to remain visible while
     15        disabled, and will only be hidden when the user specifically deletes them.
     16
     17        * Localizations/en.lproj/localizedStrings.js:
     18        * UserInterface/Base/Setting.js:
     19        * UserInterface/Main.html:
     20
     21        * UserInterface/Controllers/DOMBreakpointTreeController.js: Removed.
     22        * UserInterface/Controllers/EventBreakpointTreeController.js: Removed.
     23        * UserInterface/Controllers/XHRBreakpointTreeController.js: Removed.
     24
     25        * UserInterface/Controllers/DebuggerManager.js:
     26        (WI.DebuggerManager.prototype.get uncaughtExceptionsBreakpoint): Added.
     27        (WI.DebuggerManager.prototype.get assertionFailuresBreakpoint): Added.
     28        (WI.DebuggerManager.prototype.isBreakpointRemovable):
     29        (WI.DebuggerManager.prototype.isBreakpointSpecial): Added.
     30        (WI.DebuggerManager.prototype.isBreakpointEditable):
     31        (WI.DebuggerManager.prototype.addBreakpoint):
     32        (WI.DebuggerManager.prototype.removeBreakpoint):
     33        (WI.DebuggerManager.prototype.initializeTarget):
     34        (WI.DebuggerManager.prototype._breakpointDisabledStateDidChange):
     35        (WI.DebuggerManager.prototype._updateBreakOnExceptionsState):
     36        (WI.DebuggerManager.prototype.get allUncaughtExceptionsBreakpoint): Deleted.
     37        (WI.DebuggerManager.prototype.get assertionsBreakpoint): Deleted.
     38        * UserInterface/Controllers/DOMDebuggerManager.js:
     39        (WI.DOMDebuggerManager.prototype.isBreakpointSpecial): Added.
     40        (WI.DOMDebuggerManager.prototype.addDOMBreakpoint):
     41        (WI.DOMDebuggerManager.prototype.removeDOMBreakpoint):
     42        (WI.DOMDebuggerManager.prototype.addEventBreakpoint):
     43        (WI.DOMDebuggerManager.prototype.removeEventBreakpoint):
     44        (WI.DOMDebuggerManager.prototype.addXHRBreakpoint):
     45        (WI.DOMDebuggerManager.prototype.removeXHRBreakpoint):
     46        (WI.DOMDebuggerManager.prototype.isBreakpointRemovable): Deleted.
     47        Always fire add/remove events, including for special breakpoints, so that any listeners will
     48        be able to adjust accordingly. Even though special breakpoints don't get stored in the lists
     49        held by each manager, we are still able to enable/disable them, and that should be reported.
     50
     51        * UserInterface/Views/DebuggerSidebarPanel.js:
     52        (WI.DebuggerSidebarPanel):
     53        (WI.DebuggerSidebarPanel.prototype.closed):
     54        (WI.DebuggerSidebarPanel.prototype.saveStateToCookie):
     55        (WI.DebuggerSidebarPanel.prototype.restoreStateFromCookie.revealAndSelect):
     56        (WI.DebuggerSidebarPanel.prototype.restoreStateFromCookie):
     57        (WI.DebuggerSidebarPanel.prototype.willDismissPopover):
     58        (WI.DebuggerSidebarPanel.prototype._addBreakpoint):
     59        (WI.DebuggerSidebarPanel.prototype._removeBreakpoint): Added.
     60        (WI.DebuggerSidebarPanel.prototype._addTreeElementForSourceCodeToTreeOutline):
     61        (WI.DebuggerSidebarPanel.prototype._mainResourceDidChange):
     62        (WI.DebuggerSidebarPanel.prototype._breakpointRemoved):
     63        (WI.DebuggerSidebarPanel.prototype._removeDebuggerTreeElement):
     64        (WI.DebuggerSidebarPanel.prototype._treeSelectionDidChange):
     65        (WI.DebuggerSidebarPanel.prototype._addTreeElement.comparator): Added.
     66        (WI.DebuggerSidebarPanel.prototype._addTreeElement): Added.
     67        (WI.DebuggerSidebarPanel.prototype._updatePauseReasonSection):
     68        (WI.DebuggerSidebarPanel.prototype._domBreakpointResolvedStateDidChange): Added.
     69        (WI.DebuggerSidebarPanel.prototype._handleBreakpointElementAddedOrRemoved): Added.
     70        (WI.DebuggerSidebarPanel.prototype._handleCreateBreakpointClicked): Added.
     71        (WI.DebuggerSidebarPanel.prototype._compareTopLevelTreeElements.isSpecialBreakpoint): Deleted.
     72        (WI.DebuggerSidebarPanel.prototype._compareTopLevelTreeElements): Deleted.
     73        (WI.DebuggerSidebarPanel.prototype._domBreakpointAddedOrRemoved): Deleted.
     74        (WI.DebuggerSidebarPanel.prototype._eventBreakpointAddedOrRemoved): Deleted.
     75        (WI.DebuggerSidebarPanel.prototype._addEventBreakpointButtonClicked): Deleted.
     76        (WI.DebuggerSidebarPanel.prototype._addXHRBreakpointButtonClicked): Deleted.
     77        * UserInterface/Views/DebuggerSidebarPanel.css:
     78        (.sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node .titles): Deleted.
     79        (.sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node .icon): Deleted.
     80        (.sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node:not(:hover, .selected) .status .go-to-arrow): Deleted.
     81        (.sidebar > .panel.navigation.debugger .details-section.xhr-breakpoints .item.breakpoint .subtitle): Deleted.
     82        Unify the logic for adding/removing breakpoints of all types.
     83
     84        * UserInterface/Views/BreakpointTreeElement.js:
     85        (WI.BreakpointTreeElement):
     86        (WI.BreakpointTreeElement.prototype.ondelete):
     87        * UserInterface/Views/DOMBreakpointTreeElement.js:
     88        (WI.DOMBreakpointTreeElement):
     89        (WI.DOMBreakpointTreeElement.prototype.ondelete):
     90        * UserInterface/Views/DOMNodeTreeElement.js:
     91        (WI.DOMNodeTreeElement):
     92        (WI.DOMNodeTreeElement.prototype.ondelete):
     93        (WI.DOMNodeTreeElement.prototype.populateContextMenu):
     94        * UserInterface/Views/EventBreakpointTreeElement.js:
     95        (WI.EventBreakpointTreeElement):
     96        (WI.EventBreakpointTreeElement.prototype.ondelete):
     97        (WI.EventBreakpointTreeElement.prototype.populateContextMenu):
     98        * UserInterface/Views/XHRBreakpointTreeElement.js:
     99        (WI.XHRBreakpointTreeElement):
     100        (WI.XHRBreakpointTreeElement.prototype.ondelete):
     101        (WI.XHRBreakpointTreeElement.prototype.populateContextMenu):
     102        * UserInterface/Views/XHRBreakpointTreeElement.css: Added.
     103        (.breakpoint.xhr .subtitle):
     104        Add/remove checks for whether the associated breakpoint can be deleted.
     105
     106        * UserInterface/Views/DOMNodeTreeElement.css: Added.
     107        (.tree-outline .item.dom-node .titles):
     108        (.tree-outline .item.dom-node .icon):
     109        (.tree-outline .item.dom-node:not(:hover, .selected) .status .go-to-arrow):
     110
     111        * UserInterface/Views/ContextMenuUtilities.js:
     112        (WI.appendContextMenuItemsForDOMNode):
     113        (WI.appendContextMenuItemsForDOMNodeBreakpoints): Added.
     114        * UserInterface/Views/DOMTreeElement.js:
     115        (WI.DOMTreeElement.prototype._statusImageContextmenu):
     116
     117        * UserInterface/Views/XHRBreakpointPopover.js:
     118        (WI.XHRBreakpointPopover):
     119        (WI.XHRBreakpointPopover.prototype.get breakpoint): Added.
     120        (WI.XHRBreakpointPopover.prototype.show):
     121        (WI.XHRBreakpointPopover.prototype.dismiss): Added.
     122        (WI.XHRBreakpointPopover.prototype._createEditor):
     123        (WI.XHRBreakpointPopover.prototype._updateEditor):
     124        (WI.XHRBreakpointPopover.prototype.get result): Deleted.
     125        (WI.XHRBreakpointPopover.prototype.get type): Deleted.
     126        (WI.XHRBreakpointPopover.prototype.get value): Deleted.
     127        Drive-by: remove the erroneous usage of `WI.InputPopover.Result`.
     128
    11292018-09-26  Devin Rousso  <drousso@apple.com>
    2130
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r236539 r236540  
    7070localizedStrings["Add Action"] = "Add Action";
    7171localizedStrings["Add Breakpoint"] = "Add Breakpoint";
    72 localizedStrings["Add Event Breakpoint"] = "Add Event Breakpoint";
    7372localizedStrings["Add New"] = "Add New";
    7473localizedStrings["Add New Class"] = "Add New Class";
    7574localizedStrings["Add New Probe Expression"] = "Add New Probe Expression";
    7675localizedStrings["Add New Watch Expression"] = "Add New Watch Expression";
    77 localizedStrings["Add XHR Breakpoint"] = "Add XHR Breakpoint";
    7876localizedStrings["Add a Class"] = "Add a Class";
    7977localizedStrings["Add new breakpoint action after this action"] = "Add new breakpoint action after this action";
     
    237235localizedStrings["Could not fetch properties. Object may no longer exist."] = "Could not fetch properties. Object may no longer exist.";
    238236localizedStrings["Count"] = "Count";
     237localizedStrings["Create Breakpoint"] = "Create Breakpoint";
    239238localizedStrings["Create a new tab"] = "Create a new tab";
    240239localizedStrings["Current"] = "Current";
    241240localizedStrings["Custom"] = "Custom";
    242241localizedStrings["DNS"] = "DNS";
    243 localizedStrings["DOM Breakpoints"] = "DOM Breakpoints";
    244242localizedStrings["DOM Content Loaded \u2014 %s"] = "DOM Content Loaded \u2014 %s";
    245243localizedStrings["DOM Event"] = "DOM Event";
     
    348346localizedStrings["Evaluate JavaScript"] = "Evaluate JavaScript";
    349347localizedStrings["Event"] = "Event";
    350 localizedStrings["Event Breakpoints"] = "Event Breakpoints";
     348localizedStrings["Event Breakpoint\u2026"] = "Event Breakpoint\u2026";
    351349localizedStrings["Event Dispatched"] = "Event Dispatched";
    352350localizedStrings["Event Listeners"] = "Event Listeners";
     
    549547localizedStrings["No Attributes"] = "No Attributes";
    550548localizedStrings["No Box Model Information"] = "No Box Model Information";
    551 localizedStrings["No Breakpoints"] = "No Breakpoints";
    552549localizedStrings["No Canvas Contexts"] = "No Canvas Contexts";
    553550localizedStrings["No Canvas Selected"] = "No Canvas Selected";
     
    924921localizedStrings["Wrap lines to editor width"] = "Wrap lines to editor width";
    925922localizedStrings["XHR"] = "XHR";
    926 localizedStrings["XHR Breakpoints"] = "XHR Breakpoints";
     923localizedStrings["XHR Breakpoint\u2026"] = "XHR Breakpoint\u2026";
    927924localizedStrings["XHRs"] = "XHRs";
    928925localizedStrings["XPath"] = "XPath";
  • trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js

    r236539 r236540  
    118118    selectedNetworkDetailContentViewIdentifier: new WI.Setting("network-detail-content-view-identifier", "preview"),
    119119    showRulers: new WI.Setting("show-rulers", false),
     120    showAssertionFailuresBreakpoint: new WI.Setting("show-assertion-failures-breakpoint", true),
     121    showAllRequestsBreakpoint: new WI.Setting("show-all-requests-breakpoint", true),
    120122
    121123    // Experimental
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMDebuggerManager.js

    r235248 r236540  
    121121    get xhrBreakpoints() { return this._xhrBreakpoints; }
    122122
    123     isBreakpointRemovable(breakpoint)
    124     {
    125         return breakpoint !== this._allRequestsBreakpoint;
     123    isBreakpointSpecial(breakpoint)
     124    {
     125        return breakpoint === this._allRequestsBreakpoint;
    126126    }
    127127
     
    146146        if (!breakpoint || !breakpoint.url)
    147147            return;
     148
     149        if (this.isBreakpointSpecial(breakpoint)) {
     150            this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.DOMBreakpointAdded, {breakpoint});
     151            return;
     152        }
    148153
    149154        let breakpoints = this._domBreakpointURLMap.get(breakpoint.url);
     
    168173            return;
    169174
     175        if (this.isBreakpointSpecial(breakpoint)) {
     176            breakpoint.disabled = true;
     177            this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, {breakpoint});
     178            return;
     179        }
     180
    170181        let nodeIdentifier = breakpoint.domNodeIdentifier;
    171182        console.assert(nodeIdentifier, "Cannot remove unresolved DOM breakpoint.");
     
    212223            return;
    213224
     225        if (this.isBreakpointSpecial(breakpoint)) {
     226            this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointAdded, {breakpoint});
     227            return;
     228        }
     229
    214230        if (this.eventBreakpointForTypeAndEventName(breakpoint.type, breakpoint.eventName))
    215231            return;
     
    228244        if (!breakpoint)
    229245            return;
     246
     247        if (this.isBreakpointSpecial(breakpoint)) {
     248            breakpoint.disabled = true;
     249            this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointRemoved, {breakpoint});
     250            return;
     251        }
    230252
    231253        if (!this._eventBreakpoints.includes(breakpoint))
     
    266288            return;
    267289
     290        if (this.isBreakpointSpecial(breakpoint)) {
     291            this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.XHRBreakpointAdded, {breakpoint});
     292            return;
     293        }
     294
    268295        console.assert(!this._xhrBreakpoints.includes(breakpoint), "Already added XHR breakpoint.", breakpoint);
    269296        if (this._xhrBreakpoints.includes(breakpoint))
     
    286313        if (!breakpoint)
    287314            return;
     315
     316        if (this.isBreakpointSpecial(breakpoint)) {
     317            breakpoint.disabled = true;
     318            this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.XHRBreakpointRemoved, {breakpoint});
     319            return;
     320        }
    288321
    289322        if (!this._xhrBreakpoints.includes(breakpoint))
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js

    r235248 r236540  
    5151        this._breakpointsEnabledSetting = new WI.Setting("breakpoints-enabled", true);
    5252        this._allExceptionsBreakpointEnabledSetting = new WI.Setting("break-on-all-exceptions", false);
    53         this._allUncaughtExceptionsBreakpointEnabledSetting = new WI.Setting("break-on-all-uncaught-exceptions", false);
    54         this._assertionsBreakpointEnabledSetting = new WI.Setting("break-on-assertions", false);
     53        this._uncaughtExceptionsBreakpointEnabledSetting = new WI.Setting("break-on-uncaught-exceptions", false);
     54        this._assertionFailuresBreakpointEnabledSetting = new WI.Setting("break-on-assertion-failures", false);
    5555        this._asyncStackTraceDepthSetting = new WI.Setting("async-stack-trace-depth", 200);
    5656
     
    6060        this._allExceptionsBreakpoint.resolved = true;
    6161
    62         this._allUncaughtExceptionsBreakpoint = new WI.Breakpoint(specialBreakpointLocation, !this._allUncaughtExceptionsBreakpointEnabledSetting.value);
    63 
    64         this._assertionsBreakpoint = new WI.Breakpoint(specialBreakpointLocation, !this._assertionsBreakpointEnabledSetting.value);
    65         this._assertionsBreakpoint.resolved = true;
     62        this._uncaughtExceptionsBreakpoint = new WI.Breakpoint(specialBreakpointLocation, !this._uncaughtExceptionsBreakpointEnabledSetting.value);
     63
     64        this._assertionFailuresBreakpoint = new WI.Breakpoint(specialBreakpointLocation, !this._assertionFailuresBreakpointEnabledSetting.value);
     65        this._assertionFailuresBreakpoint.resolved = true;
    6666
    6767        this._breakpoints = [];
     
    9494        // COMPATIBILITY (iOS 10): DebuggerAgent.setPauseOnAssertions did not exist yet.
    9595        if (DebuggerAgent.setPauseOnAssertions)
    96             DebuggerAgent.setPauseOnAssertions(this._assertionsBreakpointEnabledSetting.value);
     96            DebuggerAgent.setPauseOnAssertions(this._assertionFailuresBreakpointEnabledSetting.value);
    9797
    9898        // COMPATIBILITY (iOS 10): Debugger.setAsyncStackTraceDepth did not exist yet.
     
    160160    }
    161161
    162     get allExceptionsBreakpoint()
    163     {
    164         return this._allExceptionsBreakpoint;
    165     }
    166 
    167     get allUncaughtExceptionsBreakpoint()
    168     {
    169         return this._allUncaughtExceptionsBreakpoint;
    170     }
    171 
    172     get assertionsBreakpoint()
    173     {
    174         return this._assertionsBreakpoint;
    175     }
    176 
    177     get breakpoints()
    178     {
    179         return this._breakpoints;
    180     }
     162    get allExceptionsBreakpoint() { return this._allExceptionsBreakpoint; }
     163    get uncaughtExceptionsBreakpoint() { return this._uncaughtExceptionsBreakpoint; }
     164    get assertionFailuresBreakpoint() { return this._assertionFailuresBreakpoint; }
     165    get breakpoints() { return this._breakpoints; }
    181166
    182167    breakpointForIdentifier(id)
     
    228213    {
    229214        return breakpoint !== this._allExceptionsBreakpoint
    230             && breakpoint !== this._allUncaughtExceptionsBreakpoint
    231             && breakpoint !== this._assertionsBreakpoint;
     215            && breakpoint !== this._uncaughtExceptionsBreakpoint;
     216    }
     217
     218    isBreakpointSpecial(breakpoint)
     219    {
     220        return !this.isBreakpointRemovable(breakpoint)
     221            || breakpoint === this._assertionFailuresBreakpoint;
    232222    }
    233223
    234224    isBreakpointEditable(breakpoint)
    235225    {
    236         return this.isBreakpointRemovable(breakpoint);
     226        return !this.isBreakpointSpecial(breakpoint);
    237227    }
    238228
     
    438428            return;
    439429
     430        if (this.isBreakpointSpecial(breakpoint)) {
     431            this.dispatchEventToListeners(WI.DebuggerManager.Event.BreakpointAdded, {breakpoint});
     432            return;
     433        }
     434
    440435        if (breakpoint.contentIdentifier) {
    441436            let contentIdentifierBreakpoints = this._breakpointContentIdentifierMap.get(breakpoint.contentIdentifier);
     
    481476            return;
    482477
     478        if (this.isBreakpointSpecial(breakpoint)) {
     479            breakpoint.disabled = true;
     480            this.dispatchEventToListeners(WI.DebuggerManager.Event.BreakpointRemoved, {breakpoint});
     481            return;
     482        }
     483
    483484        this._breakpoints.remove(breakpoint);
    484485
     
    526527        DebuggerAgent.enable();
    527528        DebuggerAgent.setBreakpointsActive(this._breakpointsEnabledSetting.value);
    528         DebuggerAgent.setPauseOnAssertions(this._assertionsBreakpointEnabledSetting.value);
     529        DebuggerAgent.setPauseOnAssertions(this._assertionFailuresBreakpointEnabledSetting.value);
    529530        DebuggerAgent.setPauseOnExceptions(this._breakOnExceptionsState);
    530531        DebuggerAgent.setAsyncStackTraceDepth(this._asyncStackTraceDepthSetting.value);
     
    10351036        }
    10361037
    1037         if (breakpoint === this._allUncaughtExceptionsBreakpoint) {
     1038        if (breakpoint === this._uncaughtExceptionsBreakpoint) {
    10381039            if (!breakpoint.disabled && !this.breakpointsDisabledTemporarily)
    10391040                this.breakpointsEnabled = true;
    1040             this._allUncaughtExceptionsBreakpointEnabledSetting.value = !breakpoint.disabled;
     1041            this._uncaughtExceptionsBreakpointEnabledSetting.value = !breakpoint.disabled;
    10411042            this._updateBreakOnExceptionsState();
    10421043            for (let target of WI.targets)
     
    10451046        }
    10461047
    1047         if (breakpoint === this._assertionsBreakpoint) {
     1048        if (breakpoint === this._assertionFailuresBreakpoint) {
    10481049            if (!breakpoint.disabled && !this.breakpointsDisabledTemporarily)
    10491050                this.breakpointsEnabled = true;
    1050             this._assertionsBreakpointEnabledSetting.value = !breakpoint.disabled;
     1051            this._assertionFailuresBreakpointEnabledSetting.value = !breakpoint.disabled;
    10511052            for (let target of WI.targets)
    1052                 target.DebuggerAgent.setPauseOnAssertions(this._assertionsBreakpointEnabledSetting.value);
     1053                target.DebuggerAgent.setPauseOnAssertions(this._assertionFailuresBreakpointEnabledSetting.value);
    10531054            return;
    10541055        }
     
    11701171            if (!this._allExceptionsBreakpoint.disabled)
    11711172                state = "all";
    1172             else if (!this._allUncaughtExceptionsBreakpoint.disabled)
     1173            else if (!this._uncaughtExceptionsBreakpoint.disabled)
    11731174                state = "uncaught";
    11741175        }
     
    11801181            // Mark the uncaught breakpoint as unresolved since "all" includes "uncaught".
    11811182            // That way it is clear in the user interface that the breakpoint is ignored.
    1182             this._allUncaughtExceptionsBreakpoint.resolved = false;
     1183            this._uncaughtExceptionsBreakpoint.resolved = false;
    11831184            break;
    11841185        case "uncaught":
    11851186        case "none":
    11861187            // Mark the uncaught breakpoint as resolved again.
    1187             this._allUncaughtExceptionsBreakpoint.resolved = true;
     1188            this._uncaughtExceptionsBreakpoint.resolved = true;
    11881189            break;
    11891190        }
  • trunk/Source/WebInspectorUI/UserInterface/Main.html

    r236342 r236540  
    6868    <link rel="stylesheet" href="Views/CookieStorageContentView.css">
    6969    <link rel="stylesheet" href="Views/DOMNodeDetailsSidebarPanel.css">
     70    <link rel="stylesheet" href="Views/DOMNodeTreeElement.css">
    7071    <link rel="stylesheet" href="Views/DOMStorageContentView.css">
    7172    <link rel="stylesheet" href="Views/DOMTreeContentView.css">
     
    216217    <link rel="stylesheet" href="Views/WebSocketContentView.css">
    217218    <link rel="stylesheet" href="Views/XHRBreakpointPopover.css">
     219    <link rel="stylesheet" href="Views/XHRBreakpointTreeElement.css">
    218220
    219221    <link rel="stylesheet" href="Controllers/CodeMirrorCompletionController.css">
     
    795797    <script src="Controllers/DashboardManager.js"></script>
    796798    <script src="Controllers/DebuggerManager.js"></script>
    797     <script src="Controllers/DOMBreakpointTreeController.js"></script>
    798799    <script src="Controllers/DragToAdjustController.js"></script>
    799     <script src="Controllers/EventBreakpointTreeController.js"></script>
    800800    <script src="Controllers/Formatter.js"></script>
    801801    <script src="Controllers/FormatterSourceMap.js"></script>
     
    818818    <script src="Controllers/TypeTokenAnnotator.js"></script>
    819819    <script src="Controllers/WorkerManager.js"></script>
    820     <script src="Controllers/XHRBreakpointTreeController.js"></script>
    821820
    822821    <script src="Workers/Formatter/FormatterContentBuilder.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointTreeElement.js

    r229543 r236540  
    2626WI.BreakpointTreeElement = class BreakpointTreeElement extends WI.GeneralTreeElement
    2727{
    28     constructor(breakpoint, className, title)
     28    constructor(breakpoint, {className, title} = {})
    2929    {
    3030        console.assert(breakpoint instanceof WI.Breakpoint);
     
    8181    {
    8282        if (!WI.debuggerManager.isBreakpointRemovable(this._breakpoint))
    83             return false;
     83            return true;
    8484
    8585        // We set this flag so that TreeOutlines that will remove this
  • trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js

    r236342 r236540  
    186186        contextMenu.appendSeparator();
    187187
    188         const allowEditing = false;
    189         WI.DOMBreakpointTreeController.appendBreakpointContextMenuItems(contextMenu, domNode, allowEditing);
     188        WI.appendContextMenuItemsForDOMNodeBreakpoints(contextMenu, domNode);
    190189    }
    191190
     
    256255    contextMenu.appendSeparator();
    257256};
     257
     258WI.appendContextMenuItemsForDOMNodeBreakpoints = function(contextMenu, domNode, {allowEditing} = {})
     259{
     260    if (contextMenu.__domBreakpointItemsAdded)
     261        return;
     262
     263    contextMenu.__domBreakpointItemsAdded = true;
     264
     265    let subMenu = contextMenu.appendSubMenuItem(WI.UIString("Break on…"));
     266
     267    let breakpoints = WI.domDebuggerManager.domBreakpointsForNode(domNode);
     268    let keyValuePairs = breakpoints.map((breakpoint) => [breakpoint.type, breakpoint]);
     269    let breakpointsByType = new Map(keyValuePairs);
     270
     271    for (let type of Object.values(WI.DOMBreakpoint.Type)) {
     272        let label = WI.DOMBreakpointTreeElement.displayNameForType(type);
     273        let breakpoint = breakpointsByType.get(type);
     274
     275        subMenu.appendCheckboxItem(label, function() {
     276            if (breakpoint)
     277                WI.domDebuggerManager.removeDOMBreakpoint(breakpoint);
     278            else
     279                WI.domDebuggerManager.addDOMBreakpoint(new WI.DOMBreakpoint(domNode, type));
     280        }, !!breakpoint, false);
     281    }
     282
     283    if (allowEditing) {
     284        contextMenu.appendSeparator();
     285
     286        let shouldEnable = breakpoints.some((breakpoint) => breakpoint.disabled);
     287        let label = shouldEnable ? WI.UIString("Enable Breakpoints") : WI.UIString("Disable Breakpoints");
     288        contextMenu.appendItem(label, () => {
     289            breakpoints.forEach((breakpoint) => breakpoint.disabled = !shouldEnable);
     290        });
     291
     292        contextMenu.appendItem(WI.UIString("Delete Breakpoints"), function() {
     293            WI.domDebuggerManager.removeDOMBreakpointsForNode(domNode);
     294        });
     295    }
     296};
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMBreakpointTreeElement.js

    r229543 r236540  
    2626WI.DOMBreakpointTreeElement = class DOMBreakpointTreeElement extends WI.GeneralTreeElement
    2727{
    28     constructor(breakpoint, className, title)
     28    constructor(breakpoint, {className, title} = {})
    2929    {
    3030        console.assert(breakpoint instanceof WI.DOMBreakpoint);
     
    3636            title = WI.DOMBreakpointTreeElement.displayNameForType(breakpoint.type);
    3737
    38         super(["breakpoint", className], title, null, breakpoint);
     38        const subtitle = null;
     39        super(["breakpoint", "dom", className], title, subtitle, breakpoint);
    3940
    4041        this._statusImageElement = document.createElement("img");
     
    9596    ondelete()
    9697    {
     98        // We set this flag so that TreeOutlines that will remove this
     99        // BreakpointTreeElement will know whether it was deleted from
     100        // within the TreeOutline or from outside it (e.g. TextEditor).
     101        this.__deletedViaDeleteKeyboardShortcut = true;
     102
    97103        WI.domDebuggerManager.removeDOMBreakpoint(this.representedObject);
    98104        return true;
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeTreeElement.css

    r236539 r236540  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WI.DOMNodeTreeElement = class DOMNodeTreeElement extends WI.GeneralTreeElement
    27 {
    28     constructor(domNode)
    29     {
    30         console.assert(domNode instanceof WI.DOMNode);
     26.tree-outline .item.dom-node .titles {
     27    top: 3px;
     28    font-family: Menlo, monospace;
     29}
    3130
    32         const subtitle = null;
    33         super("dom-node", domNode.displayName, subtitle, domNode, {hasChildren: true});
     31.tree-outline .item.dom-node .icon {
     32    content: url(../Images/DOMElement.svg);
     33}
    3434
    35         this.status = WI.linkifyNodeReferenceElement(domNode, WI.createGoToArrowButton());
    36         this.tooltipHandledSeparately = true;
    37     }
    38 
    39     // Protected
    40 
    41     ondelete()
    42     {
    43         WI.domDebuggerManager.removeDOMBreakpointsForNode(this.representedObject);
    44         return true;
    45     }
    46 
    47     populateContextMenu(contextMenu, event)
    48     {
    49         contextMenu.appendSeparator();
    50 
    51         const allowEditing = true;
    52         WI.DOMBreakpointTreeController.appendBreakpointContextMenuItems(contextMenu, this.representedObject, allowEditing);
    53 
    54         contextMenu.appendSeparator();
    55 
    56         contextMenu.appendItem(WI.UIString("Reveal in DOM Tree"), () => {
    57             WI.domTreeManager.inspectElement(this.representedObject.id);
    58         });
    59     }
    60 };
     35.tree-outline .item.dom-node:not(:hover, .selected) .status .go-to-arrow {
     36    display: none;
     37}
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeTreeElement.js

    r229543 r236540  
    4141    ondelete()
    4242    {
     43        // We set this flag so that TreeOutlines that will remove this
     44        // BreakpointTreeElement will know whether it was deleted from
     45        // within the TreeOutline or from outside it (e.g. TextEditor).
     46        this.__deletedViaDeleteKeyboardShortcut = true;
     47
    4348        WI.domDebuggerManager.removeDOMBreakpointsForNode(this.representedObject);
     49
     50        for (let treeElement of this.children) {
     51            if (treeElement instanceof WI.EventBreakpointTreeElement)
     52                treeElement.ondelete();
     53        }
     54
    4455        return true;
    4556    }
     
    4960        contextMenu.appendSeparator();
    5061
    51         const allowEditing = true;
    52         WI.DOMBreakpointTreeController.appendBreakpointContextMenuItems(contextMenu, this.representedObject, allowEditing);
     62        WI.appendContextMenuItemsForDOMNodeBreakpoints(contextMenu, this.representedObject, {
     63            allowEditing: true,
     64        });
    5365
    5466        contextMenu.appendSeparator();
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js

    r229744 r236540  
    18411841        let contextMenu = WI.ContextMenu.createFromEvent(event);
    18421842        if (hasBreakpoint) {
    1843             const allowEditing = true;
    1844             WI.DOMBreakpointTreeController.appendBreakpointContextMenuItems(contextMenu, this.representedObject, allowEditing);
     1843            WI.appendContextMenuItemsForDOMNodeBreakpoints(contextMenu, this.representedObject, {
     1844                allowEditing: true,
     1845            });
    18451846            return;
    18461847        }
  • trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.css

    r234464 r236540  
    108108}
    109109
    110 .sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node .titles {
    111     top: 3px;
    112     font-family: Menlo, monospace;
    113 }
    114 
    115 .sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node .icon {
    116     content: url(../Images/DOMElement.svg);
    117 }
    118 
    119 .sidebar > .panel.navigation.debugger .details-section.dom-breakpoints .item.dom-node:not(:hover, .selected) .status .go-to-arrow {
    120     display: none;
    121 }
    122 
    123 .sidebar > .panel.navigation.debugger .details-section.xhr-breakpoints .item.breakpoint .subtitle {
    124     font-family: Menlo, monospace;
    125 }
    126 
    127110@media (prefers-dark-interface) {
    128111    .sidebar > .panel.navigation.debugger .warning-banner {
  • trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js

    r235248 r236540  
    3434        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._resourceAdded, this);
    3535
     36        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointAdded, this._breakpointAdded, this);
     37        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointAdded, this._breakpointAdded, this);
     38        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.EventBreakpointAdded, this._breakpointAdded, this);
     39        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.XHRBreakpointAdded, this._breakpointAdded, this);
     40
     41        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointRemoved, this._breakpointRemoved, this);
     42        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, this._breakpointRemoved, this);
     43        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.EventBreakpointRemoved, this._breakpointRemoved, this);
     44        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.XHRBreakpointRemoved, this._breakpointRemoved, this);
     45
    3646        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._breakpointsEnabledDidChange, this);
    37         WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointAdded, this._breakpointAdded, this);
    38         WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointRemoved, this._breakpointRemoved, this);
    3947        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, this._scriptAdded, this);
    4048        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptRemoved, this._scriptRemoved, this);
     
    4654        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.WaitingToPause, this._debuggerWaitingToPause, this);
    4755
     56        WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.ResolvedStateDidChange, this._domBreakpointResolvedStateDidChange, this);
     57
    4858        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingWillStart, this._timelineCapturingWillStart, this);
    4959        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStopped, this._timelineCapturingStopped, this);
     
    108118        // Add this offset-sections class name so the sticky headers don't overlap the navigation bar.
    109119        this.element.classList.add(WI.DebuggerSidebarPanel.OffsetSectionsStyleClassName);
    110 
    111         this._allExceptionsBreakpointTreeElement = new WI.BreakpointTreeElement(WI.debuggerManager.allExceptionsBreakpoint, WI.DebuggerSidebarPanel.ExceptionIconStyleClassName, WI.UIString("All Exceptions"));
    112         this._allUncaughtExceptionsBreakpointTreeElement = new WI.BreakpointTreeElement(WI.debuggerManager.allUncaughtExceptionsBreakpoint, WI.DebuggerSidebarPanel.ExceptionIconStyleClassName, WI.UIString("Uncaught Exceptions"));
    113         this._assertionsBreakpointTreeElement = new WI.BreakpointTreeElement(WI.debuggerManager.assertionsBreakpoint, WI.DebuggerSidebarPanel.AssertionIconStyleClassName, WI.UIString("Assertion Failures"));
    114 
    115         this.suppressFilteringOnTreeElements([this._allExceptionsBreakpointTreeElement, this._allUncaughtExceptionsBreakpointTreeElement, this._assertionsBreakpointTreeElement]);
    116120
    117121        function showResourcesWithIssuesOnlyFilterFunction(treeElement)
     
    142146        breakpointsRow.element.appendChild(this._breakpointsContentTreeOutline.element);
    143147
     148        let breakpointNavigationBarWrapper = document.createElement("div");
     149
     150        let breakpointNavigationBar = new WI.NavigationBar;
     151        breakpointNavigationBarWrapper.appendChild(breakpointNavigationBar.element);
     152
     153        let createBreakpointButton = new WI.ButtonNavigationItem("create-breakpoint", WI.UIString("Create Breakpoint"), "Images/Plus13.svg", 13, 13);
     154        createBreakpointButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCreateBreakpointClicked, this);
     155        breakpointNavigationBar.addNavigationItem(createBreakpointButton);
     156
    144157        let breakpointsGroup = new WI.DetailsSectionGroup([breakpointsRow]);
    145         let breakpointsSection = new WI.DetailsSection("breakpoints", WI.UIString("Breakpoints"), [breakpointsGroup]);
     158        let breakpointsSection = new WI.DetailsSection("breakpoints", WI.UIString("Breakpoints"), [breakpointsGroup], breakpointNavigationBarWrapper);
    146159        this.contentView.element.appendChild(breakpointsSection.element);
    147160
     161        this._breakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementAdded, this._handleBreakpointElementAddedOrRemoved, this);
     162        this._breakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementRemoved, this._handleBreakpointElementAddedOrRemoved, this);
    148163        this._breakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
    149164        this._breakpointsContentTreeOutline.ondelete = this._breakpointTreeOutlineDeleteTreeElement.bind(this);
     
    154169        }.bind(this);
    155170
    156         this._breakpointsContentTreeOutline.appendChild(this._allExceptionsBreakpointTreeElement);
    157         this._breakpointsContentTreeOutline.appendChild(this._allUncaughtExceptionsBreakpointTreeElement);
    158 
    159         // COMPATIBILITY (iOS 10): DebuggerAgent.setPauseOnAssertions did not exist yet.
    160         if (DebuggerAgent.setPauseOnAssertions)
    161             this._breakpointsContentTreeOutline.appendChild(this._assertionsBreakpointTreeElement);
    162 
    163         if (WI.domDebuggerManager.supported) {
    164             this._domBreakpointsContentTreeOutline = this.createContentTreeOutline(true);
    165             this._domBreakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementAdded, this._domBreakpointAddedOrRemoved, this);
    166             this._domBreakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementRemoved, this._domBreakpointAddedOrRemoved, this);
    167             this._domBreakpointTreeController = new WI.DOMBreakpointTreeController(this._domBreakpointsContentTreeOutline);
    168 
    169             this._domBreakpointsRow = new WI.DetailsSectionRow(WI.UIString("No Breakpoints"));
    170             this._domBreakpointsRow.element.appendChild(this._domBreakpointsContentTreeOutline.element);
    171             this._domBreakpointsRow.showEmptyMessage();
    172 
    173             const defaultCollapsed = true;
    174 
    175             let domBreakpointsGroup = new WI.DetailsSectionGroup([this._domBreakpointsRow]);
    176             this._domBreakpointsSection = new WI.DetailsSection("dom-breakpoints", WI.UIString("DOM Breakpoints"), [domBreakpointsGroup], null, defaultCollapsed);
    177             this.contentView.element.appendChild(this._domBreakpointsSection.element);
    178 
    179             this._eventBreakpointsContentTreeOutline = this.createContentTreeOutline(true);
    180             this._eventBreakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementAdded, this._eventBreakpointAddedOrRemoved, this);
    181             this._eventBreakpointsContentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementRemoved, this._eventBreakpointAddedOrRemoved, this);
    182 
    183             this._eventBreakpointsRow = new WI.DetailsSectionRow(WI.UIString("No Breakpoints"));
    184             this._eventBreakpointsRow.element.appendChild(this._eventBreakpointsContentTreeOutline.element);
    185             this._eventBreakpointsRow.showEmptyMessage();
    186 
    187             let eventBreakpointNavigationBar = new WI.NavigationBar;
    188             let eventBreakpointNavigationBarWrapper = document.createElement("div");
    189             eventBreakpointNavigationBarWrapper.appendChild(eventBreakpointNavigationBar.element);
    190 
    191             let addEventBreakpointButton = new WI.ButtonNavigationItem("add-event-breakpoint", WI.UIString("Add Event Breakpoint"), "Images/Plus13.svg", 13, 13);
    192             addEventBreakpointButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._addEventBreakpointButtonClicked, this);
    193             eventBreakpointNavigationBar.addNavigationItem(addEventBreakpointButton);
    194 
    195             let eventBreakpointsGroup = new WI.DetailsSectionGroup([this._eventBreakpointsRow]);
    196             this._eventBreakpointsSection = new WI.DetailsSection("event-breakpoints", WI.UIString("Event Breakpoints"), [eventBreakpointsGroup], eventBreakpointNavigationBarWrapper, defaultCollapsed);
    197             this.contentView.element.appendChild(this._eventBreakpointsSection.element);
    198 
    199             this._eventBreakpointTreeController = new WI.EventBreakpointTreeController(this._eventBreakpointsContentTreeOutline);
    200 
    201             this._xhrBreakpointsContentTreeOutline = this.createContentTreeOutline(true);
    202             this._xhrBreakpointTreeController = new WI.XHRBreakpointTreeController(this._xhrBreakpointsContentTreeOutline);
    203 
    204             this._xhrBreakpointsRow = new WI.DetailsSectionRow;
    205             this._xhrBreakpointsRow.element.appendChild(this._xhrBreakpointsContentTreeOutline.element);
    206 
    207             let xhrBreakpointNavigationBar = new WI.NavigationBar;
    208             let xhrBreakpointNavigationBarWrapper = document.createElement("div");
    209             xhrBreakpointNavigationBarWrapper.appendChild(xhrBreakpointNavigationBar.element);
    210 
    211             let addXHRBreakpointButton = new WI.ButtonNavigationItem("add-xhr-breakpoint", WI.UIString("Add XHR Breakpoint"), "Images/Plus13.svg", 13, 13);
    212             addXHRBreakpointButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._addXHRBreakpointButtonClicked, this);
    213             xhrBreakpointNavigationBar.addNavigationItem(addXHRBreakpointButton);
    214 
    215             let xhrBreakpointsGroup = new WI.DetailsSectionGroup([this._xhrBreakpointsRow]);
    216             let xhrBreakpointsSection = new WI.DetailsSection("xhr-breakpoints", WI.UIString("XHR Breakpoints"), [xhrBreakpointsGroup], xhrBreakpointNavigationBarWrapper, defaultCollapsed);
    217             this.contentView.element.appendChild(xhrBreakpointsSection.element);
    218         }
    219 
    220171        this._scriptsContentTreeOutline = this.createContentTreeOutline();
    221172        this._scriptsContentTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
     
    260211        WI.issueManager.addEventListener(WI.IssueManager.Event.Cleared, this._handleIssuesCleared, this);
    261212
     213        WI.debuggerManager.addBreakpoint(WI.debuggerManager.allExceptionsBreakpoint);
     214        WI.debuggerManager.addBreakpoint(WI.debuggerManager.uncaughtExceptionsBreakpoint);
     215
     216        // COMPATIBILITY (iOS 10): DebuggerAgent.setPauseOnAssertions did not exist yet.
     217        if (DebuggerAgent.setPauseOnAssertions && WI.settings.showAssertionFailuresBreakpoint.value)
     218            WI.debuggerManager.addBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
     219
    262220        if (WI.frameResourceManager.mainFrame)
    263221            this._addResourcesRecursivelyForFrame(WI.frameResourceManager.mainFrame);
     
    266224            this._addScript(script);
    267225
     226        if (WI.domDebuggerManager.supported) {
     227            if (WI.settings.showAllRequestsBreakpoint.value)
     228                WI.domDebuggerManager.addXHRBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);
     229
     230            for (let eventBreakpoint of WI.domDebuggerManager.eventBreakpoints)
     231                this._addBreakpoint(eventBreakpoint);
     232
     233            for (let domBreakpoint of WI.domDebuggerManager.domBreakpoints)
     234                this._addBreakpoint(domBreakpoint);
     235
     236            for (let eventListenerBreakpoint of WI.domTreeManager.eventListenerBreakpoints)
     237                this._addBreakpoint(eventListenerBreakpoint);
     238
     239            for (let xhrBreakpoints of WI.domDebuggerManager.xhrBreakpoints)
     240                this._addBreakpoint(xhrBreakpoints);
     241        }
     242
    268243        if (WI.debuggerManager.paused)
    269244            this._debuggerDidPause(null);
     
    286261        super.closed();
    287262
    288         if (this._domBreakpointTreeController) {
    289             this._domBreakpointTreeController.disconnect();
    290             this._domBreakpointTreeController = null;
    291         }
    292 
    293263        WI.Frame.removeEventListener(null, null, this);
     264        WI.Target.removeEventListener(null, null, this);
    294265        WI.debuggerManager.removeEventListener(null, null, this);
     266        WI.domDebuggerManager.removeEventListener(null, null, this);
     267        WI.DOMBreakpoint.removeEventListener(null, null, this);
     268        WI.timelineManager.removeEventListener(null, null, this);
     269        WI.targetManager.removeEventListener(null, null, this);
    295270        WI.Breakpoint.removeEventListener(null, null, this);
    296271        WI.IssueMessage.removeEventListener(null, null, this);
     
    367342        }
    368343
    369         if (representedObject === WI.debuggerManager.allUncaughtExceptionsBreakpoint) {
    370             cookie[WI.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey] = true;
    371             return;
    372         }
    373 
    374         if (representedObject === WI.debuggerManager.assertionsBreakpoint) {
    375             cookie[WI.DebuggerSidebarPanel.SelectedAssertionsCookieKey] = true;
     344        if (representedObject === WI.debuggerManager.uncaughtExceptionsBreakpoint) {
     345            cookie[WI.DebuggerSidebarPanel.SelectedUncaughtExceptionsCookieKey] = true;
     346            return;
     347        }
     348
     349        if (representedObject === WI.debuggerManager.assertionFailuresBreakpoint) {
     350            cookie[WI.DebuggerSidebarPanel.SelectedAssertionFailuresCookieKey] = true;
    376351            return;
    377352        }
     
    389364        console.assert(cookie);
    390365
     366        function revealAndSelect(treeOutline, breakpoint) {
     367            let treeElement = treeOutline.findTreeElement(breakpoint);
     368            if (!treeElement)
     369                return;
     370
     371            treeElement.revealAndSelect();
     372        }
     373
    391374        // Eagerly resolve the special breakpoints; otherwise, use the default behavior.
    392375        if (cookie[WI.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey])
    393             this._allExceptionsBreakpointTreeElement.revealAndSelect();
    394         else if (cookie[WI.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey])
    395             this._allUncaughtExceptionsBreakpointTreeElement.revealAndSelect();
    396         else if (cookie[WI.DebuggerSidebarPanel.SelectedAssertionsCookieKey])
    397             this._assertionsBreakpointTreeElement.revealAndSelect();
    398         else if (cookie[WI.DebuggerSidebarPanel.SelectedAllRequestsCookieKey]) {
    399             if (this._xhrBreakpointTreeController)
    400                 this._xhrBreakpointTreeController.revealAndSelect(WI.domDebuggerManager.allRequestsBreakpoint);
    401         } else
     376            revealAndSelect(this._breakpointsContentTreeOutline, WI.debuggerManager.allExceptionsBreakpoint);
     377        else if (cookie[WI.DebuggerSidebarPanel.SelectedUncaughtExceptionsCookieKey])
     378            revealAndSelect(this._breakpointsContentTreeOutline, WI.debuggerManager.uncaughtExceptionsBreakpoint);
     379        else if (cookie[WI.DebuggerSidebarPanel.SelectedAssertionFailuresCookieKey])
     380            revealAndSelect(this._breakpointsContentTreeOutline, WI.debuggerManager.assertionFailuresBreakpoint);
     381        else if (cookie[WI.DebuggerSidebarPanel.SelectedAllRequestsCookieKey])
     382            revealAndSelect(this._breakpointsContentTreeOutline, WI.domDebuggerManager.allRequestsBreakpoint);
     383        else
    402384            super.restoreStateFromCookie(cookie, relaxedMatchDelay);
     385    }
     386
     387    // Popover delegate
     388
     389    willDismissPopover(popover)
     390    {
     391        let breakpoint = popover.breakpoint;
     392        if (!breakpoint)
     393            return;
     394
     395        if (breakpoint instanceof WI.EventBreakpoint)
     396            WI.domDebuggerManager.addEventBreakpoint(breakpoint);
     397        else if (breakpoint instanceof WI.XHRBreakpoint)
     398            WI.domDebuggerManager.addXHRBreakpoint(breakpoint);
    403399    }
    404400
     
    450446    _addBreakpoint(breakpoint)
    451447    {
    452         let sourceCode = breakpoint.sourceCodeLocation.displaySourceCode;
    453         if (!sourceCode)
    454             return null;
    455 
    456         if (this._breakpointsContentTreeOutline.findTreeElement(breakpoint))
    457             return;
    458 
    459         let parentTreeElement = this._addTreeElementForSourceCodeToTreeOutline(sourceCode, this._breakpointsContentTreeOutline);
    460 
    461         // Mark disabled breakpoints as resolved if there is source code loaded with that URL.
    462         // This gives the illusion the breakpoint was resolved, but since we don't send disabled
    463         // breakpoints to the backend we don't know for sure. If the user enables the breakpoint
    464         // it will be resolved properly.
    465         if (breakpoint.disabled)
    466             breakpoint.resolved = true;
    467 
    468         let breakpointTreeElement = new WI.BreakpointTreeElement(breakpoint);
    469         parentTreeElement.insertChild(breakpointTreeElement, insertionIndexForObjectInListSortedByFunction(breakpointTreeElement, parentTreeElement.children, this._compareTreeElements));
     448        let constructor = WI.BreakpointTreeElement;
     449        let options = {};
     450        let parentTreeElement = this._breakpointsContentTreeOutline;
     451
     452        let getDOMNodeTreeElement = (domNode) => {
     453            console.assert(domNode, "Missing DOMNode for identifier", breakpoint.domNodeIdentifier);
     454            if (!domNode)
     455                return null;
     456
     457            let domNodeTreeElement = this._breakpointsContentTreeOutline.findTreeElement(domNode);
     458            if (!domNodeTreeElement) {
     459                domNodeTreeElement = new WI.DOMNodeTreeElement(domNode);
     460                this._addTreeElement(domNodeTreeElement, parentTreeElement);
     461            }
     462            return domNodeTreeElement;
     463        };
     464
     465        if (breakpoint === WI.debuggerManager.allExceptionsBreakpoint) {
     466            options.className = WI.DebuggerSidebarPanel.ExceptionIconStyleClassName;
     467            options.title = WI.UIString("All Exceptions");
     468        } else if (breakpoint === WI.debuggerManager.uncaughtExceptionsBreakpoint) {
     469            options.className = WI.DebuggerSidebarPanel.ExceptionIconStyleClassName;
     470            options.title = WI.UIString("Uncaught Exceptions");
     471        } else if (breakpoint === WI.debuggerManager.assertionFailuresBreakpoint) {
     472            options.className = WI.DebuggerSidebarPanel.AssertionIconStyleClassName;
     473            options.title = WI.UIString("Assertion Failures");
     474        } else if (breakpoint instanceof WI.DOMBreakpoint) {
     475            if (!breakpoint.domNodeIdentifier)
     476                return null;
     477
     478            constructor = WI.DOMBreakpointTreeElement;
     479
     480            let domNode = WI.domTreeManager.nodeForId(breakpoint.domNodeIdentifier);
     481            parentTreeElement = getDOMNodeTreeElement(domNode);
     482        } else if (breakpoint instanceof WI.EventBreakpoint) {
     483            constructor = WI.EventBreakpointTreeElement;
     484
     485            if (breakpoint.eventListener)
     486                parentTreeElement = getDOMNodeTreeElement(breakpoint.eventListener.node);
     487        } else if (breakpoint instanceof WI.XHRBreakpoint) {
     488            constructor = WI.XHRBreakpointTreeElement;
     489
     490            if (breakpoint === WI.domDebuggerManager.allRequestsBreakpoint) {
     491                options.className = WI.DebuggerSidebarPanel.AssertionIconStyleClassName;
     492                options.title = WI.UIString("All Requests");
     493            }
     494        } else {
     495            let sourceCode = breakpoint.sourceCodeLocation && breakpoint.sourceCodeLocation.displaySourceCode;
     496            if (!sourceCode)
     497                return null;
     498
     499            if (this._breakpointsContentTreeOutline.findTreeElement(breakpoint))
     500                return null;
     501
     502            parentTreeElement = this._addTreeElementForSourceCodeToTreeOutline(sourceCode, this._breakpointsContentTreeOutline);
     503
     504            // Mark disabled breakpoints as resolved if there is source code loaded with that URL.
     505            // This gives the illusion the breakpoint was resolved, but since we don't send disabled
     506            // breakpoints to the backend we don't know for sure. If the user enables the breakpoint
     507            // it will be resolved properly.
     508            if (breakpoint.disabled)
     509                breakpoint.resolved = true;
     510        }
     511
     512        let breakpointTreeElement = new constructor(breakpoint, options);
     513        this._addTreeElement(breakpointTreeElement, parentTreeElement);
    470514        if (parentTreeElement.children.length === 1)
    471515            parentTreeElement.expand();
    472516        return breakpointTreeElement;
     517    }
     518
     519    _removeBreakpoint(breakpoint)
     520    {
     521        if (this._pauseReasonTreeOutline) {
     522            let pauseReasonBreakpointTreeElement = this._pauseReasonTreeOutline.getCachedTreeElement(breakpoint);
     523            if (pauseReasonBreakpointTreeElement)
     524                pauseReasonBreakpointTreeElement.removeStatusImage();
     525        }
     526
     527        let breakpointTreeElement = this._breakpointsContentTreeOutline.getCachedTreeElement(breakpoint);
     528        if (!breakpointTreeElement)
     529            return;
     530
     531        this._removeDebuggerTreeElement(breakpointTreeElement);
    473532    }
    474533
     
    508567            treeElement.expand();
    509568
    510             treeOutline.insertChild(treeElement, insertionIndexForObjectInListSortedByFunction(treeElement, treeOutline.children, this._compareTopLevelTreeElements.bind(this)));
     569            this._addTreeElement(treeElement, treeOutline);
    511570        }
    512571
     
    551610            this.pruneStaleResourceTreeElements();
    552611            this.contentBrowser.contentViewContainer.closeAllContentViews();
     612
     613            for (let domBreakpoint of WI.domDebuggerManager.domBreakpoints)
     614                this._removeBreakpoint(domBreakpoint);
    553615        }
    554616
     
    658720    {
    659721        var breakpoint = event.data.breakpoint;
    660 
    661         if (this._pauseReasonTreeOutline) {
    662             var pauseReasonBreakpointTreeElement = this._pauseReasonTreeOutline.getCachedTreeElement(breakpoint);
    663             if (pauseReasonBreakpointTreeElement)
    664                 pauseReasonBreakpointTreeElement.removeStatusImage();
    665         }
    666 
    667         var breakpointTreeElement = this._breakpointsContentTreeOutline.getCachedTreeElement(breakpoint);
    668         console.assert(breakpointTreeElement);
    669         if (!breakpointTreeElement)
    670             return;
    671 
    672         this._removeDebuggerTreeElement(breakpointTreeElement);
     722        this._removeBreakpoint(breakpoint);
    673723    }
    674724
     
    742792        parentTreeElement.removeChild(debuggerTreeElement);
    743793
    744         console.assert(parentTreeElement.parent === this._breakpointsContentTreeOutline);
    745         if (parentTreeElement.children.length)
     794        if (parentTreeElement.children.length || parentTreeElement === this._breakpointsContentTreeOutline)
    746795            return;
    747796
     
    858907            return;
    859908
     909        if (treeElement instanceof WI.DOMNodeTreeElement
     910            || treeElement instanceof WI.DOMBreakpointTreeElement
     911            || treeElement instanceof WI.EventBreakpointTreeElement
     912            || treeElement instanceof WI.XHRBreakpointTreeElement)
     913            return;
     914
    860915        const options = {
    861916            ignoreNetworkTab: true,
     
    903958    }
    904959
    905     _compareTopLevelTreeElements(a, b)
    906     {
    907         function isSpecialBreakpoint(treeElement)
    908         {
    909             return treeElement.representedObject === WI.debuggerManager.allExceptionsBreakpoint
    910                 || treeElement.representedObject === WI.debuggerManager.allUncaughtExceptionsBreakpoint
    911                 || treeElement.representedObject === WI.debuggerManager.assertionsBreakpoint;
    912         }
    913 
    914         if (isSpecialBreakpoint(a))
    915             return -1;
    916         if (isSpecialBreakpoint(b))
    917             return 1;
    918 
    919         return a.mainTitle.extendedLocaleCompare(b.mainTitle);
     960    _addTreeElement(treeElement, parentTreeElement)
     961    {
     962        if (!parentTreeElement)
     963            parentTreeElement = this._breakpointsContentTreeOutline;
     964
     965        function comparator(a, b) {
     966            const rankFunctions = [
     967                (treeElement) => treeElement.representedObject === WI.debuggerManager.allExceptionsBreakpoint,
     968                (treeElement) => treeElement.representedObject === WI.debuggerManager.uncaughtExceptionsBreakpoint,
     969                (treeElement) => treeElement.representedObject === WI.debuggerManager.assertionFailuresBreakpoint,
     970                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allRequestsBreakpoint,
     971                (treeElement) => treeElement instanceof WI.BreakpointTreeElement || treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement,
     972                (treeElement) => treeElement instanceof WI.EventBreakpointTreeElement,
     973                (treeElement) => treeElement instanceof WI.DOMNodeTreeElement,
     974                (treeElement) => treeElement instanceof WI.DOMBreakpointTreeElement,
     975                (treeElement) => treeElement instanceof WI.XHRBreakpointTreeElement,
     976            ];
     977
     978            let aRank = rankFunctions.findIndex((rankFunction) => rankFunction(a));
     979            let bRank = rankFunctions.findIndex((rankFunction) => rankFunction(b));
     980            if (aRank >= 0 && bRank >= 0) {
     981                if (aRank < bRank)
     982                    return -1;
     983                if (bRank < aRank)
     984                    return 1;
     985            }
     986
     987            return a.mainTitle.extendedLocaleCompare(b.mainTitle) || a.subtitle.extendedLocaleCompare(b.subtitle);
     988        }
     989
     990        parentTreeElement.insertChild(treeElement, insertionIndexForObjectInListSortedByFunction(treeElement, parentTreeElement.children, comparator));
    920991    }
    921992
     
    9971068
    9981069                let breakpoint = WI.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
    999                 let breakpointTreeElement = new WI.BreakpointTreeElement(breakpoint, WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName, WI.UIString("Triggered Breakpoint"));
     1070                let breakpointTreeElement = new WI.BreakpointTreeElement(breakpoint, {
     1071                    className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
     1072                    title: WI.UIString("Triggered Breakpoint"),
     1073                });
    10001074                let breakpointDetailsSection = new WI.DetailsSectionRow;
    10011075                this._pauseReasonTreeOutline.appendChild(breakpointTreeElement);
     
    10431117
    10441118                let type = WI.DOMBreakpointTreeElement.displayNameForType(domBreakpoint.type);
    1045                 let domBreakpointTreeElement = new WI.DOMBreakpointTreeElement(domBreakpoint, WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName, type);
     1119                let domBreakpointTreeElement = new WI.DOMBreakpointTreeElement(domBreakpoint, {
     1120                    className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
     1121                    title: type,
     1122                });
    10461123                let domBreakpointRow = new WI.DetailsSectionRow;
    10471124                this._pauseReasonTreeOutline.appendChild(domBreakpointTreeElement);
     
    11711248                    this._pauseReasonTreeOutline = this.createContentTreeOutline(true);
    11721249
    1173                     let xhrBreakpointTreeElement = new WI.XHRBreakpointTreeElement(xhrBreakpoint, WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName, WI.UIString("Triggered XHR Breakpoint"));
     1250                    let xhrBreakpointTreeElement = new WI.XHRBreakpointTreeElement(xhrBreakpoint, {
     1251                        className: WI.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName,
     1252                        title: WI.UIString("Triggered XHR Breakpoint"),
     1253                    });
    11741254                    let xhrBreakpointRow = new WI.DetailsSectionRow;
    11751255                    this._pauseReasonTreeOutline.appendChild(xhrBreakpointTreeElement);
     
    12471327    }
    12481328
     1329    _domBreakpointResolvedStateDidChange(event)
     1330    {
     1331        let breakpoint = event.target;
     1332        if (breakpoint.domNodeIdentifier)
     1333            this._addBreakpoint(breakpoint);
     1334        else
     1335            this._removeBreakpoint(breakpoint);
     1336    }
     1337
    12491338    _handleIssueAdded(event)
    12501339    {
     
    12721361    }
    12731362
    1274     _domBreakpointAddedOrRemoved(event)
    1275     {
    1276         if (!this._domBreakpointsContentTreeOutline.children.length) {
    1277             this._domBreakpointsRow.showEmptyMessage();
    1278             return;
    1279         }
    1280 
    1281         if (this._domBreakpointsContentTreeOutline.element.parentNode)
    1282             return;
    1283 
    1284         this._domBreakpointsRow.hideEmptyMessage();
    1285         this._domBreakpointsRow.element.append(this._domBreakpointsContentTreeOutline.element);
    1286 
    1287         this._domBreakpointsSection.collapsed = false;
    1288     }
    1289 
    1290     _eventBreakpointAddedOrRemoved(event)
    1291     {
    1292         if (!this._eventBreakpointsContentTreeOutline.children.length) {
    1293             this._eventBreakpointsRow.showEmptyMessage();
    1294             return;
    1295         }
    1296 
    1297         if (this._eventBreakpointsContentTreeOutline.element.parentNode)
    1298             return;
    1299 
    1300         this._eventBreakpointsRow.hideEmptyMessage();
    1301         this._eventBreakpointsRow.element.append(this._eventBreakpointsContentTreeOutline.element);
    1302 
    1303         this._eventBreakpointsSection.collapsed = false;
    1304     }
    1305 
    1306     _addEventBreakpointButtonClicked(event)
    1307     {
    1308         let popover = new WI.EventBreakpointPopover(this);
    1309         popover.show(event.target.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
    1310     }
    1311 
    1312     _addXHRBreakpointButtonClicked(event)
    1313     {
    1314         let popover = new WI.XHRBreakpointPopover(this);
    1315         popover.show(event.target.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
    1316     }
    1317 
    1318     // Popover delegate
    1319 
    1320     willDismissPopover(popover)
    1321     {
    1322         if (popover instanceof WI.EventBreakpointPopover) {
    1323             let breakpoint = popover.breakpoint;
    1324             if (breakpoint)
    1325                 WI.domDebuggerManager.addEventBreakpoint(breakpoint);
    1326             return;
    1327         }
    1328 
    1329         if (popover instanceof WI.XHRBreakpointPopover && popover.result === WI.InputPopover.Result.Committed) {
    1330             let url = popover.value;
    1331             if (url)
    1332                 WI.domDebuggerManager.addXHRBreakpoint(new WI.XHRBreakpoint(popover.type, url));
    1333             return;
    1334         }
     1363    _handleBreakpointElementAddedOrRemoved(event)
     1364    {
     1365        let treeElement = event.data.element;
     1366
     1367        let setting = null;
     1368        if (treeElement.breakpoint === WI.debuggerManager.assertionFailuresBreakpoint)
     1369            setting = WI.settings.showAssertionFailuresBreakpoint;
     1370        else if (treeElement.representedObject === WI.domDebuggerManager.allRequestsBreakpoint)
     1371            setting = WI.settings.showAllRequestsBreakpoint;
     1372
     1373        if (setting)
     1374            setting.value = !!treeElement.parent;
     1375    }
     1376
     1377    _handleCreateBreakpointClicked(event)
     1378    {
     1379        let contextMenu = WI.ContextMenu.createFromEvent(event.data.nativeEvent);
     1380
     1381        // COMPATIBILITY (iOS 10): DebuggerAgent.setPauseOnAssertions did not exist yet.
     1382        if (DebuggerAgent.setPauseOnAssertions) {
     1383            let assertionFailuresBreakpointShown = WI.settings.showAssertionFailuresBreakpoint.value;
     1384
     1385            contextMenu.appendCheckboxItem(WI.UIString("Assertion Failures"), () => {
     1386                if (assertionFailuresBreakpointShown)
     1387                    WI.debuggerManager.removeBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
     1388                else {
     1389                    WI.debuggerManager.assertionFailuresBreakpoint.disabled = false;
     1390                    WI.debuggerManager.addBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
     1391                }
     1392            }, assertionFailuresBreakpointShown);
     1393        }
     1394
     1395        if (WI.domDebuggerManager.supported) {
     1396            contextMenu.appendSeparator();
     1397
     1398            contextMenu.appendItem(WI.UIString("Event Breakpoint\u2026"), () => {
     1399                let popover = new WI.EventBreakpointPopover(this);
     1400                popover.show(event.target.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
     1401            });
     1402
     1403            contextMenu.appendSeparator();
     1404
     1405            let allRequestsBreakpointShown = WI.settings.showAllRequestsBreakpoint.value;
     1406
     1407            contextMenu.appendCheckboxItem(WI.UIString("All Requests"), () => {
     1408                if (allRequestsBreakpointShown)
     1409                    WI.domDebuggerManager.removeXHRBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);
     1410                else {
     1411                    WI.domDebuggerManager.allRequestsBreakpoint.disabled = false;
     1412                    WI.domDebuggerManager.addXHRBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);
     1413                }
     1414            }, allRequestsBreakpointShown);
     1415
     1416            contextMenu.appendItem(WI.UIString("XHR Breakpoint\u2026"), () => {
     1417                let popover = new WI.XHRBreakpointPopover(this);
     1418                popover.show(event.target.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
     1419            });
     1420        }
     1421
     1422        contextMenu.show();
    13351423    }
    13361424};
     
    13421430
    13431431WI.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey = "debugger-sidebar-panel-all-exceptions-breakpoint";
    1344 WI.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey = "debugger-sidebar-panel-all-uncaught-exceptions-breakpoint";
    1345 WI.DebuggerSidebarPanel.SelectedAssertionsCookieKey = "debugger-sidebar-panel-assertions-breakpoint";
     1432WI.DebuggerSidebarPanel.SelectedUncaughtExceptionsCookieKey = "debugger-sidebar-panel-uncaught-exceptions-breakpoint";
     1433WI.DebuggerSidebarPanel.SelectedAssertionFailuresCookieKey = "debugger-sidebar-panel-assertion-failures-breakpoint";
    13461434WI.DebuggerSidebarPanel.SelectedAllRequestsCookieKey = "debugger-sidebar-panel-all-requests-breakpoint";
  • trunk/Source/WebInspectorUI/UserInterface/Views/EventBreakpointTreeElement.js

    r235248 r236540  
    2626WI.EventBreakpointTreeElement = class EventBreakpointTreeElement extends WI.GeneralTreeElement
    2727{
    28     constructor(breakpoint, {className, title, linkifyNode} = {})
     28    constructor(breakpoint, {className, title} = {})
    2929    {
    3030        console.assert(breakpoint instanceof WI.EventBreakpoint);
     
    3737            title = breakpoint.eventName;
    3838
    39         let subtitle = null;
    40         if (linkifyNode && breakpoint.eventListener)
    41             subtitle = WI.linkifyNodeReference(breakpoint.eventListener.node);
    42 
     39        const subtitle = null;
    4340        super(classNames, title, subtitle, breakpoint);
    4441
     
    8279    ondelete()
    8380    {
     81        // We set this flag so that TreeOutlines that will remove this
     82        // BreakpointTreeElement will know whether it was deleted from
     83        // within the TreeOutline or from outside it (e.g. TextEditor).
     84        this.__deletedViaDeleteKeyboardShortcut = true;
     85
    8486        if (this.representedObject.eventListener)
    8587            WI.domTreeManager.removeBreakpointForEventListener(this.representedObject.eventListener);
     
    109111        }
    110112
    111         if (WI.domDebuggerManager.isBreakpointRemovable(breakpoint)) {
    112             contextMenu.appendSeparator();
    113             contextMenu.appendItem(WI.UIString("Delete Breakpoint"), () => {
    114                 if (breakpoint.eventListener)
    115                     WI.domTreeManager.removeBreakpointForEventListener(breakpoint.eventListener);
    116                 else
    117                     WI.domDebuggerManager.removeEventBreakpoint(breakpoint);
    118             });
    119         }
     113        contextMenu.appendSeparator();
     114
     115        contextMenu.appendItem(WI.UIString("Delete Breakpoint"), () => {
     116            if (breakpoint.eventListener)
     117                WI.domTreeManager.removeBreakpointForEventListener(breakpoint.eventListener);
     118            else
     119                WI.domDebuggerManager.removeEventBreakpoint(breakpoint);
     120        });
    120121    }
    121122
  • trunk/Source/WebInspectorUI/UserInterface/Views/XHRBreakpointPopover.js

    r220119 r236540  
    3030        super(delegate);
    3131
    32         this._result = WI.InputPopover.Result.None;
    33         this._type = WI.XHRBreakpoint.Type.Text;
    34         this._value = null;
     32        this._breakpoint = null;
    3533
    3634        this._codeMirror = null;
     
    4341    // Public
    4442
    45     get result() { return this._result; }
    46     get type() { return this._type; }
    47     get value() { return this._value; }
     43    get breakpoint() { return this._breakpoint; }
    4844
    4945    show(targetElement, preferredEdges)
     
    6258        editorWrapper.classList.add("editor-wrapper");
    6359
    64         let selectElement = document.createElement("select");
     60        this._typeSelectElement = document.createElement("select");
    6561
    66         function addOption(text, value)
    67         {
    68             let optionElement = document.createElement("option");
     62        let createOption = (text, value) => {
     63            let optionElement = this._typeSelectElement.appendChild(document.createElement("option"));
    6964            optionElement.textContent = text;
    7065            optionElement.value = value;
    71             selectElement.append(optionElement);
    72         }
     66        };
    7367
    74         addOption(WI.UIString("Containing"), WI.XHRBreakpoint.Type.Text);
    75         addOption(WI.UIString("Matching"), WI.XHRBreakpoint.Type.RegularExpression);
     68        createOption(WI.UIString("Containing"), WI.XHRBreakpoint.Type.Text);
     69        createOption(WI.UIString("Matching"), WI.XHRBreakpoint.Type.RegularExpression);
    7670
    77         selectElement.value = this._type;
    78         selectElement.addEventListener("change", (event) => {
    79             this._type = event.target.value;
     71        this._typeSelectElement.value = WI.XHRBreakpoint.Type.Text;
     72        this._typeSelectElement.addEventListener("change", (event) => {
    8073            this._updateEditor();
    8174            this._codeMirror.focus();
    8275        });
    8376
    84         editorWrapper.append(selectElement, this._createEditor());
     77        editorWrapper.append(this._typeSelectElement, this._createEditor());
    8578        contentElement.append(label, editorWrapper);
    8679
     
    8881
    8982        this._presentOverTargetElement();
     83    }
     84
     85    dismiss()
     86    {
     87        let type = this._typeSelectElement.value;
     88        let url = this._codeMirror.getValue();
     89        if (type && url)
     90            this._breakpoint = new WI.XHRBreakpoint(type, url);
     91
     92        super.dismiss();
    9093    }
    9194
     
    106109        this._codeMirror.addKeyMap({
    107110            "Enter": () => {
    108                 this._result = WI.InputPopover.Result.Committed;
    109                 this._value = this._codeMirror.getValue().trim();
     111                this.dismiss();
     112            },
     113            "Esc": () => {
    110114                this.dismiss();
    111115            },
     
    121125        let placeholder;
    122126        let mimeType;
    123         if (this._type === WI.XHRBreakpoint.Type.Text) {
     127        if (this._typeSelectElement.value === WI.XHRBreakpoint.Type.Text) {
    124128            placeholder = WI.UIString("Text");
    125129            mimeType = "text/plain";
  • trunk/Source/WebInspectorUI/UserInterface/Views/XHRBreakpointTreeElement.css

    r236539 r236540  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WI.DOMNodeTreeElement = class DOMNodeTreeElement extends WI.GeneralTreeElement
    27 {
    28     constructor(domNode)
    29     {
    30         console.assert(domNode instanceof WI.DOMNode);
    31 
    32         const subtitle = null;
    33         super("dom-node", domNode.displayName, subtitle, domNode, {hasChildren: true});
    34 
    35         this.status = WI.linkifyNodeReferenceElement(domNode, WI.createGoToArrowButton());
    36         this.tooltipHandledSeparately = true;
    37     }
    38 
    39     // Protected
    40 
    41     ondelete()
    42     {
    43         WI.domDebuggerManager.removeDOMBreakpointsForNode(this.representedObject);
    44         return true;
    45     }
    46 
    47     populateContextMenu(contextMenu, event)
    48     {
    49         contextMenu.appendSeparator();
    50 
    51         const allowEditing = true;
    52         WI.DOMBreakpointTreeController.appendBreakpointContextMenuItems(contextMenu, this.representedObject, allowEditing);
    53 
    54         contextMenu.appendSeparator();
    55 
    56         contextMenu.appendItem(WI.UIString("Reveal in DOM Tree"), () => {
    57             WI.domTreeManager.inspectElement(this.representedObject.id);
    58         });
    59     }
    60 };
     26.breakpoint.xhr .subtitle {
     27    font-family: Menlo, monospace;
     28}
  • trunk/Source/WebInspectorUI/UserInterface/Views/XHRBreakpointTreeElement.js

    r229543 r236540  
    2626WI.XHRBreakpointTreeElement = class XHRBreakpointTreeElement extends WI.GeneralTreeElement
    2727{
    28     constructor(breakpoint, className, title)
     28    constructor(breakpoint, {className, title} = {})
    2929    {
    3030        console.assert(breakpoint instanceof WI.XHRBreakpoint);
     
    4242        }
    4343
    44         super(["breakpoint", className], title, subtitle, breakpoint);
     44        super(["breakpoint", "xhr", className], title, subtitle, breakpoint);
    4545
    4646        this._statusImageElement = document.createElement("img");
     
    8484    ondelete()
    8585    {
     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
    8691        WI.domDebuggerManager.removeXHRBreakpoint(this.representedObject);
    8792        return true;
     
    106111        contextMenu.appendItem(label, this._toggleBreakpoint.bind(this));
    107112
    108         if (WI.domDebuggerManager.isBreakpointRemovable(breakpoint)) {
    109             contextMenu.appendSeparator();
    110             contextMenu.appendItem(WI.UIString("Delete Breakpoint"), function() {
    111                 WI.domDebuggerManager.removeXHRBreakpoint(breakpoint);
    112             });
    113         }
     113        contextMenu.appendSeparator();
     114
     115        contextMenu.appendItem(WI.UIString("Delete Breakpoint"), () => {
     116            WI.domDebuggerManager.removeXHRBreakpoint(breakpoint);
     117        });
    114118    }
    115119
Note: See TracChangeset for help on using the changeset viewer.