/* * Copyright (C) 2007 Apple Inc. All rights reserved. * Copyright (C) 2009 Joseph Pecoraro * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ WebInspector.EventListenersSidebarPane = function() { WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listeners")); this.bodyElement.addStyleClass("events-pane"); this.sections = []; this.settingsSelectElement = document.createElement("select"); var option = document.createElement("option"); option.value = "all"; option.label = WebInspector.UIString("All Nodes"); this.settingsSelectElement.appendChild(option); option = document.createElement("option"); option.value = "selected"; option.label = WebInspector.UIString("Selected Node Only"); this.settingsSelectElement.appendChild(option); var filter = WebInspector.settings.eventListenersFilter; if (filter === "all") this.settingsSelectElement[0].selected = true; else if (filter === "selected") this.settingsSelectElement[1].selected = true; this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false); this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false); this.titleElement.appendChild(this.settingsSelectElement); } WebInspector.EventListenersSidebarPane.prototype = { update: function(node) { var body = this.bodyElement; body.removeChildren(); this.sections = []; var self = this; function callback(error, eventListeners) { if (error) return; var sectionNames = []; var sectionMap = {}; for (var i = 0; i < eventListeners.length; ++i) { var eventListener = eventListeners[i]; eventListener.node = WebInspector.domAgent.nodeForId(eventListener.nodeId); delete eventListener.nodeId; // no longer needed if (/^function _inspectorCommandLineAPI_logEvent\(/.test(eventListener.listenerBody.toString())) continue; // ignore event listeners generated by monitorEvent var type = eventListener.type; var section = sectionMap[type]; if (!section) { section = new WebInspector.EventListenersSection(type, node.id); sectionMap[type] = section; sectionNames.push(type); self.sections.push(section); } section.addListener(eventListener); } if (sectionNames.length === 0) { var div = document.createElement("div"); div.className = "info"; div.textContent = WebInspector.UIString("No Event Listeners"); body.appendChild(div); return; } sectionNames.sort(); for (var i = 0; i < sectionNames.length; ++i) { var section = sectionMap[sectionNames[i]]; section.update(); body.appendChild(section.element); } } if (node) node.eventListeners(callback); }, _changeSetting: function(event) { var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex]; WebInspector.settings.eventListenersFilter = selectedOption.value; for (var i = 0; i < this.sections.length; ++i) this.sections[i].update(); } } WebInspector.EventListenersSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype; WebInspector.EventListenersSection = function(title, nodeId) { this.eventListeners = []; this._nodeId = nodeId; WebInspector.PropertiesSection.call(this, title); // Changed from a Properties List this.propertiesElement.parentNode.removeChild(this.propertiesElement); delete this.propertiesElement; delete this.propertiesTreeOutline; this.eventBars = document.createElement("div"); this.eventBars.className = "event-bars"; this.element.appendChild(this.eventBars); } WebInspector.EventListenersSection.prototype = { update: function() { // A Filtered Array simplifies when to create connectors var filteredEventListeners = this.eventListeners; if (WebInspector.settings.eventListenersFilter === "selected") { filteredEventListeners = []; for (var i = 0; i < this.eventListeners.length; ++i) { var eventListener = this.eventListeners[i]; if (eventListener.node.id === this._nodeId) filteredEventListeners.push(eventListener); } } this.eventBars.removeChildren(); var length = filteredEventListeners.length; for (var i = 0; i < length; ++i) { var eventListener = filteredEventListeners[i]; var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId); this.eventBars.appendChild(eventListenerBar.element); } }, addListener: function(eventListener) { this.eventListeners.push(eventListener); } } WebInspector.EventListenersSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype; WebInspector.EventListenerBar = function(eventListener, nodeId) { this.eventListener = eventListener; this._nodeId = nodeId; WebInspector.ObjectPropertiesSection.call(this); this._setNodeTitle(); this._setFunctionSubtitle(); this.editable = false; this.element.className = "event-bar"; /* Changed from "section" */ this.headerElement.addStyleClass("source-code"); this.propertiesElement.className = "event-properties properties-tree source-code"; /* Changed from "properties" */ } WebInspector.EventListenerBar.prototype = { update: function() { function updateWithNodeObject(nodeObject) { var properties = []; if (nodeObject) properties.push(new WebInspector.RemoteObjectProperty("node", nodeObject)); for (var propertyName in this.eventListener) { var value = WebInspector.RemoteObject.fromPrimitiveValue(this.eventListener[propertyName]); properties.push(new WebInspector.RemoteObjectProperty(propertyName, value)); } this.updateProperties(properties); if (nodeObject) nodeObject.release(); } var node = this.eventListener.node; delete this.eventListener.node; WebInspector.RemoteObject.resolveNode(node, updateWithNodeObject.bind(this)); }, _setNodeTitle: function() { var node = this.eventListener.node; if (!node) return; if (node.nodeType() === Node.DOCUMENT_NODE) { this.titleElement.textContent = "document"; return; } if (node.id === this._nodeId) { this.titleElement.textContent = node.appropriateSelectorFor(); return; } this.titleElement.removeChildren(); this.titleElement.appendChild(WebInspector.panels.elements.linkifyNodeReference(this.eventListener.node)); }, _setFunctionSubtitle: function() { // Requires that Function.toString() return at least the function's signature. if (this.eventListener.sourceName) { this.subtitleElement.removeChildren(); this.subtitleElement.appendChild(WebInspector.linkifyResourceAsNode(this.eventListener.sourceName, "scripts", this.eventListener.lineNumber)); } else { var match = this.eventListener.listenerBody.match(/function ([^\(]+?)\(/); if (match) this.subtitleElement.textContent = match[1]; else this.subtitleElement.textContent = WebInspector.UIString("(anonymous function)"); } } } WebInspector.EventListenerBar.prototype.__proto__ = WebInspector.ObjectPropertiesSection.prototype;