| 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 |