e186f70f9e6137ae4f679bb196783d0e67a88d8e
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / DOMBreakpointTreeElement.js
1 /*
2  * Copyright (C) 2017 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.DOMBreakpointTreeElement = class DOMBreakpointTreeElement extends WI.GeneralTreeElement
27 {
28     constructor(breakpoint, {className, title} = {})
29     {
30         console.assert(breakpoint instanceof WI.DOMBreakpoint);
31
32         let classNames = ["breakpoint", "dom", `breakpoint-for-${breakpoint.type}`];
33         if (className)
34             classNames.push(className);
35
36         if (!title)
37             title = WI.DOMBreakpointTreeElement.displayNameForType(breakpoint.type);
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     // Static
49
50     static displayNameForType(type)
51     {
52         switch (type) {
53         case WI.DOMBreakpoint.Type.SubtreeModified:
54             return WI.UIString("Subtree Modified", "A submenu item of 'Break On' that breaks (pauses) before child DOM node is modified");
55         case WI.DOMBreakpoint.Type.AttributeModified:
56             return WI.UIString("Attribute Modified", "A submenu item of 'Break On' that breaks (pauses) before DOM attribute is modified");
57         case WI.DOMBreakpoint.Type.NodeRemoved:
58             return WI.UIString("Node Removed", "A submenu item of 'Break On' that breaks (pauses) before DOM node is removed");
59         default:
60             console.error("Unexpected DOM breakpoint type: " + type);
61             return null;
62         }
63     }
64
65     // Protected
66
67     onattach()
68     {
69         super.onattach();
70
71         this.representedObject.addEventListener(WI.DOMBreakpoint.Event.DisabledStateChanged, this._updateStatus, this);
72         WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._updateStatus, this);
73
74         this._boundStatusImageElementClicked = this._statusImageElementClicked.bind(this);
75         this._boundStatusImageElementFocused = this._statusImageElementFocused.bind(this);
76         this._boundStatusImageElementMouseDown = this._statusImageElementMouseDown.bind(this);
77
78         this.status.addEventListener("click", this._boundStatusImageElementClicked);
79         this.status.addEventListener("focus", this._boundStatusImageElementFocused);
80         this.status.addEventListener("mousedown", this._boundStatusImageElementMouseDown);
81
82         this._updateStatus();
83     }
84
85     ondetach()
86     {
87         super.ondetach();
88
89         this.representedObject.removeEventListener(null, null, this);
90         WI.debuggerManager.removeEventListener(null, null, this);
91
92         this.status.removeEventListener("click", this._boundStatusImageElementClicked);
93         this.status.removeEventListener("focus", this._boundStatusImageElementFocused);
94         this.status.removeEventListener("mousedown", this._boundStatusImageElementMouseDown);
95
96         this._boundStatusImageElementClicked = null;
97         this._boundStatusImageElementFocused = null;
98         this._boundStatusImageElementMouseDown = null;
99     }
100
101     ondelete()
102     {
103         // We set this flag so that TreeOutlines that will remove this
104         // BreakpointTreeElement will know whether it was deleted from
105         // within the TreeOutline or from outside it (e.g. TextEditor).
106         this.__deletedViaDeleteKeyboardShortcut = true;
107
108         WI.domDebuggerManager.removeDOMBreakpoint(this.representedObject);
109     }
110
111     onenter()
112     {
113         this._toggleBreakpoint();
114         return true;
115     }
116
117     onspace()
118     {
119         this._toggleBreakpoint();
120         return true;
121     }
122
123     populateContextMenu(contextMenu, event)
124     {
125         let breakpoint = this.representedObject;
126         let label = breakpoint.disabled ? WI.UIString("Enable Breakpoint") : WI.UIString("Disable Breakpoint");
127         contextMenu.appendItem(label, this._toggleBreakpoint.bind(this));
128
129         contextMenu.appendItem(WI.UIString("Delete Breakpoint"), function() {
130             WI.domDebuggerManager.removeDOMBreakpoint(breakpoint);
131         });
132     }
133
134     // Private
135
136     _statusImageElementClicked(event)
137     {
138         this._toggleBreakpoint();
139     }
140
141     _statusImageElementFocused(event)
142     {
143         // Prevent tree outline focus.
144         event.stopPropagation();
145     }
146
147     _statusImageElementMouseDown(event)
148     {
149         // Prevent tree element selection.
150         event.stopPropagation();
151     }
152
153     _toggleBreakpoint()
154     {
155         this.representedObject.disabled = !this.representedObject.disabled;
156     }
157
158     _updateStatus()
159     {
160         if (!this.status)
161             return;
162
163         this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageDisabledStyleClassName, this.representedObject.disabled);
164         this.status.classList.toggle(WI.BreakpointTreeElement.StatusImageResolvedStyleClassName, WI.debuggerManager.breakpointsEnabled);
165     }
166 };