Web Inspector: REGRESSION (r248873): Debugger: pressing delete on a breakpoint will...
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / EventBreakpointTreeElement.js
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WI.EventBreakpointTreeElement = class EventBreakpointTreeElement extends WI.GeneralTreeElement
27 {
28     constructor(breakpoint, {className, title} = {})
29     {
30         console.assert(breakpoint instanceof WI.EventBreakpoint);
31
32         let classNames = ["breakpoint", "event", `breakpoint-for-${breakpoint.type}`];
33         if (className)
34             classNames.push(className);
35
36         if (!title)
37             title = breakpoint.eventName;
38
39         const subtitle = null;
40         super(classNames, title, subtitle, breakpoint);
41
42         this.status = WI.ImageUtilities.useSVGSymbol("Images/Breakpoint.svg");
43         this.status.className = WI.BreakpointTreeElement.StatusImageElementStyleClassName;
44
45         this.tooltipHandledSeparately = true;
46     }
47
48     // Protected
49
50     onattach()
51     {
52         super.onattach();
53
54         this.representedObject.addEventListener(WI.EventBreakpoint.Event.DisabledStateChanged, this._updateStatus, this);
55         WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._updateStatus, this);
56
57         this._boundStatusImageElementClicked = this._statusImageElementClicked.bind(this);
58         this._boundStatusImageElementFocused = this._statusImageElementFocused.bind(this);
59         this._boundStatusImageElementMouseDown = this._statusImageElementMouseDown.bind(this);
60
61         this.status.addEventListener("click", this._boundStatusImageElementClicked);
62         this.status.addEventListener("focus", this._boundStatusImageElementFocused);
63         this.status.addEventListener("mousedown", this._boundStatusImageElementMouseDown);
64
65         this._updateStatus();
66     }
67
68     ondetach()
69     {
70         super.ondetach();
71
72         this.representedObject.removeEventListener(null, null, this);
73         WI.debuggerManager.removeEventListener(null, null, this);
74
75         this.status.removeEventListener("click", this._boundStatusImageElementClicked);
76         this.status.removeEventListener("focus", this._boundStatusImageElementFocused);
77         this.status.removeEventListener("mousedown", this._boundStatusImageElementMouseDown);
78
79         this._boundStatusImageElementClicked = null;
80         this._boundStatusImageElementFocused = null;
81         this._boundStatusImageElementMouseDown = null;
82     }
83
84     ondelete()
85     {
86         // We set this flag so that TreeOutlines that will remove this
87         // BreakpointTreeElement will know whether it was deleted from
88         // within the TreeOutline or from outside it (e.g. TextEditor).
89         this.__deletedViaDeleteKeyboardShortcut = true;
90
91         if (this.representedObject.eventListener)
92             WI.domManager.removeBreakpointForEventListener(this.representedObject.eventListener);
93         else
94             WI.domDebuggerManager.removeEventBreakpoint(this.representedObject);
95
96         return true;
97     }
98
99     onenter()
100     {
101         this._toggleBreakpoint();
102         return true;
103     }
104
105     onspace()
106     {
107         this._toggleBreakpoint();
108         return true;
109     }
110
111     populateContextMenu(contextMenu, event)
112     {
113         let breakpoint = this.representedObject;
114
115         let label = breakpoint.disabled ? WI.UIString("Enable Breakpoint") : WI.UIString("Disable Breakpoint");
116         contextMenu.appendItem(label, this._toggleBreakpoint.bind(this));
117
118         contextMenu.appendItem(WI.UIString("Delete Breakpoint"), () => {
119             if (breakpoint.eventListener)
120                 WI.domManager.removeBreakpointForEventListener(breakpoint.eventListener);
121             else
122                 WI.domDebuggerManager.removeEventBreakpoint(breakpoint);
123         });
124     }
125
126     // Private
127
128     _statusImageElementClicked(event)
129     {
130         this._toggleBreakpoint();
131     }
132
133     _statusImageElementFocused(event)
134     {
135         // Prevent tree outline focus.
136         event.stopPropagation();
137     }
138
139     _statusImageElementMouseDown(event)
140     {
141         // Prevent tree element selection.
142         event.stopPropagation();
143     }
144
145     _toggleBreakpoint()
146     {
147         this.representedObject.disabled = !this.representedObject.disabled;
148     }
149
150     _updateStatus()
151     {
152         if (!this.status)
153             return;
154
155         this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageDisabledStyleClassName, this.representedObject.disabled);
156         this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageResolvedStyleClassName, WI.debuggerManager.breakpointsEnabled);
157     }
158 };