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