2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 WebInspector.BreakpointsSidebarPane = function(title)
28 WebInspector.SidebarPane.call(this, title);
30 this.listElement = document.createElement("ol");
31 this.listElement.className = "breakpoint-list";
33 this.emptyElement = document.createElement("div");
34 this.emptyElement.className = "info";
35 this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
37 this.bodyElement.appendChild(this.emptyElement);
39 WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
42 WebInspector.BreakpointsSidebarPane.prototype = {
43 addBreakpointItem: function(breakpointItem)
45 var element = breakpointItem.element;
46 element._breakpointItem = breakpointItem;
48 breakpointItem.addEventListener("breakpoint-hit", this.expand, this);
49 breakpointItem.addEventListener("removed", this._removeListElement.bind(this, element), this);
51 var currentElement = this.listElement.firstChild;
52 while (currentElement) {
53 if (currentElement._breakpointItem && currentElement._breakpointItem.compareTo(element._breakpointItem) > 0)
55 currentElement = currentElement.nextSibling;
57 this._addListElement(element, currentElement);
59 if (breakpointItem.click) {
60 element.addStyleClass("cursor-pointer");
61 element.addEventListener("click", breakpointItem.click.bind(breakpointItem), false);
63 element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointItem), true);
66 _contextMenuEventFired: function(breakpointItem, event)
68 var contextMenu = new WebInspector.ContextMenu();
69 contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpointItem.remove.bind(breakpointItem));
70 contextMenu.show(event);
73 _addListElement: function(element, beforeElement)
76 this.listElement.insertBefore(element, beforeElement);
78 if (!this.listElement.firstChild) {
79 this.bodyElement.removeChild(this.emptyElement);
80 this.bodyElement.appendChild(this.listElement);
82 this.listElement.appendChild(element);
86 _removeListElement: function(element)
88 this.listElement.removeChild(element);
89 if (!this.listElement.firstChild) {
90 this.bodyElement.removeChild(this.listElement);
91 this.bodyElement.appendChild(this.emptyElement);
95 _projectChanged: function()
97 this.listElement.removeChildren();
98 if (this.listElement.parentElement) {
99 this.bodyElement.removeChild(this.listElement);
100 this.bodyElement.appendChild(this.emptyElement);
105 WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
107 WebInspector.XHRBreakpointsSidebarPane = function()
109 WebInspector.BreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints"));
111 function addButtonClicked(event)
113 event.stopPropagation();
114 this._startEditingBreakpoint(null);
117 var addButton = document.createElement("button");
118 addButton.className = "add";
119 addButton.addEventListener("click", addButtonClicked.bind(this), false);
120 this.titleElement.appendChild(addButton);
123 WebInspector.XHRBreakpointsSidebarPane.prototype = {
124 addBreakpointItem: function(breakpointItem)
126 WebInspector.BreakpointsSidebarPane.prototype.addBreakpointItem.call(this, breakpointItem);
127 breakpointItem._labelElement.addEventListener("dblclick", this._startEditingBreakpoint.bind(this, breakpointItem), false);
130 _startEditingBreakpoint: function(breakpointItem)
132 if (this._editingBreakpoint)
134 this._editingBreakpoint = true;
137 this.expanded = true;
139 var inputElement = document.createElement("span");
140 inputElement.className = "breakpoint-condition editing";
141 if (breakpointItem) {
142 breakpointItem.populateEditElement(inputElement);
143 this.listElement.insertBefore(inputElement, breakpointItem.element);
144 breakpointItem.element.addStyleClass("hidden");
146 this._addListElement(inputElement, this.listElement.firstChild);
148 var commitHandler = this._hideEditBreakpointDialog.bind(this, inputElement, true, breakpointItem);
149 var cancelHandler = this._hideEditBreakpointDialog.bind(this, inputElement, false, breakpointItem);
150 WebInspector.startEditing(inputElement, {
151 commitHandler: commitHandler,
152 cancelHandler: cancelHandler
156 _hideEditBreakpointDialog: function(inputElement, accept, breakpointItem)
158 this._removeListElement(inputElement);
159 this._editingBreakpoint = false;
162 breakpointItem.remove();
163 WebInspector.breakpointManager.createXHRBreakpoint(inputElement.textContent.toLowerCase());
164 } else if (breakpointItem)
165 breakpointItem.element.removeStyleClass("hidden");
169 WebInspector.XHRBreakpointsSidebarPane.prototype.__proto__ = WebInspector.BreakpointsSidebarPane.prototype;
171 WebInspector.BreakpointItem = function(breakpoint)
173 this._breakpoint = breakpoint;
175 this._element = document.createElement("li");
177 var checkboxElement = document.createElement("input");
178 checkboxElement.className = "checkbox-elem";
179 checkboxElement.type = "checkbox";
180 checkboxElement.checked = this._breakpoint.enabled;
181 checkboxElement.addEventListener("click", this._checkboxClicked.bind(this), false);
182 this._element.appendChild(checkboxElement);
184 this._createLabelElement();
186 this._breakpoint.addEventListener("enable-changed", this._enableChanged, this);
187 this._breakpoint.addEventListener("hit-state-changed", this._hitStateChanged, this);
188 this._breakpoint.addEventListener("label-changed", this._labelChanged, this);
189 this._breakpoint.addEventListener("removed", this.dispatchEventToListeners.bind(this, "removed"));
190 if (breakpoint.click)
191 this.click = breakpoint.click.bind(breakpoint);
194 WebInspector.BreakpointItem.prototype = {
197 return this._element;
200 compareTo: function(other)
202 return this._breakpoint.compareTo(other._breakpoint);
205 populateEditElement: function(element)
207 this._breakpoint.populateEditElement(element);
212 this._breakpoint.remove();
215 _checkboxClicked: function(event)
217 this._breakpoint.enabled = !this._breakpoint.enabled;
219 // Breakpoint element may have it's own click handler.
220 event.stopPropagation();
223 _enableChanged: function(event)
225 var checkbox = this._element.firstChild;
226 checkbox.checked = this._breakpoint.enabled;
229 _hitStateChanged: function(event)
231 if (event.target.hit) {
232 this._element.addStyleClass("breakpoint-hit");
233 this.dispatchEventToListeners("breakpoint-hit");
235 this._element.removeStyleClass("breakpoint-hit");
238 _labelChanged: function(event)
240 this._element.removeChild(this._labelElement);
241 this._createLabelElement();
244 _createLabelElement: function()
246 this._labelElement = document.createElement("span");
247 this._breakpoint.populateLabelElement(this._labelElement);
248 this._element.appendChild(this._labelElement);
252 WebInspector.BreakpointItem.prototype.__proto__ = WebInspector.Object.prototype;
254 WebInspector.EventListenerBreakpointsSidebarPane = function()
256 WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Breakpoints"));
258 this.categoriesElement = document.createElement("ol");
259 this.categoriesElement.tabIndex = 0;
260 this.categoriesElement.addStyleClass("properties-tree event-listener-breakpoints");
261 this.categoriesTreeOutline = new TreeOutline(this.categoriesElement);
262 this.bodyElement.appendChild(this.categoriesElement);
264 WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
265 WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.EventListenerBreakpointAdded, this._breakpointAdded, this);
267 this._breakpointItems = {};
268 this._createCategory(WebInspector.UIString("Keyboard"), "listener", ["keydown", "keyup", "keypress", "textInput"]);
269 this._createCategory(WebInspector.UIString("Mouse"), "listener", ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mousewheel"]);
270 // FIXME: uncomment following once inspector stops being drop targer in major ports.
271 // Otherwise, inspector page reacts on drop event and tries to load the event data.
272 // this._createCategory(WebInspector.UIString("Drag"), "listener", ["drag", "drop", "dragstart", "dragend", "dragenter", "dragleave", "dragover"]);
273 this._createCategory(WebInspector.UIString("Control"), "listener", ["resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset"]);
274 this._createCategory(WebInspector.UIString("Clipboard"), "listener", ["copy", "cut", "paste", "beforecopy", "beforecut", "beforepaste"]);
275 this._createCategory(WebInspector.UIString("Load"), "listener", ["load", "unload", "abort", "error"]);
276 this._createCategory(WebInspector.UIString("DOM Mutation"), "listener", ["DOMActivate", "DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOMNodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMSubtreeModified", "DOMContentLoaded"]);
277 this._createCategory(WebInspector.UIString("Device"), "listener", ["deviceorientation", "devicemotion"]);
278 this._createCategory(WebInspector.UIString("Timer"), "instrumentation", ["setTimer", "clearTimer", "timerFired"]);
281 WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
282 _createCategory: function(name, type, eventNames)
284 var categoryItem = {};
285 categoryItem.element = new TreeElement(name);
286 this.categoriesTreeOutline.appendChild(categoryItem.element);
287 categoryItem.element.listItemElement.addStyleClass("event-category");
288 categoryItem.element.selectable = true;
290 categoryItem.checkbox = this._createCheckbox(categoryItem.element);
291 categoryItem.checkbox.addEventListener("click", this._categoryCheckboxClicked.bind(this, categoryItem), true);
293 categoryItem.children = {};
294 for (var i = 0; i < eventNames.length; ++i) {
295 var eventName = type + ":" + eventNames[i];
297 var breakpointItem = {};
298 var title = WebInspector.EventListenerBreakpointView.eventNameForUI(eventName);
299 breakpointItem.element = new TreeElement(title);
300 categoryItem.element.appendChild(breakpointItem.element);
301 var hitMarker = document.createElement("div");
302 hitMarker.className = "breakpoint-hit-marker";
303 breakpointItem.element.listItemElement.appendChild(hitMarker);
304 breakpointItem.element.listItemElement.addStyleClass("source-code");
305 breakpointItem.element.selectable = true;
307 breakpointItem.checkbox = this._createCheckbox(breakpointItem.element);
308 breakpointItem.checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, breakpointItem), true);
309 breakpointItem.parent = categoryItem;
310 breakpointItem.eventName = eventName;
312 this._breakpointItems[eventName] = breakpointItem;
313 categoryItem.children[eventName] = breakpointItem;
317 _createCheckbox: function(treeElement)
319 var checkbox = document.createElement("input");
320 checkbox.className = "checkbox-elem";
321 checkbox.type = "checkbox";
322 treeElement.listItemElement.insertBefore(checkbox, treeElement.listItemElement.firstChild);
326 _categoryCheckboxClicked: function(categoryItem)
328 var checked = categoryItem.checkbox.checked;
329 for (var eventName in categoryItem.children) {
330 var breakpointItem = categoryItem.children[eventName];
331 if (breakpointItem.checkbox.checked !== checked) {
332 breakpointItem.checkbox.checked = checked;
333 this._breakpointCheckboxClicked(breakpointItem);
338 _breakpointCheckboxClicked: function(breakpointItem)
340 if (breakpointItem.checkbox.checked)
341 WebInspector.breakpointManager.createEventListenerBreakpoint(breakpointItem.eventName);
343 breakpointItem.breakpoint.remove();
346 _breakpointAdded: function(event)
348 var breakpoint = event.data;
350 var breakpointItem = this._breakpointItems[breakpoint.eventName];
351 breakpointItem.breakpoint = breakpoint;
352 breakpoint.addEventListener("hit-state-changed", this._breakpointHitStateChanged.bind(this, breakpointItem));
353 breakpoint.addEventListener("removed", this._breakpointRemoved.bind(this, breakpointItem));
354 breakpointItem.checkbox.checked = true;
355 this._updateCategoryCheckbox(breakpointItem);
358 _breakpointHitStateChanged: function(breakpointItem, event)
360 if (event.target.hit) {
361 this.expanded = true;
362 var categoryItem = breakpointItem.parent;
363 categoryItem.element.expand();
364 breakpointItem.element.listItemElement.addStyleClass("breakpoint-hit");
366 breakpointItem.element.listItemElement.removeStyleClass("breakpoint-hit");
369 _breakpointRemoved: function(breakpointItem)
371 breakpointItem.breakpoint = null;
372 breakpointItem.checkbox.checked = false;
373 this._updateCategoryCheckbox(breakpointItem);
376 _updateCategoryCheckbox: function(breakpointItem)
378 var categoryItem = breakpointItem.parent;
379 var hasEnabled = false, hasDisabled = false;
380 for (var eventName in categoryItem.children) {
381 var breakpointItem = categoryItem.children[eventName];
382 if (breakpointItem.checkbox.checked)
387 categoryItem.checkbox.checked = hasEnabled;
388 categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled;
391 _projectChanged: function()
393 for (var eventName in this._breakpointItems) {
394 var breakpointItem = this._breakpointItems[eventName];
395 breakpointItem.breakpoint = null;
396 breakpointItem.checkbox.checked = false;
397 this._updateCategoryCheckbox(breakpointItem);
402 WebInspector.EventListenerBreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;