OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * @constructor |
| 7 * @extends {WebInspector.SidebarPane} |
| 8 * @implements {WebInspector.TargetManager.Observer} |
| 9 */ |
| 10 WebInspector.EventListenerBreakpointsSidebarPane = function() |
| 11 { |
| 12 WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Br
eakpoints")); |
| 13 this.registerRequiredCSS("components/breakpointsList.css"); |
| 14 |
| 15 this._categoriesTreeOutline = new TreeOutline(); |
| 16 this._categoriesTreeOutline.element.tabIndex = 0; |
| 17 this._categoriesTreeOutline.element.classList.add("event-listener-breakpoint
s"); |
| 18 this.bodyElement.appendChild(this._categoriesTreeOutline.element); |
| 19 |
| 20 this._categoryItems = []; |
| 21 // FIXME: uncomment following once inspector stops being drop targer in majo
r ports. |
| 22 // Otherwise, inspector page reacts on drop event and tries to load the even
t data. |
| 23 // this._createCategory(WebInspector.UIString("Drag"), ["drag", "drop", "dra
gstart", "dragend", "dragenter", "dragleave", "dragover"]); |
| 24 this._createCategory(WebInspector.UIString("Animation"), ["requestAnimationF
rame", "cancelAnimationFrame", "animationFrameFired"], true); |
| 25 this._createCategory(WebInspector.UIString("Control"), ["resize", "scroll",
"zoom", "focus", "blur", "select", "change", "submit", "reset"]); |
| 26 this._createCategory(WebInspector.UIString("Clipboard"), ["copy", "cut", "pa
ste", "beforecopy", "beforecut", "beforepaste"]); |
| 27 this._createCategory(WebInspector.UIString("DOM Mutation"), ["DOMActivate",
"DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOM
NodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedF
romDocument", "DOMSubtreeModified", "DOMContentLoaded"]); |
| 28 this._createCategory(WebInspector.UIString("Device"), ["deviceorientation",
"devicemotion"]); |
| 29 this._createCategory(WebInspector.UIString("Drag / drop"), ["dragenter", "dr
agover", "dragleave", "drop"]); |
| 30 this._createCategory(WebInspector.UIString("Keyboard"), ["keydown", "keyup",
"keypress", "input"]); |
| 31 this._createCategory(WebInspector.UIString("Load"), ["load", "beforeunload",
"unload", "abort", "error", "hashchange", "popstate"]); |
| 32 this._createCategory(WebInspector.UIString("Media"), ["play", "pause", "play
ing", "canplay", "canplaythrough", "seeking", "seeked", "timeupdate", "ended", "
ratechange", "durationchange", "volumechange", "loadstart", "progress", "suspend
", "abort", "error", "emptied", "stalled", "loadedmetadata", "loadeddata", "wait
ing"], false, ["audio", "video"]); |
| 33 this._createCategory(WebInspector.UIString("Mouse"), ["click", "dblclick", "
mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mouseenter", "mous
eleave", "mousewheel", "wheel", "contextmenu"]); |
| 34 this._createCategory(WebInspector.UIString("Promise"), ["newPromise", "promi
seResolved", "promiseRejected"], true); |
| 35 this._createCategory(WebInspector.UIString("Script"), ["scriptFirstStatement
"], true); |
| 36 this._createCategory(WebInspector.UIString("Timer"), ["setTimer", "clearTime
r", "timerFired"], true); |
| 37 this._createCategory(WebInspector.UIString("Touch"), ["touchstart", "touchmo
ve", "touchend", "touchcancel"]); |
| 38 this._createCategory(WebInspector.UIString("XHR"), ["readystatechange", "loa
d", "loadstart", "loadend", "abort", "error", "progress", "timeout"], false, ["X
MLHttpRequest", "XMLHttpRequestUpload"]); |
| 39 this._createCategory(WebInspector.UIString("WebGL"), ["webglErrorFired", "we
bglWarningFired"], true); |
| 40 this._createCategory(WebInspector.UIString("Window"), ["close"], true); |
| 41 |
| 42 WebInspector.targetManager.observeTargets(this); |
| 43 } |
| 44 |
| 45 WebInspector.EventListenerBreakpointsSidebarPane.categoryListener = "listener:"; |
| 46 WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation = "inst
rumentation:"; |
| 47 WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny = "*"; |
| 48 |
| 49 /** |
| 50 * @param {string} eventName |
| 51 * @param {!Object=} auxData |
| 52 * @return {string} |
| 53 */ |
| 54 WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI = function(event
Name, auxData) |
| 55 { |
| 56 if (!WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI) { |
| 57 WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI = { |
| 58 "instrumentation:setTimer": WebInspector.UIString("Set Timer"), |
| 59 "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"), |
| 60 "instrumentation:timerFired": WebInspector.UIString("Timer Fired"), |
| 61 "instrumentation:newPromise": WebInspector.UIString("Promise Created
"), |
| 62 "instrumentation:promiseResolved": WebInspector.UIString("Promise Re
solved"), |
| 63 "instrumentation:promiseRejected": WebInspector.UIString("Promise Re
jected"), |
| 64 "instrumentation:scriptFirstStatement": WebInspector.UIString("Scrip
t First Statement"), |
| 65 "instrumentation:requestAnimationFrame": WebInspector.UIString("Requ
est Animation Frame"), |
| 66 "instrumentation:cancelAnimationFrame": WebInspector.UIString("Cance
l Animation Frame"), |
| 67 "instrumentation:animationFrameFired": WebInspector.UIString("Animat
ion Frame Fired"), |
| 68 "instrumentation:webglErrorFired": WebInspector.UIString("WebGL Erro
r Fired"), |
| 69 "instrumentation:webglWarningFired": WebInspector.UIString("WebGL Wa
rning Fired") |
| 70 }; |
| 71 } |
| 72 if (auxData) { |
| 73 if (eventName === "instrumentation:webglErrorFired" && auxData["webglErr
orName"]) { |
| 74 var errorName = auxData["webglErrorName"]; |
| 75 // If there is a hex code of the error, display only this. |
| 76 errorName = errorName.replace(/^.*(0x[0-9a-f]+).*$/i, "$1"); |
| 77 return WebInspector.UIString("WebGL Error Fired (%s)", errorName); |
| 78 } |
| 79 } |
| 80 return WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI[eve
ntName] || eventName.substring(eventName.indexOf(":") + 1); |
| 81 } |
| 82 |
| 83 WebInspector.EventListenerBreakpointsSidebarPane.prototype = { |
| 84 /** |
| 85 * @override |
| 86 * @param {!WebInspector.Target} target |
| 87 */ |
| 88 targetAdded: function(target) |
| 89 { |
| 90 this._restoreBreakpoints(target); |
| 91 }, |
| 92 |
| 93 /** |
| 94 * @override |
| 95 * @param {!WebInspector.Target} target |
| 96 */ |
| 97 targetRemoved: function(target) { }, |
| 98 |
| 99 /** |
| 100 * @param {string} name |
| 101 * @param {!Array.<string>} eventNames |
| 102 * @param {boolean=} isInstrumentationEvent |
| 103 * @param {!Array.<string>=} targetNames |
| 104 */ |
| 105 _createCategory: function(name, eventNames, isInstrumentationEvent, targetNa
mes) |
| 106 { |
| 107 var labelNode = createCheckboxLabel(name); |
| 108 |
| 109 var categoryItem = {}; |
| 110 categoryItem.element = new TreeElement(labelNode); |
| 111 this._categoriesTreeOutline.appendChild(categoryItem.element); |
| 112 categoryItem.element.listItemElement.classList.add("event-category"); |
| 113 categoryItem.element.selectable = true; |
| 114 |
| 115 categoryItem.checkbox = labelNode.checkboxElement; |
| 116 categoryItem.checkbox.addEventListener("click", this._categoryCheckboxCl
icked.bind(this, categoryItem), true); |
| 117 |
| 118 categoryItem.targetNames = this._stringArrayToLowerCase(targetNames || [
WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny]); |
| 119 categoryItem.children = {}; |
| 120 var category = (isInstrumentationEvent ? WebInspector.EventListenerBreak
pointsSidebarPane.categoryInstrumentation : WebInspector.EventListenerBreakpoin
tsSidebarPane.categoryListener); |
| 121 for (var i = 0; i < eventNames.length; ++i) { |
| 122 var eventName = category + eventNames[i]; |
| 123 |
| 124 var breakpointItem = {}; |
| 125 var title = WebInspector.EventListenerBreakpointsSidebarPane.eventNa
meForUI(eventName); |
| 126 |
| 127 labelNode = createCheckboxLabel(title); |
| 128 labelNode.classList.add("source-code"); |
| 129 |
| 130 breakpointItem.element = new TreeElement(labelNode); |
| 131 categoryItem.element.appendChild(breakpointItem.element); |
| 132 |
| 133 breakpointItem.element.listItemElement.createChild("div", "breakpoin
t-hit-marker"); |
| 134 breakpointItem.element.selectable = false; |
| 135 |
| 136 breakpointItem.checkbox = labelNode.checkboxElement; |
| 137 breakpointItem.checkbox.addEventListener("click", this._breakpointCh
eckboxClicked.bind(this, eventName, categoryItem.targetNames), true); |
| 138 breakpointItem.parent = categoryItem; |
| 139 |
| 140 categoryItem.children[eventName] = breakpointItem; |
| 141 } |
| 142 this._categoryItems.push(categoryItem); |
| 143 }, |
| 144 |
| 145 /** |
| 146 * @param {!Array.<string>} array |
| 147 * @return {!Array.<string>} |
| 148 */ |
| 149 _stringArrayToLowerCase: function(array) |
| 150 { |
| 151 return array.map(function(value) { |
| 152 return value.toLowerCase(); |
| 153 }); |
| 154 }, |
| 155 |
| 156 _categoryCheckboxClicked: function(categoryItem) |
| 157 { |
| 158 var checked = categoryItem.checkbox.checked; |
| 159 for (var eventName in categoryItem.children) { |
| 160 var breakpointItem = categoryItem.children[eventName]; |
| 161 if (breakpointItem.checkbox.checked === checked) |
| 162 continue; |
| 163 if (checked) |
| 164 this._setBreakpoint(eventName, categoryItem.targetNames); |
| 165 else |
| 166 this._removeBreakpoint(eventName, categoryItem.targetNames); |
| 167 } |
| 168 this._saveBreakpoints(); |
| 169 }, |
| 170 |
| 171 /** |
| 172 * @param {string} eventName |
| 173 * @param {!Array.<string>} targetNames |
| 174 * @param {!Event} event |
| 175 */ |
| 176 _breakpointCheckboxClicked: function(eventName, targetNames, event) |
| 177 { |
| 178 if (event.target.checked) |
| 179 this._setBreakpoint(eventName, targetNames); |
| 180 else |
| 181 this._removeBreakpoint(eventName, targetNames); |
| 182 this._saveBreakpoints(); |
| 183 }, |
| 184 |
| 185 /** |
| 186 * @param {string} eventName |
| 187 * @param {?Array.<string>=} eventTargetNames |
| 188 * @param {!WebInspector.Target=} target |
| 189 */ |
| 190 _setBreakpoint: function(eventName, eventTargetNames, target) |
| 191 { |
| 192 eventTargetNames = eventTargetNames || [WebInspector.EventListenerBreakp
ointsSidebarPane.eventTargetAny]; |
| 193 for (var i = 0; i < eventTargetNames.length; ++i) { |
| 194 var eventTargetName = eventTargetNames[i]; |
| 195 var breakpointItem = this._findBreakpointItem(eventName, eventTarget
Name); |
| 196 if (!breakpointItem) |
| 197 continue; |
| 198 breakpointItem.checkbox.checked = true; |
| 199 breakpointItem.parent.dirtyCheckbox = true; |
| 200 this._updateBreakpointOnTarget(eventName, eventTargetName, true, tar
get); |
| 201 } |
| 202 this._updateCategoryCheckboxes(); |
| 203 }, |
| 204 |
| 205 /** |
| 206 * @param {string} eventName |
| 207 * @param {?Array.<string>=} eventTargetNames |
| 208 * @param {!WebInspector.Target=} target |
| 209 */ |
| 210 _removeBreakpoint: function(eventName, eventTargetNames, target) |
| 211 { |
| 212 eventTargetNames = eventTargetNames || [WebInspector.EventListenerBreakp
ointsSidebarPane.eventTargetAny]; |
| 213 for (var i = 0; i < eventTargetNames.length; ++i) { |
| 214 var eventTargetName = eventTargetNames[i]; |
| 215 var breakpointItem = this._findBreakpointItem(eventName, eventTarget
Name); |
| 216 if (!breakpointItem) |
| 217 continue; |
| 218 breakpointItem.checkbox.checked = false; |
| 219 breakpointItem.parent.dirtyCheckbox = true; |
| 220 this._updateBreakpointOnTarget(eventName, eventTargetName, false, ta
rget); |
| 221 } |
| 222 this._updateCategoryCheckboxes(); |
| 223 }, |
| 224 |
| 225 /** |
| 226 * @param {string} eventName |
| 227 * @param {string} eventTargetName |
| 228 * @param {boolean} enable |
| 229 * @param {!WebInspector.Target=} target |
| 230 */ |
| 231 _updateBreakpointOnTarget: function(eventName, eventTargetName, enable, targ
et) |
| 232 { |
| 233 var targets = target ? [target] : WebInspector.targetManager.targets(); |
| 234 for (var i = 0; i < targets.length; ++i) { |
| 235 if (eventName.startsWith(WebInspector.EventListenerBreakpointsSideba
rPane.categoryListener)) { |
| 236 var protocolEventName = eventName.substring(WebInspector.EventLi
stenerBreakpointsSidebarPane.categoryListener.length); |
| 237 if (enable) |
| 238 targets[i].domdebuggerAgent().setEventListenerBreakpoint(pro
tocolEventName, eventTargetName); |
| 239 else |
| 240 targets[i].domdebuggerAgent().removeEventListenerBreakpoint(
protocolEventName, eventTargetName); |
| 241 } else if (eventName.startsWith(WebInspector.EventListenerBreakpoint
sSidebarPane.categoryInstrumentation)) { |
| 242 var protocolEventName = eventName.substring(WebInspector.EventLi
stenerBreakpointsSidebarPane.categoryInstrumentation.length); |
| 243 if (enable) |
| 244 targets[i].domdebuggerAgent().setInstrumentationBreakpoint(p
rotocolEventName); |
| 245 else |
| 246 targets[i].domdebuggerAgent().removeInstrumentationBreakpoin
t(protocolEventName); |
| 247 } |
| 248 } |
| 249 }, |
| 250 |
| 251 _updateCategoryCheckboxes: function() |
| 252 { |
| 253 for (var i = 0; i < this._categoryItems.length; ++i) { |
| 254 var categoryItem = this._categoryItems[i]; |
| 255 if (!categoryItem.dirtyCheckbox) |
| 256 continue; |
| 257 categoryItem.dirtyCheckbox = false; |
| 258 var hasEnabled = false; |
| 259 var hasDisabled = false; |
| 260 for (var eventName in categoryItem.children) { |
| 261 var breakpointItem = categoryItem.children[eventName]; |
| 262 if (breakpointItem.checkbox.checked) |
| 263 hasEnabled = true; |
| 264 else |
| 265 hasDisabled = true; |
| 266 } |
| 267 categoryItem.checkbox.checked = hasEnabled; |
| 268 categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled; |
| 269 } |
| 270 }, |
| 271 |
| 272 /** |
| 273 * @param {string} eventName |
| 274 * @param {string=} targetName |
| 275 * @return {?Object} |
| 276 */ |
| 277 _findBreakpointItem: function(eventName, targetName) |
| 278 { |
| 279 targetName = (targetName || WebInspector.EventListenerBreakpointsSidebar
Pane.eventTargetAny).toLowerCase(); |
| 280 for (var i = 0; i < this._categoryItems.length; ++i) { |
| 281 var categoryItem = this._categoryItems[i]; |
| 282 if (categoryItem.targetNames.indexOf(targetName) === -1) |
| 283 continue; |
| 284 var breakpointItem = categoryItem.children[eventName]; |
| 285 if (breakpointItem) |
| 286 return breakpointItem; |
| 287 } |
| 288 return null; |
| 289 }, |
| 290 |
| 291 /** |
| 292 * @param {string} eventName |
| 293 * @param {string=} targetName |
| 294 */ |
| 295 highlightBreakpoint: function(eventName, targetName) |
| 296 { |
| 297 var breakpointItem = this._findBreakpointItem(eventName, targetName); |
| 298 if (!breakpointItem || !breakpointItem.checkbox.checked) |
| 299 breakpointItem = this._findBreakpointItem(eventName, WebInspector.Ev
entListenerBreakpointsSidebarPane.eventTargetAny); |
| 300 if (!breakpointItem) |
| 301 return; |
| 302 this.expand(); |
| 303 breakpointItem.parent.element.expand(); |
| 304 breakpointItem.element.listItemElement.classList.add("breakpoint-hit"); |
| 305 this._highlightedElement = breakpointItem.element.listItemElement; |
| 306 }, |
| 307 |
| 308 clearBreakpointHighlight: function() |
| 309 { |
| 310 if (this._highlightedElement) { |
| 311 this._highlightedElement.classList.remove("breakpoint-hit"); |
| 312 delete this._highlightedElement; |
| 313 } |
| 314 }, |
| 315 |
| 316 _saveBreakpoints: function() |
| 317 { |
| 318 var breakpoints = []; |
| 319 for (var i = 0; i < this._categoryItems.length; ++i) { |
| 320 var categoryItem = this._categoryItems[i]; |
| 321 for (var eventName in categoryItem.children) { |
| 322 var breakpointItem = categoryItem.children[eventName]; |
| 323 if (breakpointItem.checkbox.checked) |
| 324 breakpoints.push({ eventName: eventName, targetNames: catego
ryItem.targetNames }); |
| 325 } |
| 326 } |
| 327 WebInspector.settings.eventListenerBreakpoints.set(breakpoints); |
| 328 }, |
| 329 |
| 330 /** |
| 331 * @param {!WebInspector.Target} target |
| 332 */ |
| 333 _restoreBreakpoints: function(target) |
| 334 { |
| 335 var breakpoints = WebInspector.settings.eventListenerBreakpoints.get(); |
| 336 for (var i = 0; i < breakpoints.length; ++i) { |
| 337 var breakpoint = breakpoints[i]; |
| 338 if (breakpoint && typeof breakpoint.eventName === "string") |
| 339 this._setBreakpoint(breakpoint.eventName, breakpoint.targetNames
, target); |
| 340 } |
| 341 }, |
| 342 |
| 343 __proto__: WebInspector.SidebarPane.prototype |
| 344 } |
OLD | NEW |