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