OSDN Git Service

Merge WebKit at r84325: Initial merge by git.
[android-x86/external-webkit.git] / Source / WebCore / inspector / front-end / EventListenersSidebarPane.js
1 /*
2  * Copyright (C) 2007 Apple Inc.  All rights reserved.
3  * Copyright (C) 2009 Joseph Pecoraro
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 WebInspector.EventListenersSidebarPane = function()
31 {
32     WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listeners"));
33     this.bodyElement.addStyleClass("events-pane");
34
35     this.sections = [];
36
37     this.settingsSelectElement = document.createElement("select");
38
39     var option = document.createElement("option");
40     option.value = "all";
41     option.label = WebInspector.UIString("All Nodes");
42     this.settingsSelectElement.appendChild(option);
43
44     option = document.createElement("option");
45     option.value = "selected";
46     option.label = WebInspector.UIString("Selected Node Only");
47     this.settingsSelectElement.appendChild(option);
48
49     var filter = WebInspector.settings.eventListenersFilter;
50     if (filter === "all")
51         this.settingsSelectElement[0].selected = true;
52     else if (filter === "selected")
53         this.settingsSelectElement[1].selected = true;
54     this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false);
55     this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);
56
57     this.titleElement.appendChild(this.settingsSelectElement);
58 }
59
60 WebInspector.EventListenersSidebarPane.prototype = {
61     update: function(node)
62     {
63         var body = this.bodyElement;
64         body.removeChildren();
65         this.sections = [];
66
67         var self = this;
68         function callback(error, eventListeners) {
69             if (error)
70                 return;
71
72             var sectionNames = [];
73             var sectionMap = {};
74             for (var i = 0; i < eventListeners.length; ++i) {
75                 var eventListener = eventListeners[i];
76                 eventListener.node = WebInspector.domAgent.nodeForId(eventListener.nodeId);
77                 delete eventListener.nodeId; // no longer needed
78                 if (/^function _inspectorCommandLineAPI_logEvent\(/.test(eventListener.listenerBody.toString()))
79                     continue; // ignore event listeners generated by monitorEvent
80                 var type = eventListener.type;
81                 var section = sectionMap[type];
82                 if (!section) {
83                     section = new WebInspector.EventListenersSection(type, node.id);
84                     sectionMap[type] = section;
85                     sectionNames.push(type);
86                     self.sections.push(section);
87                 }
88                 section.addListener(eventListener);
89             }
90             
91             if (sectionNames.length === 0) {
92                 var div = document.createElement("div");
93                 div.className = "info";
94                 div.textContent = WebInspector.UIString("No Event Listeners");
95                 body.appendChild(div);
96                 return;
97             }
98
99             sectionNames.sort();
100             for (var i = 0; i < sectionNames.length; ++i) {
101                 var section = sectionMap[sectionNames[i]];
102                 section.update();
103                 body.appendChild(section.element);
104             }
105         }
106
107         if (node)
108             node.eventListeners(callback);
109     },
110
111     _changeSetting: function(event)
112     {
113         var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
114         WebInspector.settings.eventListenersFilter = selectedOption.value;
115
116         for (var i = 0; i < this.sections.length; ++i)
117             this.sections[i].update();
118     }
119 }
120
121 WebInspector.EventListenersSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
122
123 WebInspector.EventListenersSection = function(title, nodeId)
124 {
125     this.eventListeners = [];
126     this._nodeId = nodeId;
127     WebInspector.PropertiesSection.call(this, title);
128
129     // Changed from a Properties List
130     this.propertiesElement.parentNode.removeChild(this.propertiesElement);
131     delete this.propertiesElement;
132     delete this.propertiesTreeOutline;
133
134     this.eventBars = document.createElement("div");
135     this.eventBars.className = "event-bars";
136     this.element.appendChild(this.eventBars);
137 }
138
139 WebInspector.EventListenersSection.prototype = {
140     update: function()
141     {
142         // A Filtered Array simplifies when to create connectors
143         var filteredEventListeners = this.eventListeners;
144         if (WebInspector.settings.eventListenersFilter === "selected") {
145             filteredEventListeners = [];
146             for (var i = 0; i < this.eventListeners.length; ++i) {
147                 var eventListener = this.eventListeners[i];
148                 if (eventListener.node.id === this._nodeId)
149                     filteredEventListeners.push(eventListener);
150             }
151         }
152
153         this.eventBars.removeChildren();
154         var length = filteredEventListeners.length;
155         for (var i = 0; i < length; ++i) {
156             var eventListener = filteredEventListeners[i];
157             var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId);
158             this.eventBars.appendChild(eventListenerBar.element);
159         }
160     },
161
162     addListener: function(eventListener)
163     {
164         this.eventListeners.push(eventListener);
165     }
166 }
167
168 WebInspector.EventListenersSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
169
170 WebInspector.EventListenerBar = function(eventListener, nodeId)
171 {
172     this.eventListener = eventListener;
173     this._nodeId = nodeId;
174     WebInspector.ObjectPropertiesSection.call(this);
175     this._setNodeTitle();
176     this._setFunctionSubtitle();
177     this.editable = false;
178     this.element.className = "event-bar"; /* Changed from "section" */
179     this.headerElement.addStyleClass("source-code");
180     this.propertiesElement.className = "event-properties properties-tree source-code"; /* Changed from "properties" */
181 }
182
183 WebInspector.EventListenerBar.prototype = {
184     update: function()
185     {
186         function updateWithNodeObject(nodeObject)
187         {
188             var properties = [];
189             if (nodeObject)
190                 properties.push(new WebInspector.RemoteObjectProperty("node", nodeObject));
191
192             for (var propertyName in this.eventListener) {
193                 var value = WebInspector.RemoteObject.fromPrimitiveValue(this.eventListener[propertyName]);
194                 properties.push(new WebInspector.RemoteObjectProperty(propertyName, value));
195             }
196             this.updateProperties(properties);
197             if (nodeObject)
198                 nodeObject.release();
199         }
200         var node = this.eventListener.node;
201         delete this.eventListener.node;
202         WebInspector.RemoteObject.resolveNode(node, updateWithNodeObject.bind(this));
203     },
204
205     _setNodeTitle: function()
206     {
207         var node = this.eventListener.node;
208         if (!node)
209             return;
210
211         if (node.nodeType() === Node.DOCUMENT_NODE) {
212             this.titleElement.textContent = "document";
213             return;
214         }
215
216         if (node.id === this._nodeId) {
217             this.titleElement.textContent = node.appropriateSelectorFor();
218             return;
219         }
220
221         this.titleElement.removeChildren();
222         this.titleElement.appendChild(WebInspector.panels.elements.linkifyNodeReference(this.eventListener.node));
223     },
224
225     _setFunctionSubtitle: function()
226     {
227         // Requires that Function.toString() return at least the function's signature.
228         if (this.eventListener.sourceName) {
229             this.subtitleElement.removeChildren();
230             this.subtitleElement.appendChild(WebInspector.linkifyResourceAsNode(this.eventListener.sourceName, "scripts", this.eventListener.lineNumber));
231         } else {
232             var match = this.eventListener.listenerBody.match(/function ([^\(]+?)\(/);
233             if (match)
234                 this.subtitleElement.textContent = match[1];
235             else
236                 this.subtitleElement.textContent = WebInspector.UIString("(anonymous function)");
237         }
238     }
239 }
240
241 WebInspector.EventListenerBar.prototype.__proto__ = WebInspector.ObjectPropertiesSection.prototype;