OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
13 * distribution. | 13 * distribution. |
14 * * Neither the name of Google Inc. nor the names of its | 14 * * Neither the name of Google Inc. nor the names of its |
15 * contributors may be used to endorse or promote products derived from | 15 * contributors may be used to endorse or promote products derived from |
16 * this software without specific prior written permission. | 16 * this software without specific prior written permission. |
17 * | 17 * |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
| 30 |
30 /** | 31 /** |
31 * @implements {UI.ContextFlavorListener} | 32 * @implements {UI.ContextFlavorListener} |
32 * @unrestricted | |
33 */ | 33 */ |
34 Components.DOMBreakpointsSidebarPane = class extends Components.BreakpointsSideb
arPaneBase { | 34 Components.DOMBreakpointsSidebarPane = class extends Components.BreakpointsSideb
arPaneBase { |
35 constructor() { | 35 constructor() { |
36 super(); | 36 super(); |
37 this._domBreakpointsSetting = Common.settings.createLocalSetting('domBreakpo
ints', []); | 37 this.registerRequiredCSS('components/breakpointsList.css'); |
38 this.listElement.classList.add('dom-breakpoints-list'); | 38 this.listElement.classList.add('dom-breakpoints-list'); |
39 | 39 |
40 /** @type {!Map<string, !Element>} */ | 40 /** @type {!Map<!SDK.DOMDebuggerModel.DOMBreakpoint, !Components.DOMBreakpoi
ntsSidebarPane.Item>} */ |
41 this._breakpointElements = new Map(); | 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); |
42 | 48 |
43 SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.NodeRem
oved, this._nodeRemoved, this); | 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; |
44 this._update(); | 56 this._update(); |
45 } | 57 } |
46 | 58 |
47 /** | 59 /** |
48 * @param {!SDK.DebuggerPausedDetails} details | 60 * @param {!SDK.DebuggerPausedDetails} details |
49 * @return {!Element} | 61 * @return {!Element} |
50 */ | 62 */ |
51 static createBreakpointHitMessage(details) { | 63 static createBreakpointHitMessage(details) { |
52 var messageWrapper = createElement('span'); | 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 |
53 var mainElement = messageWrapper.createChild('div', 'status-main'); | 72 var mainElement = messageWrapper.createChild('div', 'status-main'); |
54 mainElement.appendChild(UI.Icon.create('smallicon-info', 'status-icon')); | 73 mainElement.appendChild(UI.Icon.create('smallicon-info', 'status-icon')); |
55 var auxData = /** @type {!Object} */ (details.auxData); | |
56 mainElement.appendChild(createTextNode( | 74 mainElement.appendChild(createTextNode( |
57 String.sprintf('Paused on %s', Components.DOMBreakpointsSidebarPane.Brea
kpointTypeNouns[auxData['type']]))); | 75 String.sprintf('Paused on %s', Components.DOMBreakpointsSidebarPane.Brea
kpointTypeNouns.get(data.type)))); |
58 | 76 |
59 var domModel = details.debuggerModel.target().model(SDK.DOMModel); | 77 var subElement = messageWrapper.createChild('div', 'status-sub monospace'); |
60 if (domModel) { | 78 var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(dat
a.node); |
61 var subElement = messageWrapper.createChild('div', 'status-sub monospace')
; | 79 subElement.appendChild(linkifiedNode); |
62 var node = domModel.nodeForId(auxData['nodeId']); | |
63 var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(n
ode); | |
64 subElement.appendChild(linkifiedNode); | |
65 | 80 |
66 var targetNode = auxData['targetNodeId'] ? domModel.nodeForId(auxData['tar
getNodeId']) : null; | 81 if (data.targetNode) { |
67 var targetNodeLink = targetNode ? Components.DOMPresentationUtils.linkifyN
odeReference(targetNode) : ''; | 82 var targetNodeLink = Components.DOMPresentationUtils.linkifyNodeReference(
data.targetNode); |
68 var message; | 83 var message; |
69 if (auxData.type === Components.DOMBreakpointsSidebarPane.BreakpointTypes.
SubtreeModified) { | 84 if (data.insertion) |
70 if (auxData['insertion']) | 85 message = data.targetNode === data.node ? 'Child %s added' : 'Descendant
%s added'; |
71 message = targetNode === node ? 'Child %s added' : 'Descendant %s adde
d'; | 86 else |
72 else | 87 message = 'Descendant %s removed'; |
73 message = 'Descendant %s removed'; | 88 subElement.appendChild(createElement('br')); |
74 subElement.appendChild(createElement('br')); | 89 subElement.appendChild(UI.formatLocalized(message, [targetNodeLink])); |
75 subElement.appendChild(UI.formatLocalized(message, [targetNodeLink])); | |
76 } | |
77 } | 90 } |
78 return messageWrapper; | 91 return messageWrapper; |
79 } | 92 } |
80 | 93 |
81 /** | 94 /** |
82 * @param {!SDK.DOMNode} node | 95 * @param {!Common.Event} event |
83 * @param {!UI.ContextMenu} contextMenu | |
84 * @param {boolean} createSubMenu | |
85 */ | 96 */ |
86 populateNodeContextMenu(node, contextMenu, createSubMenu) { | 97 _breakpointAdded(event) { |
87 if (node.pseudoType()) | 98 this._addBreakpoint(/** @type {!SDK.DOMDebuggerModel.DOMBreakpoint} */ (even
t.data)); |
88 return; | 99 } |
89 | 100 |
90 var nodeBreakpoints = this._nodeBreakpoints(node); | 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 } |
91 | 110 |
92 /** | 111 /** |
93 * @param {!Protocol.DOMDebugger.DOMBreakpointType} type | 112 * @param {!Common.Event} event |
94 * @this {Components.DOMBreakpointsSidebarPane} | 113 */ |
95 */ | 114 _breakpointsRemoved(event) { |
96 function toggleBreakpoint(type) { | 115 var breakpoints = /** @type {!Array<!SDK.DOMDebuggerModel.DOMBreakpoint>} */
(event.data); |
97 if (!nodeBreakpoints.has(type)) | 116 for (var breakpoint of breakpoints) { |
98 this._setBreakpoint(node, type, true); | 117 var item = this._items.get(breakpoint); |
99 else | 118 if (item) { |
100 this._removeBreakpoint(node, type); | 119 this._items.delete(breakpoint); |
101 this._saveBreakpoints(); | 120 this.removeListElement(item.element); |
102 } | 121 } |
103 | |
104 var breakpointsMenu = createSubMenu ? contextMenu.appendSubMenuItem(Common.U
IString('Break on...')) : contextMenu; | |
105 for (var key in Components.DOMBreakpointsSidebarPane.BreakpointTypes) { | |
106 var type = Components.DOMBreakpointsSidebarPane.BreakpointTypes[key]; | |
107 var label = Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns[type]
; | |
108 breakpointsMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type
), nodeBreakpoints.has(type)); | |
109 } | 122 } |
110 } | 123 } |
111 | 124 |
112 /** | 125 /** |
113 * @param {!SDK.DOMNode} node | 126 * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint |
114 * @return {!Set<!Protocol.DOMDebugger.DOMBreakpointType>} | |
115 */ | 127 */ |
116 _nodeBreakpoints(node) { | 128 _addBreakpoint(breakpoint) { |
117 /** @type {!Set<!Protocol.DOMDebugger.DOMBreakpointType>} */ | 129 var element = createElement('li'); |
118 var nodeBreakpoints = new Set(); | 130 element.addEventListener('contextmenu', this._contextMenu.bind(this, breakpo
int), true); |
119 for (var element of this._breakpointElements.values()) { | |
120 if (element._node === node && element._checkboxElement.checked) | |
121 nodeBreakpoints.add(element._type); | |
122 } | |
123 return nodeBreakpoints; | |
124 } | |
125 | 131 |
126 /** | 132 var checkboxLabel = UI.CheckboxLabel.create('', breakpoint.enabled); |
127 * @param {!SDK.DOMNode} node | |
128 * @return {boolean} | |
129 */ | |
130 hasBreakpoints(node) { | |
131 for (var element of this._breakpointElements.values()) { | |
132 if (element._node === node && element._checkboxElement.checked) | |
133 return true; | |
134 } | |
135 return false; | |
136 } | |
137 | |
138 _nodeRemoved(event) { | |
139 var node = event.data.node; | |
140 this._removeBreakpointsForNode(event.data.node); | |
141 var children = node.children(); | |
142 if (!children) | |
143 return; | |
144 for (var i = 0; i < children.length; ++i) | |
145 this._removeBreakpointsForNode(children[i]); | |
146 this._saveBreakpoints(); | |
147 } | |
148 | |
149 /** | |
150 * @param {!SDK.DOMNode} node | |
151 */ | |
152 _removeBreakpointsForNode(node) { | |
153 for (var element of this._breakpointElements.values()) { | |
154 if (element._node === node) | |
155 this._removeBreakpoint(element._node, element._type); | |
156 } | |
157 } | |
158 | |
159 /** | |
160 * @param {!SDK.DOMNode} node | |
161 * @param {!Protocol.DOMDebugger.DOMBreakpointType} type | |
162 * @param {boolean} enabled | |
163 */ | |
164 _setBreakpoint(node, type, enabled) { | |
165 var breakpointId = this._createBreakpointId(node.id, type); | |
166 var breakpointElement = this._breakpointElements.get(breakpointId); | |
167 if (!breakpointElement) { | |
168 breakpointElement = this._createBreakpointElement(node, type, enabled); | |
169 this._breakpointElements.set(breakpointId, breakpointElement); | |
170 } else { | |
171 breakpointElement._checkboxElement.checked = enabled; | |
172 } | |
173 if (enabled) | |
174 node.domModel().target().domdebuggerAgent().setDOMBreakpoint(node.id, type
); | |
175 node.setMarker(Components.DOMBreakpointsSidebarPane.Marker, true); | |
176 } | |
177 | |
178 /** | |
179 * @param {!SDK.DOMNode} node | |
180 * @param {!Protocol.DOMDebugger.DOMBreakpointType} type | |
181 * @param {boolean} enabled | |
182 */ | |
183 _createBreakpointElement(node, type, enabled) { | |
184 var element = createElement('li'); | |
185 element._node = node; | |
186 element._type = type; | |
187 element.addEventListener('contextmenu', this._contextMenu.bind(this, node, t
ype), true); | |
188 | |
189 var checkboxLabel = UI.CheckboxLabel.create('', enabled); | |
190 var checkboxElement = checkboxLabel.checkboxElement; | 133 var checkboxElement = checkboxLabel.checkboxElement; |
191 checkboxElement.addEventListener('click', this._checkboxClicked.bind(this, n
ode, type), false); | 134 checkboxElement.addEventListener('click', this._checkboxClicked.bind(this, b
reakpoint), false); |
192 element._checkboxElement = checkboxElement; | |
193 element.appendChild(checkboxLabel); | 135 element.appendChild(checkboxLabel); |
194 | 136 |
195 var labelElement = createElementWithClass('div', 'dom-breakpoint'); | 137 var labelElement = createElementWithClass('div', 'dom-breakpoint'); |
196 element.appendChild(labelElement); | 138 element.appendChild(labelElement); |
197 | 139 |
198 var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(nod
e); | 140 var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(bre
akpoint.node); |
199 linkifiedNode.classList.add('monospace'); | 141 linkifiedNode.classList.add('monospace'); |
200 linkifiedNode.style.display = 'block'; | 142 linkifiedNode.style.display = 'block'; |
201 labelElement.appendChild(linkifiedNode); | 143 labelElement.appendChild(linkifiedNode); |
202 | 144 |
203 var description = createElement('div'); | 145 var description = createElement('div'); |
204 description.textContent = Components.DOMBreakpointsSidebarPane.BreakpointTyp
eLabels[type]; | 146 description.textContent = Components.DOMBreakpointsSidebarPane.BreakpointTyp
eLabels.get(breakpoint.type); |
205 labelElement.appendChild(description); | 147 labelElement.appendChild(description); |
206 | 148 |
| 149 var item = {breakpoint: breakpoint, element: element, checkbox: checkboxElem
ent}; |
| 150 element._item = item; |
| 151 this._items.set(breakpoint, item); |
| 152 |
207 var currentElement = this.listElement.firstChild; | 153 var currentElement = this.listElement.firstChild; |
208 while (currentElement) { | 154 while (currentElement) { |
209 if (currentElement._type && currentElement._type < element._type) | 155 if (currentElement._item && currentElement._item.breakpoint.type < breakpo
int.type) |
210 break; | 156 break; |
211 currentElement = currentElement.nextSibling; | 157 currentElement = currentElement.nextSibling; |
212 } | 158 } |
213 this.addListElement(element, currentElement); | 159 this.addListElement(element, currentElement); |
214 return element; | |
215 } | |
216 | |
217 _removeAllBreakpoints() { | |
218 for (var element of this._breakpointElements.values()) | |
219 this._removeBreakpoint(element._node, element._type); | |
220 this._saveBreakpoints(); | |
221 } | 160 } |
222 | 161 |
223 /** | 162 /** |
224 * @param {!SDK.DOMNode} node | 163 * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint |
225 * @param {!Protocol.DOMDebugger.DOMBreakpointType} type | |
226 */ | |
227 _removeBreakpoint(node, type) { | |
228 var breakpointId = this._createBreakpointId(node.id, type); | |
229 var element = this._breakpointElements.get(breakpointId); | |
230 if (!element) | |
231 return; | |
232 | |
233 this.removeListElement(element); | |
234 this._breakpointElements.delete(breakpointId); | |
235 if (element._checkboxElement.checked) | |
236 node.domModel().target().domdebuggerAgent().removeDOMBreakpoint(node.id, t
ype); | |
237 node.setMarker(Components.DOMBreakpointsSidebarPane.Marker, this.hasBreakpoi
nts(node) ? true : null); | |
238 } | |
239 | |
240 /** | |
241 * @param {!SDK.DOMNode} node | |
242 * @param {!Protocol.DOMDebugger.DOMBreakpointType} type | |
243 * @param {!Event} event | 164 * @param {!Event} event |
244 */ | 165 */ |
245 _contextMenu(node, type, event) { | 166 _contextMenu(breakpoint, event) { |
246 var contextMenu = new UI.ContextMenu(event); | 167 var contextMenu = new UI.ContextMenu(event); |
247 | 168 contextMenu.appendItem(Common.UIString.capitalize('Remove ^breakpoint'), ()
=> { |
248 /** | 169 breakpoint.domDebuggerModel.removeDOMBreakpoint(breakpoint.node, breakpoin
t.type); |
249 * @this {Components.DOMBreakpointsSidebarPane} | 170 }); |
250 */ | 171 contextMenu.appendItem(Common.UIString.capitalize('Remove ^all DOM breakpoin
ts'), () => { |
251 function removeBreakpoint() { | 172 breakpoint.domDebuggerModel.removeAllDOMBreakpoints(); |
252 this._removeBreakpoint(node, type); | 173 }); |
253 this._saveBreakpoints(); | |
254 } | |
255 contextMenu.appendItem(Common.UIString.capitalize('Remove ^breakpoint'), rem
oveBreakpoint.bind(this)); | |
256 contextMenu.appendItem( | |
257 Common.UIString.capitalize('Remove ^all DOM breakpoints'), this._removeA
llBreakpoints.bind(this)); | |
258 contextMenu.show(); | 174 contextMenu.show(); |
259 } | 175 } |
260 | 176 |
261 /** | 177 /** |
262 * @param {!SDK.DOMNode} node | 178 * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint |
263 * @param {!Protocol.DOMDebugger.DOMBreakpointType} type | |
264 * @param {!Event} event | |
265 */ | 179 */ |
266 _checkboxClicked(node, type, event) { | 180 _checkboxClicked(breakpoint) { |
267 if (event.target.checked) | 181 var item = this._items.get(breakpoint); |
268 node.domModel().target().domdebuggerAgent().setDOMBreakpoint(node.id, type
); | 182 if (!item) |
269 else | 183 return; |
270 node.domModel().target().domdebuggerAgent().removeDOMBreakpoint(node.id, t
ype); | 184 breakpoint.domDebuggerModel.toggleDOMBreakpoint(breakpoint, item.checkbox.ch
ecked); |
271 this._saveBreakpoints(); | |
272 } | 185 } |
273 | 186 |
274 /** | 187 /** |
275 * @override | 188 * @override |
276 * @param {?Object} object | 189 * @param {?Object} object |
277 */ | 190 */ |
278 flavorChanged(object) { | 191 flavorChanged(object) { |
279 this._update(); | 192 this._update(); |
280 } | 193 } |
281 | 194 |
282 _update() { | 195 _update() { |
283 var details = UI.context.flavor(SDK.DebuggerPausedDetails); | 196 var details = UI.context.flavor(SDK.DebuggerPausedDetails); |
284 if (!details || details.reason !== SDK.DebuggerModel.BreakReason.DOM) { | 197 if (!details || !details.auxData || details.reason !== SDK.DebuggerModel.Bre
akReason.DOM) { |
285 if (this._highlightedElement) { | 198 if (this._highlightedElement) { |
286 this._highlightedElement.classList.remove('breakpoint-hit'); | 199 this._highlightedElement.classList.remove('breakpoint-hit'); |
287 delete this._highlightedElement; | 200 delete this._highlightedElement; |
288 } | 201 } |
289 return; | 202 return; |
290 } | 203 } |
291 var auxData = details.auxData; | 204 var domDebuggerModel = details.debuggerModel.target().model(SDK.DOMDebuggerM
odel); |
292 var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type); | 205 if (!domDebuggerModel) |
293 var element = this._breakpointElements.get(breakpointId); | 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 } |
294 if (!element) | 216 if (!element) |
295 return; | 217 return; |
296 UI.viewManager.showView('sources.domBreakpoints'); | 218 UI.viewManager.showView('sources.domBreakpoints'); |
297 element.classList.add('breakpoint-hit'); | 219 element.classList.add('breakpoint-hit'); |
298 this._highlightedElement = element; | 220 this._highlightedElement = element; |
299 } | 221 } |
| 222 }; |
300 | 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 { |
301 /** | 243 /** |
302 * @param {number} nodeId | 244 * @override |
303 * @param {!Protocol.DOMDebugger.DOMBreakpointType} type | 245 * @param {!Event} event |
| 246 * @param {!UI.ContextMenu} contextMenu |
| 247 * @param {!Object} object |
304 */ | 248 */ |
305 _createBreakpointId(nodeId, type) { | 249 appendApplicableItems(event, contextMenu, object) { |
306 return nodeId + ':' + type; | 250 var node = /** @type {!SDK.DOMNode} */ (object); |
307 } | 251 if (node.pseudoType()) |
308 | 252 return; |
309 _saveBreakpoints() { | 253 var domDebuggerModel = node.domModel().target().model(SDK.DOMDebuggerModel); |
310 var breakpoints = []; | 254 if (!domDebuggerModel) |
311 var storedBreakpoints = this._domBreakpointsSetting.get(); | 255 return; |
312 for (var i = 0; i < storedBreakpoints.length; ++i) { | |
313 var breakpoint = storedBreakpoints[i]; | |
314 if (breakpoint.url !== this._inspectedURL) | |
315 breakpoints.push(breakpoint); | |
316 } | |
317 for (var element of this._breakpointElements.values()) { | |
318 breakpoints.push({ | |
319 url: this._inspectedURL, | |
320 path: element._node.path(), | |
321 type: element._type, | |
322 enabled: element._checkboxElement.checked | |
323 }); | |
324 } | |
325 this._domBreakpointsSetting.set(breakpoints); | |
326 } | |
327 | |
328 /** | |
329 * @param {!SDK.DOMDocument} domDocument | |
330 */ | |
331 restoreBreakpoints(domDocument) { | |
332 this._breakpointElements.clear(); | |
333 this.reset(); | |
334 this._inspectedURL = domDocument.documentURL; | |
335 var domModel = domDocument.domModel(); | |
336 /** @type {!Map<string, !Array<!Object>>} */ | |
337 var pathToBreakpoints = new Map(); | |
338 | 256 |
339 /** | 257 /** |
340 * @param {string} path | 258 * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type |
341 * @param {?Protocol.DOM.NodeId} nodeId | |
342 * @this {Components.DOMBreakpointsSidebarPane} | |
343 */ | 259 */ |
344 function didPushNodeByPathToFrontend(path, nodeId) { | 260 function toggleBreakpoint(type) { |
345 var node = nodeId ? domModel.nodeForId(nodeId) : null; | 261 if (domDebuggerModel.hasDOMBreakpoint(node, type)) |
346 if (!node) | 262 domDebuggerModel.removeDOMBreakpoint(node, type); |
347 return; | 263 else |
348 | 264 domDebuggerModel.setDOMBreakpoint(node, type); |
349 var breakpoints = pathToBreakpoints.get(path); | |
350 for (var i = 0; i < breakpoints.length; ++i) | |
351 this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled); | |
352 } | 265 } |
353 | 266 |
354 var breakpoints = this._domBreakpointsSetting.get(); | 267 var breakpointsMenu = contextMenu.appendSubMenuItem(Common.UIString('Break o
n...')); |
355 for (var i = 0; i < breakpoints.length; ++i) { | 268 for (var key in SDK.DOMDebuggerModel.DOMBreakpoint.Type) { |
356 var breakpoint = breakpoints[i]; | 269 var type = SDK.DOMDebuggerModel.DOMBreakpoint.Type[key]; |
357 if (breakpoint.url !== this._inspectedURL) | 270 var label = Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns.get(t
ype); |
358 continue; | 271 breakpointsMenu.appendCheckboxItem( |
359 var path = breakpoint.path; | 272 label, toggleBreakpoint.bind(null, type), domDebuggerModel.hasDOMBreak
point(node, type)); |
360 if (!pathToBreakpoints.has(path)) { | |
361 pathToBreakpoints.set(path, []); | |
362 domModel.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind
(this, path)); | |
363 } | |
364 pathToBreakpoints.get(path).push(breakpoint); | |
365 } | 273 } |
366 } | 274 } |
367 }; | 275 }; |
368 | |
369 Components.DOMBreakpointsSidebarPane.BreakpointTypes = { | |
370 SubtreeModified: 'subtree-modified', | |
371 AttributeModified: 'attribute-modified', | |
372 NodeRemoved: 'node-removed' | |
373 }; | |
374 | |
375 Components.DOMBreakpointsSidebarPane.BreakpointTypeLabels = { | |
376 'subtree-modified': Common.UIString('Subtree Modified'), | |
377 'attribute-modified': Common.UIString('Attribute Modified'), | |
378 'node-removed': Common.UIString('Node Removed') | |
379 }; | |
380 | |
381 Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns = { | |
382 'subtree-modified': Common.UIString('subtree modifications'), | |
383 'attribute-modified': Common.UIString('attribute modifications'), | |
384 'node-removed': Common.UIString('node removal') | |
385 }; | |
386 | |
387 Components.DOMBreakpointsSidebarPane.Marker = 'breakpoint-marker'; | |
388 | |
389 | |
390 /** | |
391 * @unrestricted | |
392 */ | |
393 Components.DOMBreakpointsSidebarPane.Proxy = class extends UI.VBox { | |
394 constructor() { | |
395 super(); | |
396 this.registerRequiredCSS('components/breakpointsList.css'); | |
397 } | |
398 | |
399 /** | |
400 * @override | |
401 */ | |
402 wasShown() { | |
403 super.wasShown(); | |
404 var pane = Components.domBreakpointsSidebarPane; | |
405 if (pane.element.parentNode !== this.element) | |
406 pane.show(this.element); | |
407 } | |
408 }; | |
409 | |
410 /** | |
411 * @type {!Components.DOMBreakpointsSidebarPane} | |
412 */ | |
413 Components.domBreakpointsSidebarPane; | |
OLD | NEW |