OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2011 Google 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 /** | |
32 * @implements {UI.ContextFlavorListener} | |
33 */ | |
34 Components.DOMBreakpointsSidebarPane = class extends Components.BreakpointsSideb
arPaneBase { | |
35 constructor() { | |
36 super(); | |
37 this.registerRequiredCSS('components/breakpointsList.css'); | |
38 this.listElement.classList.add('dom-breakpoints-list'); | |
39 | |
40 /** @type {!Map<!SDK.DOMDebuggerModel.DOMBreakpoint, !Components.DOMBreakpoi
ntsSidebarPane.Item>} */ | |
41 this._items = new Map(); | |
42 SDK.targetManager.addModelListener( | |
43 SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, th
is._breakpointAdded, this); | |
44 SDK.targetManager.addModelListener( | |
45 SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointToggled,
this._breakpointToggled, this); | |
46 SDK.targetManager.addModelListener( | |
47 SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointsRemoved,
this._breakpointsRemoved, this); | |
48 | |
49 for (var domDebuggerModel of SDK.targetManager.models(SDK.DOMDebuggerModel))
{ | |
50 domDebuggerModel.retrieveDOMBreakpoints(); | |
51 for (var breakpoint of domDebuggerModel.domBreakpoints()) | |
52 this._addBreakpoint(breakpoint); | |
53 } | |
54 | |
55 this._highlightedElement = null; | |
56 this._update(); | |
57 } | |
58 | |
59 /** | |
60 * @param {!SDK.DebuggerPausedDetails} details | |
61 * @return {!Element} | |
62 */ | |
63 static createBreakpointHitMessage(details) { | |
64 var messageWrapper = createElement('span'); | |
65 var domDebuggerModel = details.debuggerModel.target().model(SDK.DOMDebuggerM
odel); | |
66 if (!details.auxData || !domDebuggerModel) | |
67 return messageWrapper; | |
68 var data = domDebuggerModel.resolveDOMBreakpointData(/** @type {!Object} */
(details.auxData)); | |
69 if (!data) | |
70 return messageWrapper; | |
71 | |
72 var mainElement = messageWrapper.createChild('div', 'status-main'); | |
73 mainElement.appendChild(UI.Icon.create('smallicon-info', 'status-icon')); | |
74 mainElement.appendChild(createTextNode( | |
75 String.sprintf('Paused on %s', Components.DOMBreakpointsSidebarPane.Brea
kpointTypeNouns.get(data.type)))); | |
76 | |
77 var subElement = messageWrapper.createChild('div', 'status-sub monospace'); | |
78 var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(dat
a.node); | |
79 subElement.appendChild(linkifiedNode); | |
80 | |
81 if (data.targetNode) { | |
82 var targetNodeLink = Components.DOMPresentationUtils.linkifyNodeReference(
data.targetNode); | |
83 var message; | |
84 if (data.insertion) | |
85 message = data.targetNode === data.node ? 'Child %s added' : 'Descendant
%s added'; | |
86 else | |
87 message = 'Descendant %s removed'; | |
88 subElement.appendChild(createElement('br')); | |
89 subElement.appendChild(UI.formatLocalized(message, [targetNodeLink])); | |
90 } | |
91 return messageWrapper; | |
92 } | |
93 | |
94 /** | |
95 * @param {!Common.Event} event | |
96 */ | |
97 _breakpointAdded(event) { | |
98 this._addBreakpoint(/** @type {!SDK.DOMDebuggerModel.DOMBreakpoint} */ (even
t.data)); | |
99 } | |
100 | |
101 /** | |
102 * @param {!Common.Event} event | |
103 */ | |
104 _breakpointToggled(event) { | |
105 var breakpoint = /** @type {!SDK.DOMDebuggerModel.DOMBreakpoint} */ (event.d
ata); | |
106 var item = this._items.get(breakpoint); | |
107 if (item) | |
108 item.checkbox.checked = breakpoint.enabled; | |
109 } | |
110 | |
111 /** | |
112 * @param {!Common.Event} event | |
113 */ | |
114 _breakpointsRemoved(event) { | |
115 var breakpoints = /** @type {!Array<!SDK.DOMDebuggerModel.DOMBreakpoint>} */
(event.data); | |
116 for (var breakpoint of breakpoints) { | |
117 var item = this._items.get(breakpoint); | |
118 if (item) { | |
119 this._items.delete(breakpoint); | |
120 this.removeListElement(item.element); | |
121 } | |
122 } | |
123 } | |
124 | |
125 /** | |
126 * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint | |
127 */ | |
128 _addBreakpoint(breakpoint) { | |
129 var element = createElement('li'); | |
130 element.addEventListener('contextmenu', this._contextMenu.bind(this, breakpo
int), true); | |
131 | |
132 var checkboxLabel = UI.CheckboxLabel.create('', breakpoint.enabled); | |
133 var checkboxElement = checkboxLabel.checkboxElement; | |
134 checkboxElement.addEventListener('click', this._checkboxClicked.bind(this, b
reakpoint), false); | |
135 element.appendChild(checkboxLabel); | |
136 | |
137 var labelElement = createElementWithClass('div', 'dom-breakpoint'); | |
138 element.appendChild(labelElement); | |
139 | |
140 var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(bre
akpoint.node); | |
141 linkifiedNode.classList.add('monospace'); | |
142 linkifiedNode.style.display = 'block'; | |
143 labelElement.appendChild(linkifiedNode); | |
144 | |
145 var description = createElement('div'); | |
146 description.textContent = Components.DOMBreakpointsSidebarPane.BreakpointTyp
eLabels.get(breakpoint.type); | |
147 labelElement.appendChild(description); | |
148 | |
149 var item = {breakpoint: breakpoint, element: element, checkbox: checkboxElem
ent}; | |
150 element._item = item; | |
151 this._items.set(breakpoint, item); | |
152 | |
153 var currentElement = this.listElement.firstChild; | |
154 while (currentElement) { | |
155 if (currentElement._item && currentElement._item.breakpoint.type < breakpo
int.type) | |
156 break; | |
157 currentElement = currentElement.nextSibling; | |
158 } | |
159 this.addListElement(element, currentElement); | |
160 } | |
161 | |
162 /** | |
163 * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint | |
164 * @param {!Event} event | |
165 */ | |
166 _contextMenu(breakpoint, event) { | |
167 var contextMenu = new UI.ContextMenu(event); | |
168 contextMenu.appendItem(Common.UIString.capitalize('Remove ^breakpoint'), ()
=> { | |
169 breakpoint.domDebuggerModel.removeDOMBreakpoint(breakpoint.node, breakpoin
t.type); | |
170 }); | |
171 contextMenu.appendItem(Common.UIString.capitalize('Remove ^all DOM breakpoin
ts'), () => { | |
172 breakpoint.domDebuggerModel.removeAllDOMBreakpoints(); | |
173 }); | |
174 contextMenu.show(); | |
175 } | |
176 | |
177 /** | |
178 * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint | |
179 */ | |
180 _checkboxClicked(breakpoint) { | |
181 var item = this._items.get(breakpoint); | |
182 if (!item) | |
183 return; | |
184 breakpoint.domDebuggerModel.toggleDOMBreakpoint(breakpoint, item.checkbox.ch
ecked); | |
185 } | |
186 | |
187 /** | |
188 * @override | |
189 * @param {?Object} object | |
190 */ | |
191 flavorChanged(object) { | |
192 this._update(); | |
193 } | |
194 | |
195 _update() { | |
196 var details = UI.context.flavor(SDK.DebuggerPausedDetails); | |
197 if (!details || !details.auxData || details.reason !== SDK.DebuggerModel.Bre
akReason.DOM) { | |
198 if (this._highlightedElement) { | |
199 this._highlightedElement.classList.remove('breakpoint-hit'); | |
200 delete this._highlightedElement; | |
201 } | |
202 return; | |
203 } | |
204 var domDebuggerModel = details.debuggerModel.target().model(SDK.DOMDebuggerM
odel); | |
205 if (!domDebuggerModel) | |
206 return; | |
207 var data = domDebuggerModel.resolveDOMBreakpointData(/** @type {!Object} */
(details.auxData)); | |
208 if (!data) | |
209 return; | |
210 | |
211 var element = null; | |
212 for (var item of this._items.values()) { | |
213 if (item.breakpoint.node === data.node && item.breakpoint.type === data.ty
pe) | |
214 element = item.element; | |
215 } | |
216 if (!element) | |
217 return; | |
218 UI.viewManager.showView('sources.domBreakpoints'); | |
219 element.classList.add('breakpoint-hit'); | |
220 this._highlightedElement = element; | |
221 } | |
222 }; | |
223 | |
224 /** @typedef {!{element: !Element, checkbox: !Element, breakpoint: !SDK.DOMDebug
gerModel.DOMBreakpoint}} */ | |
225 Components.DOMBreakpointsSidebarPane.Item; | |
226 | |
227 Components.DOMBreakpointsSidebarPane.BreakpointTypeLabels = new Map([ | |
228 [SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified, Common.UIString('Sub
tree Modified')], | |
229 [SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified, Common.UIString('A
ttribute Modified')], | |
230 [SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved, Common.UIString('Node Re
moved')], | |
231 ]); | |
232 | |
233 Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns = new Map([ | |
234 [SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified, Common.UIString('sub
tree modifications')], | |
235 [SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified, Common.UIString('a
ttribute modifications')], | |
236 [SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved, Common.UIString('node re
moval')], | |
237 ]); | |
238 | |
239 /** | |
240 * @implements {UI.ContextMenu.Provider} | |
241 */ | |
242 Components.DOMBreakpointsSidebarPane.ContextMenuProvider = class { | |
243 /** | |
244 * @override | |
245 * @param {!Event} event | |
246 * @param {!UI.ContextMenu} contextMenu | |
247 * @param {!Object} object | |
248 */ | |
249 appendApplicableItems(event, contextMenu, object) { | |
250 var node = /** @type {!SDK.DOMNode} */ (object); | |
251 if (node.pseudoType()) | |
252 return; | |
253 var domDebuggerModel = node.domModel().target().model(SDK.DOMDebuggerModel); | |
254 if (!domDebuggerModel) | |
255 return; | |
256 | |
257 /** | |
258 * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type | |
259 */ | |
260 function toggleBreakpoint(type) { | |
261 if (domDebuggerModel.hasDOMBreakpoint(node, type)) | |
262 domDebuggerModel.removeDOMBreakpoint(node, type); | |
263 else | |
264 domDebuggerModel.setDOMBreakpoint(node, type); | |
265 } | |
266 | |
267 var breakpointsMenu = contextMenu.appendSubMenuItem(Common.UIString('Break o
n...')); | |
268 for (var key in SDK.DOMDebuggerModel.DOMBreakpoint.Type) { | |
269 var type = SDK.DOMDebuggerModel.DOMBreakpoint.Type[key]; | |
270 var label = Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns.get(t
ype); | |
271 breakpointsMenu.appendCheckboxItem( | |
272 label, toggleBreakpoint.bind(null, type), domDebuggerModel.hasDOMBreak
point(node, type)); | |
273 } | |
274 } | |
275 }; | |
OLD | NEW |