1 /* 2 * Copyright (C) 2008 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. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 /** 27 * @constructor 28 * @param {!WebInspector.BreakpointManager} breakpointManager 29 * @extends {WebInspector.SidebarPane} 30 */ 31 WebInspector.JavaScriptBreakpointsSidebarPane = function(breakpointManager, showSourceLineDelegate) 32 { 33 WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints")); 34 this.registerRequiredCSS("breakpointsList.css"); 35 36 this._breakpointManager = breakpointManager; 37 this._showSourceLineDelegate = showSourceLineDelegate; 38 39 this.listElement = document.createElement("ol"); 40 this.listElement.className = "breakpoint-list"; 41 42 this.emptyElement = document.createElement("div"); 43 this.emptyElement.className = "info"; 44 this.emptyElement.textContent = WebInspector.UIString("No Breakpoints"); 45 46 this.bodyElement.appendChild(this.emptyElement); 47 48 this._items = new Map(); 49 50 var breakpointLocations = this._breakpointManager.allBreakpointLocations(); 51 for (var i = 0; i < breakpointLocations.length; ++i) 52 this._addBreakpoint(breakpointLocations[i].breakpoint, breakpointLocations[i].uiLocation); 53 54 this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this); 55 this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this); 56 57 this.emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true); 58 } 59 60 WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { 61 _emptyElementContextMenu: function(event) 62 { 63 var contextMenu = new WebInspector.ContextMenu(event); 64 var breakpointActive = WebInspector.debuggerModel.breakpointsActive(); 65 var breakpointActiveTitle = breakpointActive ? 66 WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Deactivate breakpoints" : "Deactivate Breakpoints") : 67 WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Activate breakpoints" : "Activate Breakpoints"); 68 contextMenu.appendItem(breakpointActiveTitle, WebInspector.debuggerModel.setBreakpointsActive.bind(WebInspector.debuggerModel, !breakpointActive)); 69 contextMenu.show(); 70 }, 71 72 /** 73 * @param {!WebInspector.Event} event 74 */ 75 _breakpointAdded: function(event) 76 { 77 this._breakpointRemoved(event); 78 79 var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint); 80 var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocation); 81 this._addBreakpoint(breakpoint, uiLocation); 82 }, 83 84 /** 85 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint 86 * @param {!WebInspector.UILocation} uiLocation 87 */ 88 _addBreakpoint: function(breakpoint, uiLocation) 89 { 90 var element = document.createElement("li"); 91 element.classList.add("cursor-pointer"); 92 element.addEventListener("contextmenu", this._breakpointContextMenu.bind(this, breakpoint), true); 93 element.addEventListener("click", this._breakpointClicked.bind(this, uiLocation), false); 94 95 var checkbox = document.createElement("input"); 96 checkbox.className = "checkbox-elem"; 97 checkbox.type = "checkbox"; 98 checkbox.checked = breakpoint.enabled(); 99 checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, breakpoint), false); 100 element.appendChild(checkbox); 101 102 var labelElement = document.createTextNode(uiLocation.linkText()); 103 element.appendChild(labelElement); 104 105 var snippetElement = document.createElement("div"); 106 snippetElement.className = "source-text monospace"; 107 element.appendChild(snippetElement); 108 109 /** 110 * @param {?string} content 111 */ 112 function didRequestContent(content) 113 { 114 var lineEndings = content.lineEndings(); 115 if (uiLocation.lineNumber < lineEndings.length) 116 snippetElement.textContent = content.substring(lineEndings[uiLocation.lineNumber - 1], lineEndings[uiLocation.lineNumber]); 117 } 118 uiLocation.uiSourceCode.requestContent(didRequestContent.bind(this)); 119 120 element._data = uiLocation; 121 var currentElement = this.listElement.firstChild; 122 while (currentElement) { 123 if (currentElement._data && this._compareBreakpoints(currentElement._data, element._data) > 0) 124 break; 125 currentElement = currentElement.nextSibling; 126 } 127 this._addListElement(element, currentElement); 128 129 var breakpointItem = {}; 130 breakpointItem.element = element; 131 breakpointItem.checkbox = checkbox; 132 this._items.put(breakpoint, breakpointItem); 133 134 this.expand(); 135 }, 136 137 /** 138 * @param {!WebInspector.Event} event 139 */ 140 _breakpointRemoved: function(event) 141 { 142 var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint); 143 var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiLocation); 144 var breakpointItem = this._items.get(breakpoint); 145 if (!breakpointItem) 146 return; 147 this._items.remove(breakpoint); 148 this._removeListElement(breakpointItem.element); 149 }, 150 151 /** 152 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint 153 */ 154 highlightBreakpoint: function(breakpoint) 155 { 156 var breakpointItem = this._items.get(breakpoint); 157 if (!breakpointItem) 158 return; 159 breakpointItem.element.classList.add("breakpoint-hit"); 160 this._highlightedBreakpointItem = breakpointItem; 161 }, 162 163 clearBreakpointHighlight: function() 164 { 165 if (this._highlightedBreakpointItem) { 166 this._highlightedBreakpointItem.element.classList.remove("breakpoint-hit"); 167 delete this._highlightedBreakpointItem; 168 } 169 }, 170 171 _breakpointClicked: function(uiLocation, event) 172 { 173 this._showSourceLineDelegate(uiLocation.uiSourceCode, uiLocation.lineNumber); 174 }, 175 176 /** 177 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint 178 */ 179 _breakpointCheckboxClicked: function(breakpoint, event) 180 { 181 // Breakpoint element has it's own click handler. 182 event.consume(); 183 breakpoint.setEnabled(event.target.checked); 184 }, 185 186 /** 187 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint 188 */ 189 _breakpointContextMenu: function(breakpoint, event) 190 { 191 var breakpoints = this._items.values(); 192 var contextMenu = new WebInspector.ContextMenu(event); 193 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove breakpoint" : "Remove Breakpoint"), breakpoint.remove.bind(breakpoint)); 194 if (breakpoints.length > 1) { 195 var removeAllTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all breakpoints" : "Remove All Breakpoints"); 196 contextMenu.appendItem(removeAllTitle, this._breakpointManager.removeAllBreakpoints.bind(this._breakpointManager)); 197 } 198 199 contextMenu.appendSeparator(); 200 var breakpointActive = WebInspector.debuggerModel.breakpointsActive(); 201 var breakpointActiveTitle = breakpointActive ? 202 WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Deactivate breakpoints" : "Deactivate Breakpoints") : 203 WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Activate breakpoints" : "Activate Breakpoints"); 204 contextMenu.appendItem(breakpointActiveTitle, WebInspector.debuggerModel.setBreakpointsActive.bind(WebInspector.debuggerModel, !breakpointActive)); 205 206 function enabledBreakpointCount(breakpoints) 207 { 208 var count = 0; 209 for (var i = 0; i < breakpoints.length; ++i) { 210 if (breakpoints[i].checkbox.checked) 211 count++; 212 } 213 return count; 214 } 215 if (breakpoints.length > 1) { 216 var enableBreakpointCount = enabledBreakpointCount(breakpoints); 217 var enableTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Enable all breakpoints" : "Enable All Breakpoints"); 218 var disableTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Disable all breakpoints" : "Disable All Breakpoints"); 219 220 contextMenu.appendSeparator(); 221 222 contextMenu.appendItem(enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true), !(enableBreakpointCount != breakpoints.length)); 223 contextMenu.appendItem(disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, false), !(enableBreakpointCount > 1)); 224 } 225 226 contextMenu.show(); 227 }, 228 229 _addListElement: function(element, beforeElement) 230 { 231 if (beforeElement) 232 this.listElement.insertBefore(element, beforeElement); 233 else { 234 if (!this.listElement.firstChild) { 235 this.bodyElement.removeChild(this.emptyElement); 236 this.bodyElement.appendChild(this.listElement); 237 } 238 this.listElement.appendChild(element); 239 } 240 }, 241 242 _removeListElement: function(element) 243 { 244 this.listElement.removeChild(element); 245 if (!this.listElement.firstChild) { 246 this.bodyElement.removeChild(this.listElement); 247 this.bodyElement.appendChild(this.emptyElement); 248 } 249 }, 250 251 _compare: function(x, y) 252 { 253 if (x !== y) 254 return x < y ? -1 : 1; 255 return 0; 256 }, 257 258 _compareBreakpoints: function(b1, b2) 259 { 260 return this._compare(b1.uiSourceCode.originURL(), b2.uiSourceCode.originURL()) || this._compare(b1.lineNumber, b2.lineNumber); 261 }, 262 263 reset: function() 264 { 265 this.listElement.removeChildren(); 266 if (this.listElement.parentElement) { 267 this.bodyElement.removeChild(this.listElement); 268 this.bodyElement.appendChild(this.emptyElement); 269 } 270 this._items.clear(); 271 }, 272 273 __proto__: WebInspector.SidebarPane.prototype 274 } 275 276 /** 277 * @constructor 278 * @extends {WebInspector.NativeBreakpointsSidebarPane} 279 */ 280 WebInspector.XHRBreakpointsSidebarPane = function() 281 { 282 WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints")); 283 284 this._breakpointElements = {}; 285 286 var addButton = document.createElement("button"); 287 addButton.className = "pane-title-button add"; 288 addButton.addEventListener("click", this._addButtonClicked.bind(this), false); 289 addButton.title = WebInspector.UIString("Add XHR breakpoint"); 290 this.titleElement.appendChild(addButton); 291 292 this.emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true); 293 294 this._restoreBreakpoints(); 295 } 296 297 WebInspector.XHRBreakpointsSidebarPane.prototype = { 298 _emptyElementContextMenu: function(event) 299 { 300 var contextMenu = new WebInspector.ContextMenu(event); 301 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add breakpoint" : "Add Breakpoint"), this._addButtonClicked.bind(this)); 302 contextMenu.show(); 303 }, 304 305 _addButtonClicked: function(event) 306 { 307 if (event) 308 event.consume(); 309 310 this.expand(); 311 312 var inputElementContainer = document.createElement("p"); 313 inputElementContainer.className = "breakpoint-condition"; 314 var inputElement = document.createElement("span"); 315 inputElementContainer.textContent = WebInspector.UIString("Break when URL contains:"); 316 inputElement.className = "editing"; 317 inputElement.id = "breakpoint-condition-input"; 318 inputElementContainer.appendChild(inputElement); 319 this._addListElement(inputElementContainer, this.listElement.firstChild); 320 321 /** 322 * @param {boolean} accept 323 * @param {!Element} e 324 * @param {string} text 325 * @this {WebInspector.XHRBreakpointsSidebarPane} 326 */ 327 function finishEditing(accept, e, text) 328 { 329 this._removeListElement(inputElementContainer); 330 if (accept) { 331 this._setBreakpoint(text, true); 332 this._saveBreakpoints(); 333 } 334 } 335 336 var config = new WebInspector.EditingConfig(finishEditing.bind(this, true), finishEditing.bind(this, false)); 337 WebInspector.startEditing(inputElement, config); 338 }, 339 340 _setBreakpoint: function(url, enabled) 341 { 342 if (url in this._breakpointElements) 343 return; 344 345 var element = document.createElement("li"); 346 element._url = url; 347 element.addEventListener("contextmenu", this._contextMenu.bind(this, url), true); 348 349 var checkboxElement = document.createElement("input"); 350 checkboxElement.className = "checkbox-elem"; 351 checkboxElement.type = "checkbox"; 352 checkboxElement.checked = enabled; 353 checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, url), false); 354 element._checkboxElement = checkboxElement; 355 element.appendChild(checkboxElement); 356 357 var labelElement = document.createElement("span"); 358 if (!url) 359 labelElement.textContent = WebInspector.UIString("Any XHR"); 360 else 361 labelElement.textContent = WebInspector.UIString("URL contains \"%s\"", url); 362 labelElement.classList.add("cursor-auto"); 363 labelElement.addEventListener("dblclick", this._labelClicked.bind(this, url), false); 364 element.appendChild(labelElement); 365 366 var currentElement = this.listElement.firstChild; 367 while (currentElement) { 368 if (currentElement._url && currentElement._url < element._url) 369 break; 370 currentElement = currentElement.nextSibling; 371 } 372 this._addListElement(element, currentElement); 373 this._breakpointElements[url] = element; 374 if (enabled) 375 DOMDebuggerAgent.setXHRBreakpoint(url); 376 }, 377 378 _removeBreakpoint: function(url) 379 { 380 var element = this._breakpointElements[url]; 381 if (!element) 382 return; 383 384 this._removeListElement(element); 385 delete this._breakpointElements[url]; 386 if (element._checkboxElement.checked) 387 DOMDebuggerAgent.removeXHRBreakpoint(url); 388 }, 389 390 _contextMenu: function(url, event) 391 { 392 var contextMenu = new WebInspector.ContextMenu(event); 393 394 /** 395 * @this {WebInspector.XHRBreakpointsSidebarPane} 396 */ 397 function removeBreakpoint() 398 { 399 this._removeBreakpoint(url); 400 this._saveBreakpoints(); 401 } 402 403 /** 404 * @this {WebInspector.XHRBreakpointsSidebarPane} 405 */ 406 function removeAllBreakpoints() 407 { 408 for (var url in this._breakpointElements) 409 this._removeBreakpoint(url); 410 this._saveBreakpoints(); 411 } 412 var removeAllTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all breakpoints" : "Remove All Breakpoints"); 413 414 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add breakpoint" : "Add Breakpoint"), this._addButtonClicked.bind(this)); 415 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove breakpoint" : "Remove Breakpoint"), removeBreakpoint.bind(this)); 416 contextMenu.appendItem(removeAllTitle, removeAllBreakpoints.bind(this)); 417 contextMenu.show(); 418 }, 419 420 _checkboxClicked: function(url, event) 421 { 422 if (event.target.checked) 423 DOMDebuggerAgent.setXHRBreakpoint(url); 424 else 425 DOMDebuggerAgent.removeXHRBreakpoint(url); 426 this._saveBreakpoints(); 427 }, 428 429 _labelClicked: function(url) 430 { 431 var element = this._breakpointElements[url]; 432 var inputElement = document.createElement("span"); 433 inputElement.className = "breakpoint-condition editing"; 434 inputElement.textContent = url; 435 this.listElement.insertBefore(inputElement, element); 436 element.classList.add("hidden"); 437 438 /** 439 * @param {boolean} accept 440 * @param {!Element} e 441 * @param {string} text 442 * @this {WebInspector.XHRBreakpointsSidebarPane} 443 */ 444 function finishEditing(accept, e, text) 445 { 446 this._removeListElement(inputElement); 447 if (accept) { 448 this._removeBreakpoint(url); 449 this._setBreakpoint(text, element._checkboxElement.checked); 450 this._saveBreakpoints(); 451 } else 452 element.classList.remove("hidden"); 453 } 454 455 WebInspector.startEditing(inputElement, new WebInspector.EditingConfig(finishEditing.bind(this, true), finishEditing.bind(this, false))); 456 }, 457 458 highlightBreakpoint: function(url) 459 { 460 var element = this._breakpointElements[url]; 461 if (!element) 462 return; 463 this.expand(); 464 element.classList.add("breakpoint-hit"); 465 this._highlightedElement = element; 466 }, 467 468 clearBreakpointHighlight: function() 469 { 470 if (this._highlightedElement) { 471 this._highlightedElement.classList.remove("breakpoint-hit"); 472 delete this._highlightedElement; 473 } 474 }, 475 476 _saveBreakpoints: function() 477 { 478 var breakpoints = []; 479 for (var url in this._breakpointElements) 480 breakpoints.push({ url: url, enabled: this._breakpointElements[url]._checkboxElement.checked }); 481 WebInspector.settings.xhrBreakpoints.set(breakpoints); 482 }, 483 484 _restoreBreakpoints: function() 485 { 486 var breakpoints = WebInspector.settings.xhrBreakpoints.get(); 487 for (var i = 0; i < breakpoints.length; ++i) { 488 var breakpoint = breakpoints[i]; 489 if (breakpoint && typeof breakpoint.url === "string") 490 this._setBreakpoint(breakpoint.url, breakpoint.enabled); 491 } 492 }, 493 494 __proto__: WebInspector.NativeBreakpointsSidebarPane.prototype 495 } 496 497 /** 498 * @constructor 499 * @extends {WebInspector.SidebarPane} 500 */ 501 WebInspector.EventListenerBreakpointsSidebarPane = function() 502 { 503 WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Breakpoints")); 504 this.registerRequiredCSS("breakpointsList.css"); 505 506 this.categoriesElement = document.createElement("ol"); 507 this.categoriesElement.tabIndex = 0; 508 this.categoriesElement.classList.add("properties-tree"); 509 this.categoriesElement.classList.add("event-listener-breakpoints"); 510 this.categoriesTreeOutline = new TreeOutline(this.categoriesElement); 511 this.bodyElement.appendChild(this.categoriesElement); 512 513 this._breakpointItems = {}; 514 // FIXME: uncomment following once inspector stops being drop targer in major ports. 515 // Otherwise, inspector page reacts on drop event and tries to load the event data. 516 // this._createCategory(WebInspector.UIString("Drag"), true, ["drag", "drop", "dragstart", "dragend", "dragenter", "dragleave", "dragover"]); 517 this._createCategory(WebInspector.UIString("Animation"), false, ["requestAnimationFrame", "cancelAnimationFrame", "animationFrameFired"]); 518 this._createCategory(WebInspector.UIString("Control"), true, ["resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset"]); 519 this._createCategory(WebInspector.UIString("Clipboard"), true, ["copy", "cut", "paste", "beforecopy", "beforecut", "beforepaste"]); 520 this._createCategory(WebInspector.UIString("DOM Mutation"), true, ["DOMActivate", "DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOMNodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMSubtreeModified", "DOMContentLoaded"]); 521 this._createCategory(WebInspector.UIString("Device"), true, ["deviceorientation", "devicemotion"]); 522 this._createCategory(WebInspector.UIString("Keyboard"), true, ["keydown", "keyup", "keypress", "input"]); 523 this._createCategory(WebInspector.UIString("Load"), true, ["load", "beforeunload", "unload", "abort", "error", "hashchange", "popstate"]); 524 this._createCategory(WebInspector.UIString("Mouse"), true, ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mousewheel"]); 525 this._createCategory(WebInspector.UIString("Timer"), false, ["setTimer", "clearTimer", "timerFired"]); 526 this._createCategory(WebInspector.UIString("Touch"), true, ["touchstart", "touchmove", "touchend", "touchcancel"]); 527 this._createCategory(WebInspector.UIString("WebGL"), false, ["webglErrorFired", "webglWarningFired"]); 528 529 this._restoreBreakpoints(); 530 } 531 532 WebInspector.EventListenerBreakpointsSidebarPane.categotyListener = "listener:"; 533 WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation = "instrumentation:"; 534 535 /** 536 * @param {string} eventName 537 * @param {!Object=} auxData 538 * @return {string} 539 */ 540 WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI = function(eventName, auxData) 541 { 542 if (!WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI) { 543 WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI = { 544 "instrumentation:setTimer": WebInspector.UIString("Set Timer"), 545 "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"), 546 "instrumentation:timerFired": WebInspector.UIString("Timer Fired"), 547 "instrumentation:requestAnimationFrame": WebInspector.UIString("Request Animation Frame"), 548 "instrumentation:cancelAnimationFrame": WebInspector.UIString("Cancel Animation Frame"), 549 "instrumentation:animationFrameFired": WebInspector.UIString("Animation Frame Fired"), 550 "instrumentation:webglErrorFired": WebInspector.UIString("WebGL Error Fired"), 551 "instrumentation:webglWarningFired": WebInspector.UIString("WebGL Warning Fired") 552 }; 553 } 554 if (auxData) { 555 if (eventName === "instrumentation:webglErrorFired" && auxData["webglErrorName"]) { 556 var errorName = auxData["webglErrorName"]; 557 // If there is a hex code of the error, display only this. 558 errorName = errorName.replace(/^.*(0x[0-9a-f]+).*$/i, "$1"); 559 return WebInspector.UIString("WebGL Error Fired (%s)", errorName); 560 } 561 } 562 return WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1); 563 } 564 565 WebInspector.EventListenerBreakpointsSidebarPane.prototype = { 566 _createCategory: function(name, isDOMEvent, eventNames) 567 { 568 var categoryItem = {}; 569 categoryItem.element = new TreeElement(name); 570 this.categoriesTreeOutline.appendChild(categoryItem.element); 571 categoryItem.element.listItemElement.classList.add("event-category"); 572 categoryItem.element.selectable = true; 573 574 categoryItem.checkbox = this._createCheckbox(categoryItem.element); 575 categoryItem.checkbox.addEventListener("click", this._categoryCheckboxClicked.bind(this, categoryItem), true); 576 577 categoryItem.children = {}; 578 for (var i = 0; i < eventNames.length; ++i) { 579 var eventName = (isDOMEvent ? WebInspector.EventListenerBreakpointsSidebarPane.categotyListener : WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation) + eventNames[i]; 580 581 var breakpointItem = {}; 582 var title = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName); 583 breakpointItem.element = new TreeElement(title); 584 categoryItem.element.appendChild(breakpointItem.element); 585 var hitMarker = document.createElement("div"); 586 hitMarker.className = "breakpoint-hit-marker"; 587 breakpointItem.element.listItemElement.appendChild(hitMarker); 588 breakpointItem.element.listItemElement.classList.add("source-code"); 589 breakpointItem.element.selectable = false; 590 591 breakpointItem.checkbox = this._createCheckbox(breakpointItem.element); 592 breakpointItem.checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, eventName), true); 593 breakpointItem.parent = categoryItem; 594 595 this._breakpointItems[eventName] = breakpointItem; 596 categoryItem.children[eventName] = breakpointItem; 597 } 598 }, 599 600 _createCheckbox: function(treeElement) 601 { 602 var checkbox = document.createElement("input"); 603 checkbox.className = "checkbox-elem"; 604 checkbox.type = "checkbox"; 605 treeElement.listItemElement.insertBefore(checkbox, treeElement.listItemElement.firstChild); 606 return checkbox; 607 }, 608 609 _categoryCheckboxClicked: function(categoryItem) 610 { 611 var checked = categoryItem.checkbox.checked; 612 for (var eventName in categoryItem.children) { 613 var breakpointItem = categoryItem.children[eventName]; 614 if (breakpointItem.checkbox.checked === checked) 615 continue; 616 if (checked) 617 this._setBreakpoint(eventName); 618 else 619 this._removeBreakpoint(eventName); 620 } 621 this._saveBreakpoints(); 622 }, 623 624 _breakpointCheckboxClicked: function(eventName, event) 625 { 626 if (event.target.checked) 627 this._setBreakpoint(eventName); 628 else 629 this._removeBreakpoint(eventName); 630 this._saveBreakpoints(); 631 }, 632 633 _setBreakpoint: function(eventName) 634 { 635 var breakpointItem = this._breakpointItems[eventName]; 636 if (!breakpointItem) 637 return; 638 breakpointItem.checkbox.checked = true; 639 if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener)) 640 DOMDebuggerAgent.setEventListenerBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener.length)); 641 else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation)) 642 DOMDebuggerAgent.setInstrumentationBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation.length)); 643 this._updateCategoryCheckbox(breakpointItem.parent); 644 }, 645 646 _removeBreakpoint: function(eventName) 647 { 648 var breakpointItem = this._breakpointItems[eventName]; 649 if (!breakpointItem) 650 return; 651 breakpointItem.checkbox.checked = false; 652 if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener)) 653 DOMDebuggerAgent.removeEventListenerBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener.length)); 654 else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation)) 655 DOMDebuggerAgent.removeInstrumentationBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation.length)); 656 this._updateCategoryCheckbox(breakpointItem.parent); 657 }, 658 659 _updateCategoryCheckbox: function(categoryItem) 660 { 661 var hasEnabled = false, hasDisabled = false; 662 for (var eventName in categoryItem.children) { 663 var breakpointItem = categoryItem.children[eventName]; 664 if (breakpointItem.checkbox.checked) 665 hasEnabled = true; 666 else 667 hasDisabled = true; 668 } 669 categoryItem.checkbox.checked = hasEnabled; 670 categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled; 671 }, 672 673 highlightBreakpoint: function(eventName) 674 { 675 var breakpointItem = this._breakpointItems[eventName]; 676 if (!breakpointItem) 677 return; 678 this.expand(); 679 breakpointItem.parent.element.expand(); 680 breakpointItem.element.listItemElement.classList.add("breakpoint-hit"); 681 this._highlightedElement = breakpointItem.element.listItemElement; 682 }, 683 684 clearBreakpointHighlight: function() 685 { 686 if (this._highlightedElement) { 687 this._highlightedElement.classList.remove("breakpoint-hit"); 688 delete this._highlightedElement; 689 } 690 }, 691 692 _saveBreakpoints: function() 693 { 694 var breakpoints = []; 695 for (var eventName in this._breakpointItems) { 696 if (this._breakpointItems[eventName].checkbox.checked) 697 breakpoints.push({ eventName: eventName }); 698 } 699 WebInspector.settings.eventListenerBreakpoints.set(breakpoints); 700 }, 701 702 _restoreBreakpoints: function() 703 { 704 var breakpoints = WebInspector.settings.eventListenerBreakpoints.get(); 705 for (var i = 0; i < breakpoints.length; ++i) { 706 var breakpoint = breakpoints[i]; 707 if (breakpoint && typeof breakpoint.eventName === "string") 708 this._setBreakpoint(breakpoint.eventName); 709 } 710 }, 711 712 __proto__: WebInspector.SidebarPane.prototype 713 } 714