[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75
pfeldman at chromium.org
pfeldman at chromium.org
Thu Oct 29 20:34:56 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit a5c785e8edaff2f126a40a7f839133ddf37aac91
Author: pfeldman at chromium.org <pfeldman at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Sep 28 12:36:44 2009 +0000
2009-09-28 Joseph Pecoraro <joepeck at webkit.org>
Reviewed by Timothy Hatcher.
Inspector Should Show Event Listeners/Handlers Registered on each Node
https://bugs.webkit.org/show_bug.cgi?id=17429
Extracted a method from dispatchEvent to get the event ancestor chain
* dom/Node.cpp:
(WebCore::Node::eventAncestors): the extracted method
(WebCore::Node::dispatchGenericEvent): use eventAncestors
* dom/Node.h:
Asynchronous Flow For the Inspector, Backend -> DOM Agent -> Frontend
The DOMAgent's getEventListenersForNode handles the logic of finding
all the relevant listeners in the event flow.
* inspector/InspectorBackend.cpp:
(WebCore::InspectorBackend::getEventListenersForNode):
* inspector/InspectorBackend.h:
* inspector/InspectorBackend.idl:
* inspector/InspectorDOMAgent.cpp:
(WebCore::InspectorDOMAgent::getEventListenersForNode):
(WebCore::InspectorDOMAgent::buildObjectForEventListener):
(WebCore::InspectorDOMAgent::buildObjectForNode): added localName
* inspector/InspectorDOMAgent.h:
(WebCore::EventListenerInfo::EventListenerInfo):
* inspector/InspectorFrontend.cpp:
(WebCore::InspectorFrontend::didGetEventListenersForNode):
* inspector/InspectorFrontend.h:
(WebCore::InspectorFrontend::scriptState):
* inspector/front-end/DOMAgent.js: added localName to WebInspector.DOMNode from payload
(WebInspector.EventListeners.getEventListenersForNodeAsync.mycallback):
(WebInspector.EventListeners.getEventListenersForNodeAsync):
New Sidebar Pane in the Element's Panel
Includes Gear Menu for filtering the Event Listeners on the
"Selected Node Only" or "All Nodes"
* inspector/front-end/ElementsPanel.js: Handles refreshing the Pane when necessary
(WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged):
(WebInspector.ElementsPanel):
(WebInspector.ElementsPanel.prototype.updateEventListeners):
* inspector/front-end/EventListenersSidebarPane.js: Added.
(WebInspector.EventListenersSidebarPane): The 1st level in the Pane
(WebInspector.EventListenersSidebarPane.prototype.update.callback):
(WebInspector.EventListenersSidebarPane.prototype.update):
(WebInspector.EventListenersSection): The 2nd level in the Pane
(WebInspector.EventListenersSection.prototype.update): filters on Preference
(WebInspector.EventListenersSection.prototype.addListener):
(WebInspector.EventListenerBar): The 3rd level in the Pane
(WebInspector.EventListenerBar.prototype._getNodeDisplayName):
(WebInspector.EventListenerBar.prototype._getFunctionDisplayName):
(WebInspector.EventListenersSidebarPane.prototype._changeSetting): For the Gear Menu
Consolidated "appropriateSelectorForNode"
* inspector/front-end/StylesSidebarPane.js:
* inspector/front-end/utilities.js:
Miscellaneous Updates
* English.lproj/localizedStrings.js: "Event Listeners", "No Event Listeners", "Selected Node Only", "All Nodes"
* WebCore.gypi: included the new inspector files
* WebCore.vcproj/WebCore.vcproj: included source files that were missing
* inspector/front-end/Images/grayConnectorPoint.png: Added. Thanks to Timothy Hatcher.
* inspector/front-end/Images/whiteConnectorPoint.png: Added. Thanks to Timothy Hatcher.
* inspector/front-end/inspector.js: Preferences for the Gear Menu Event Listeners filter
* inspector/front-end/inspector.css: reused as much as possible
* inspector/front-end/inspector.html: include the new script
* inspector/front-end/WebKit.qrc: included the new inspector files
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 036fb5e..3098fbb 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,76 @@
+2009-09-28 Joseph Pecoraro <joepeck at webkit.org>
+
+ Reviewed by Timothy Hatcher.
+
+ Inspector Should Show Event Listeners/Handlers Registered on each Node
+ https://bugs.webkit.org/show_bug.cgi?id=17429
+
+ Extracted a method from dispatchEvent to get the event ancestor chain
+
+ * dom/Node.cpp:
+ (WebCore::Node::eventAncestors): the extracted method
+ (WebCore::Node::dispatchGenericEvent): use eventAncestors
+ * dom/Node.h:
+
+ Asynchronous Flow For the Inspector, Backend -> DOM Agent -> Frontend
+ The DOMAgent's getEventListenersForNode handles the logic of finding
+ all the relevant listeners in the event flow.
+
+ * inspector/InspectorBackend.cpp:
+ (WebCore::InspectorBackend::getEventListenersForNode):
+ * inspector/InspectorBackend.h:
+ * inspector/InspectorBackend.idl:
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::getEventListenersForNode):
+ (WebCore::InspectorDOMAgent::buildObjectForEventListener):
+ (WebCore::InspectorDOMAgent::buildObjectForNode): added localName
+ * inspector/InspectorDOMAgent.h:
+ (WebCore::EventListenerInfo::EventListenerInfo):
+ * inspector/InspectorFrontend.cpp:
+ (WebCore::InspectorFrontend::didGetEventListenersForNode):
+ * inspector/InspectorFrontend.h:
+ (WebCore::InspectorFrontend::scriptState):
+ * inspector/front-end/DOMAgent.js: added localName to WebInspector.DOMNode from payload
+ (WebInspector.EventListeners.getEventListenersForNodeAsync.mycallback):
+ (WebInspector.EventListeners.getEventListenersForNodeAsync):
+
+ New Sidebar Pane in the Element's Panel
+ Includes Gear Menu for filtering the Event Listeners on the
+ "Selected Node Only" or "All Nodes"
+
+ * inspector/front-end/ElementsPanel.js: Handles refreshing the Pane when necessary
+ (WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged):
+ (WebInspector.ElementsPanel):
+ (WebInspector.ElementsPanel.prototype.updateEventListeners):
+ * inspector/front-end/EventListenersSidebarPane.js: Added.
+ (WebInspector.EventListenersSidebarPane): The 1st level in the Pane
+ (WebInspector.EventListenersSidebarPane.prototype.update.callback):
+ (WebInspector.EventListenersSidebarPane.prototype.update):
+ (WebInspector.EventListenersSection): The 2nd level in the Pane
+ (WebInspector.EventListenersSection.prototype.update): filters on Preference
+ (WebInspector.EventListenersSection.prototype.addListener):
+ (WebInspector.EventListenerBar): The 3rd level in the Pane
+ (WebInspector.EventListenerBar.prototype._getNodeDisplayName):
+ (WebInspector.EventListenerBar.prototype._getFunctionDisplayName):
+ (WebInspector.EventListenersSidebarPane.prototype._changeSetting): For the Gear Menu
+
+ Consolidated "appropriateSelectorForNode"
+
+ * inspector/front-end/StylesSidebarPane.js:
+ * inspector/front-end/utilities.js:
+
+ Miscellaneous Updates
+
+ * English.lproj/localizedStrings.js: "Event Listeners", "No Event Listeners", "Selected Node Only", "All Nodes"
+ * WebCore.gypi: included the new inspector files
+ * WebCore.vcproj/WebCore.vcproj: included source files that were missing
+ * inspector/front-end/Images/grayConnectorPoint.png: Added. Thanks to Timothy Hatcher.
+ * inspector/front-end/Images/whiteConnectorPoint.png: Added. Thanks to Timothy Hatcher.
+ * inspector/front-end/inspector.js: Preferences for the Gear Menu Event Listeners filter
+ * inspector/front-end/inspector.css: reused as much as possible
+ * inspector/front-end/inspector.html: include the new script
+ * inspector/front-end/WebKit.qrc: included the new inspector files
+
2009-09-27 Sam Weinig <sam at webkit.org>
Reviewed by Dan Bernstein.
diff --git a/WebCore/English.lproj/localizedStrings.js b/WebCore/English.lproj/localizedStrings.js
index c53cd2f..93385b2 100644
Binary files a/WebCore/English.lproj/localizedStrings.js and b/WebCore/English.lproj/localizedStrings.js differ
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index e91076b..18cfb0c 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -3546,6 +3546,7 @@
'inspector/front-end/Drawer.js',
'inspector/front-end/ElementsPanel.js',
'inspector/front-end/ElementsTreeOutline.js',
+ 'inspector/front-end/EventListenersSidebarPane.js',
'inspector/front-end/FontView.js',
'inspector/front-end/ImageView.js',
'inspector/front-end/InjectedScript.js',
@@ -3630,6 +3631,7 @@
'inspector/front-end/Images/goArrow.png',
'inspector/front-end/Images/graphLabelCalloutLeft.png',
'inspector/front-end/Images/graphLabelCalloutRight.png',
+ 'inspector/front-end/Images/grayConnectorPoint.png',
'inspector/front-end/Images/largerResourcesButtonGlyph.png',
'inspector/front-end/Images/localStorage.png',
'inspector/front-end/Images/nodeSearchButtonGlyph.png',
@@ -3712,6 +3714,7 @@
'inspector/front-end/Images/warningIcon.png',
'inspector/front-end/Images/warningMediumIcon.png',
'inspector/front-end/Images/warningsErrors.png',
+ 'inspector/front-end/Images/whiteConnectorPoint.png'
],
}
}
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index 6cb0b7e..4c6c43d 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -31427,10 +31427,6 @@
>
</File>
<File
- RelativePath="..\inspector\front-end\DatabasesPanel.js"
- >
- </File>
- <File
RelativePath="..\inspector\front-end\DatabaseTableView.js"
>
</File>
@@ -31463,6 +31459,14 @@
>
</File>
<File
+ RelativePath="..\inspector\front-end\ElementsTreeOutline.js"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\front-end\EventListenersSidebarPane.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\FontView.js"
>
</File>
@@ -31583,6 +31587,10 @@
>
</File>
<File
+ RelativePath="..\inspector\front-end\StoragePanel.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\StylesSidebarPane.js"
>
</File>
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index c899f3d..612bf18 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -2422,6 +2422,20 @@ static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNo
return referenceNode;
}
+void Node::eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors)
+{
+ if (inDocument()) {
+ for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) {
+#if ENABLE(SVG)
+ // Skip <use> shadow tree elements.
+ if (ancestor->isSVGElement() && ancestor->isShadowNode())
+ continue;
+#endif
+ ancestors.append(ancestor);
+ }
+ }
+}
+
bool Node::dispatchEvent(PassRefPtr<Event> prpEvent)
{
RefPtr<EventTarget> protect = this;
@@ -2452,16 +2466,7 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
// Be sure to ref all of nodes since event handlers could result in the last reference going away.
RefPtr<Node> thisNode(this);
Vector<RefPtr<ContainerNode> > ancestors;
- if (inDocument()) {
- for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) {
-#if ENABLE(SVG)
- // Skip <use> shadow tree elements.
- if (ancestor->isSVGElement() && ancestor->isShadowNode())
- continue;
-#endif
- ancestors.append(ancestor);
- }
- }
+ eventAncestors(ancestors);
// Set up a pointer to indicate whether / where to dispatch window events.
// We don't dispatch load events to the window. That quirk was originally
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index f3bebc6..35be6d3 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -206,6 +206,9 @@ public:
// The node's parent for the purpose of event capture and bubbling.
virtual ContainerNode* eventParentNode();
+ // Node ancestors when concerned about event flow
+ void eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors);
+
bool isBlockFlow() const;
bool isBlockFlowOrBlockTable() const;
diff --git a/WebCore/inspector/InspectorBackend.cpp b/WebCore/inspector/InspectorBackend.cpp
index ad0c510..752ec0c 100644
--- a/WebCore/inspector/InspectorBackend.cpp
+++ b/WebCore/inspector/InspectorBackend.cpp
@@ -276,19 +276,6 @@ bool InspectorBackend::timelineEnabled() const
return false;
}
-void InspectorBackend::getCookies(long callId)
-{
- if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
- domAgent->getCookies(callId);
-}
-
-void InspectorBackend::deleteCookie(const String& cookieName)
-{
- if (!m_inspectorController)
- return;
- m_inspectorController->deleteCookie(cookieName);
-}
-
#if ENABLE(JAVASCRIPT_DEBUGGER)
const ProfilesArray& InspectorBackend::profiles() const
{
@@ -449,6 +436,12 @@ void InspectorBackend::setTextNodeValue(long callId, long nodeId, const String&
domAgent->setTextNodeValue(callId, nodeId, value);
}
+void InspectorBackend::getEventListenersForNode(long callId, long nodeId)
+{
+ if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
+ domAgent->getEventListenersForNode(callId, nodeId);
+}
+
void InspectorBackend::copyNode(long nodeId)
{
Node* node = nodeForId(nodeId);
@@ -458,6 +451,19 @@ void InspectorBackend::copyNode(long nodeId)
Pasteboard::generalPasteboard()->writePlainText(markup);
}
+void InspectorBackend::getCookies(long callId)
+{
+ if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
+ domAgent->getCookies(callId);
+}
+
+void InspectorBackend::deleteCookie(const String& cookieName)
+{
+ if (!m_inspectorController)
+ return;
+ m_inspectorController->deleteCookie(cookieName);
+}
+
void InspectorBackend::highlight(long nodeId)
{
if (Node* node = nodeForId(nodeId))
diff --git a/WebCore/inspector/InspectorBackend.h b/WebCore/inspector/InspectorBackend.h
index 739d28e..72278a3 100644
--- a/WebCore/inspector/InspectorBackend.h
+++ b/WebCore/inspector/InspectorBackend.h
@@ -99,9 +99,6 @@ public:
void disableTimeline(bool always);
bool timelineEnabled() const;
- void getCookies(long callId);
- void deleteCookie(const String& cookieName);
-
#if ENABLE(JAVASCRIPT_DEBUGGER)
const ProfilesArray& profiles() const;
@@ -138,8 +135,12 @@ public:
void setAttribute(long callId, long elementId, const String& name, const String& value);
void removeAttribute(long callId, long elementId, const String& name);
void setTextNodeValue(long callId, long nodeId, const String& value);
+ void getEventListenersForNode(long callId, long nodeId);
void copyNode(long nodeId);
+ void getCookies(long callId);
+ void deleteCookie(const String& cookieName);
+
// Generic code called from custom implementations.
void highlight(long nodeId);
Node* nodeForId(long nodeId);
diff --git a/WebCore/inspector/InspectorBackend.idl b/WebCore/inspector/InspectorBackend.idl
index d8ccf9f..5c6babb 100644
--- a/WebCore/inspector/InspectorBackend.idl
+++ b/WebCore/inspector/InspectorBackend.idl
@@ -71,9 +71,6 @@ module core {
void disableResourceTracking(in boolean always);
void storeLastActivePanel(in DOMString panelName);
- void getCookies(in long callId);
- void deleteCookie(in DOMString cookieName);
-
#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
boolean debuggerEnabled();
void enableDebugger(in boolean always);
@@ -109,8 +106,12 @@ module core {
void setAttribute(in long callId, in long elementId, in DOMString name, in DOMString value);
void removeAttribute(in long callId, in long elementId, in DOMString name);
void setTextNodeValue(in long callId, in long nodeId, in DOMString value);
+ void getEventListenersForNode(in long callId, in long nodeId);
void copyNode(in long nodeId);
+ void getCookies(in long callId);
+ void deleteCookie(in DOMString cookieName);
+
// Called from InjectedScript.
[Custom] DOMObject nodeForId(in long nodeId);
[Custom] long wrapObject(in DOMObject object);
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index d893796..db983a1 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -56,6 +56,11 @@
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
+#if USE(JSC)
+#include "JSDOMWindow.h"
+#include <runtime/JSObject.h>
+#endif
+
namespace WebCore {
InspectorDOMAgent::InspectorDOMAgent(InspectorFrontend* frontend)
@@ -363,6 +368,80 @@ void InspectorDOMAgent::setTextNodeValue(long callId, long nodeId, const String&
}
}
+void InspectorDOMAgent::getEventListenersForNode(long callId, long nodeId)
+{
+ Node* node = nodeForId(nodeId);
+ ScriptArray listenersArray = m_frontend->newScriptArray();
+ unsigned counter = 0;
+ EventTargetData* d;
+
+ // Quick break if a null node or no listeners at all
+ if (!node || !(d = node->eventTargetData())) {
+ m_frontend->didGetEventListenersForNode(callId, nodeId, listenersArray);
+ return;
+ }
+
+ // Get the list of event types this Node is concerned with
+ Vector<AtomicString> eventTypes;
+ const EventListenerMap& listenerMap = d->eventListenerMap;
+ HashMap<AtomicString, EventListenerVector>::const_iterator end = listenerMap.end();
+ for (HashMap<AtomicString, EventListenerVector>::const_iterator iter = listenerMap.begin(); iter != end; ++iter)
+ eventTypes.append(iter->first);
+
+ // Quick break if no useful listeners
+ size_t eventTypesLength = eventTypes.size();
+ if (eventTypesLength == 0) {
+ m_frontend->didGetEventListenersForNode(callId, nodeId, listenersArray);
+ return;
+ }
+
+ // The Node's Event Ancestors (not including self)
+ Vector<RefPtr<ContainerNode> > ancestors;
+ node->eventAncestors(ancestors);
+
+ // Nodes and their Listeners for the concerned event types (order is top to bottom)
+ Vector<EventListenerInfo> eventInformation;
+ for (size_t i = ancestors.size(); i; --i) {
+ ContainerNode* ancestor = ancestors[i - 1].get();
+ for (size_t j = 0; j < eventTypesLength; ++j) {
+ AtomicString& type = eventTypes[j];
+ if (ancestor->hasEventListeners(type))
+ eventInformation.append(EventListenerInfo(static_cast<Node*>(ancestor), type, ancestor->getEventListeners(type)));
+ }
+ }
+
+ // Insert the Current Node at the end of that list (last in capturing, first in bubbling)
+ for (size_t i = 0; i < eventTypesLength; ++i) {
+ const AtomicString& type = eventTypes[i];
+ eventInformation.append(EventListenerInfo(node, type, node->getEventListeners(type)));
+ }
+
+ // Get Capturing Listeners (in this order)
+ size_t eventInformationLength = eventInformation.size();
+ for (size_t i = 0; i < eventInformationLength; ++i) {
+ const EventListenerInfo& info = eventInformation[i];
+ const EventListenerVector& vector = info.eventListenerVector;
+ for (size_t j = 0; j < vector.size(); ++j) {
+ const RegisteredEventListener& listener = vector[j];
+ if (listener.useCapture)
+ listenersArray.set(counter++, buildObjectForEventListener(listener, info.eventType, info.node));
+ }
+ }
+
+ // Get Bubbling Listeners (reverse order)
+ for (size_t i = eventInformationLength; i; --i) {
+ const EventListenerInfo& info = eventInformation[i - 1];
+ const EventListenerVector& vector = info.eventListenerVector;
+ for (size_t j = 0; j < vector.size(); ++j) {
+ const RegisteredEventListener& listener = vector[j];
+ if (!listener.useCapture)
+ listenersArray.set(counter++, buildObjectForEventListener(listener, info.eventType, info.node));
+ }
+ }
+
+ m_frontend->didGetEventListenersForNode(callId, nodeId, listenersArray);
+}
+
void InspectorDOMAgent::getCookies(long callId)
{
Document* doc = mainFrameDocument();
@@ -381,6 +460,7 @@ ScriptObject InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeTo
long id = bind(node, nodesMap);
String nodeName;
+ String localName;
String nodeValue;
switch (node->nodeType()) {
@@ -389,18 +469,22 @@ ScriptObject InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeTo
nodeValue = node->nodeValue();
break;
case Node::ATTRIBUTE_NODE:
+ localName = node->localName();
+ break;
case Node::DOCUMENT_FRAGMENT_NODE:
break;
case Node::DOCUMENT_NODE:
case Node::ELEMENT_NODE:
default:
nodeName = node->nodeName();
+ localName = node->localName();
break;
}
value.set("id", static_cast<int>(id));
value.set("nodeType", node->nodeType());
value.set("nodeName", nodeName);
+ value.set("localName", localName);
value.set("nodeValue", nodeValue);
if (node->nodeType() == Node::ELEMENT_NODE) {
@@ -457,6 +541,22 @@ ScriptArray InspectorDOMAgent::buildArrayForContainerChildren(Node* container, i
return children;
}
+ScriptObject InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node)
+{
+ RefPtr<EventListener> eventListener = registeredEventListener.listener;
+ ScriptObject value = m_frontend->newScriptObject();
+ value.set("type", eventType);
+ value.set("useCapture", registeredEventListener.useCapture);
+ value.set("isAttribute", eventListener->isAttribute());
+ value.set("nodeId", static_cast<long long>(pushNodePathToFrontend(node)));
+#if USE(JSC)
+ JSC::JSObject* functionObject = eventListener->jsFunction();
+ if (functionObject)
+ value.set("listener", ScriptObject(m_frontend->scriptState(), functionObject));
+#endif
+ return value;
+}
+
ScriptObject InspectorDOMAgent::buildObjectForCookie(const Cookie& cookie)
{
ScriptObject value = m_frontend->newScriptObject();
diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h
index c430c57..890b4f9 100644
--- a/WebCore/inspector/InspectorDOMAgent.h
+++ b/WebCore/inspector/InspectorDOMAgent.h
@@ -30,7 +30,9 @@
#ifndef InspectorDOMAgent_h
#define InspectorDOMAgent_h
+#include "AtomicString.h"
#include "EventListener.h"
+#include "EventTarget.h"
#include "ScriptArray.h"
#include "ScriptObject.h"
#include "ScriptState.h"
@@ -53,6 +55,19 @@ namespace WebCore {
struct Cookie;
+ struct EventListenerInfo {
+ EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector)
+ : node(node)
+ , eventType(eventType)
+ , eventListenerVector(eventListenerVector)
+ {
+ }
+
+ Node* node;
+ const AtomicString eventType;
+ const EventListenerVector eventListenerVector;
+ };
+
class InspectorDOMAgent : public EventListener {
public:
static const InspectorDOMAgent* cast(const EventListener* listener)
@@ -72,6 +87,7 @@ namespace WebCore {
void setAttribute(long callId, long elementId, const String& name, const String& value);
void removeAttribute(long callId, long elementId, const String& name);
void setTextNodeValue(long callId, long nodeId, const String& value);
+ void getEventListenersForNode(long callId, long nodeId);
void getCookies(long callId);
// Methods called from the InspectorController.
@@ -98,6 +114,8 @@ namespace WebCore {
ScriptArray buildArrayForElementAttributes(Element* element);
ScriptArray buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap);
+ ScriptObject buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node);
+
ScriptObject buildObjectForCookie(const Cookie& cookie);
ScriptArray buildArrayForCookies(const Vector<Cookie>& cookiesList);
diff --git a/WebCore/inspector/InspectorFrontend.cpp b/WebCore/inspector/InspectorFrontend.cpp
index c9793cb..9f329a6 100644
--- a/WebCore/inspector/InspectorFrontend.cpp
+++ b/WebCore/inspector/InspectorFrontend.cpp
@@ -368,6 +368,15 @@ void InspectorFrontend::didApplyDomChange(int callId, bool success)
function->call();
}
+void InspectorFrontend::didGetEventListenersForNode(int callId, int nodeId, ScriptArray& listenersArray)
+{
+ OwnPtr<ScriptFunctionCall> function(newFunctionCall("didGetEventListenersForNode"));
+ function->appendArgument(callId);
+ function->appendArgument(nodeId);
+ function->appendArgument(listenersArray);
+ function->call();
+}
+
void InspectorFrontend::didGetCookies(int callId, const ScriptArray& cookies, const String& cookiesString)
{
OwnPtr<ScriptFunctionCall> function(newFunctionCall("didGetCookies"));
diff --git a/WebCore/inspector/InspectorFrontend.h b/WebCore/inspector/InspectorFrontend.h
index f9d3ba1..397868b 100644
--- a/WebCore/inspector/InspectorFrontend.h
+++ b/WebCore/inspector/InspectorFrontend.h
@@ -115,6 +115,7 @@ namespace WebCore {
void attributesUpdated(int id, const ScriptArray& attributes);
void didGetChildNodes(int callId);
void didApplyDomChange(int callId, bool success);
+ void didGetEventListenersForNode(int callId, int nodeId, ScriptArray& listenersArray);
void timelineWasEnabled();
void timelineWasDisabled();
@@ -125,6 +126,8 @@ namespace WebCore {
void addNodesToSearchResult(const String& nodeIds);
+ ScriptState* scriptState() const { return m_scriptState; }
+
private:
PassOwnPtr<ScriptFunctionCall> newFunctionCall(const String& functionName);
void callSimpleFunction(const String& functionName);
diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js
index 47c8041..3207c25 100644
--- a/WebCore/inspector/front-end/DOMAgent.js
+++ b/WebCore/inspector/front-end/DOMAgent.js
@@ -35,6 +35,7 @@ WebInspector.DOMNode = function(doc, payload) {
this.id = payload.id;
this.nodeType = payload.nodeType;
this.nodeName = payload.nodeName;
+ this.localName = payload.localName;
this._nodeValue = payload.nodeValue;
this.textContent = this.nodeValue;
@@ -473,6 +474,17 @@ WebInspector.Cookies.buildCookiesFromString = function(rawCookieString)
return cookies;
}
+WebInspector.EventListeners = {}
+
+WebInspector.EventListeners.getEventListenersForNodeAsync = function(node, callback)
+{
+ if (!node)
+ return;
+
+ var callId = WebInspector.Callback.wrap(callback);
+ InspectorController.getEventListenersForNode(callId, node.id);
+}
+
WebInspector.CSSStyleDeclaration = function(payload)
{
this.id = payload.id;
@@ -648,3 +660,4 @@ WebInspector.didPerformSearch = WebInspector.Callback.processCallback;
WebInspector.didApplyDomChange = WebInspector.Callback.processCallback;
WebInspector.didRemoveAttribute = WebInspector.Callback.processCallback;
WebInspector.didSetTextNodeValue = WebInspector.Callback.processCallback;
+WebInspector.didGetEventListenersForNode = WebInspector.Callback.processCallback;
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index 928da52..1b61a7b 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -56,6 +56,7 @@ WebInspector.ElementsPanel = function()
this.panel.updateStyles(true);
this.panel.updateMetrics();
this.panel.updateProperties();
+ this.panel.updateEventListeners();
if (InspectorController.searchingForNode()) {
InspectorController.toggleNodeSearch();
@@ -76,10 +77,12 @@ WebInspector.ElementsPanel = function()
this.sidebarPanes.styles = new WebInspector.StylesSidebarPane();
this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane();
this.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane();
+ this.sidebarPanes.eventListeners = new WebInspector.EventListenersSidebarPane();
this.sidebarPanes.styles.onexpand = this.updateStyles.bind(this);
this.sidebarPanes.metrics.onexpand = this.updateMetrics.bind(this);
this.sidebarPanes.properties.onexpand = this.updateProperties.bind(this);
+ this.sidebarPanes.eventListeners.onexpand = this.updateEventListeners.bind(this);
this.sidebarPanes.styles.expanded = true;
@@ -93,6 +96,7 @@ WebInspector.ElementsPanel = function()
this.sidebarElement.appendChild(this.sidebarPanes.styles.element);
this.sidebarElement.appendChild(this.sidebarPanes.metrics.element);
this.sidebarElement.appendChild(this.sidebarPanes.properties.element);
+ this.sidebarElement.appendChild(this.sidebarPanes.eventListeners.element);
this.sidebarResizeElement = document.createElement("div");
this.sidebarResizeElement.className = "sidebar-resizer-vertical";
@@ -977,6 +981,16 @@ WebInspector.ElementsPanel.prototype = {
propertiesSidebarPane.needsUpdate = false;
},
+ updateEventListeners: function()
+ {
+ var eventListenersSidebarPane = this.sidebarPanes.eventListeners;
+ if (!eventListenersSidebarPane.expanded || !eventListenersSidebarPane.needsUpdate)
+ return;
+
+ eventListenersSidebarPane.update(this.focusedDOMNode);
+ eventListenersSidebarPane.needsUpdate = false;
+ },
+
handleKeyEvent: function(event)
{
this.treeOutline.handleKeyEvent(event);
diff --git a/WebCore/inspector/front-end/EventListenersSidebarPane.js b/WebCore/inspector/front-end/EventListenersSidebarPane.js
new file mode 100644
index 0000000..a593cb8
--- /dev/null
+++ b/WebCore/inspector/front-end/EventListenersSidebarPane.js
@@ -0,0 +1,205 @@
+/*
+ * 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";
+ if (Preferences.eventListenersFilter === "all")
+ option.selected = true;
+ option.label = WebInspector.UIString("All Nodes");
+ this.settingsSelectElement.appendChild(option);
+
+ option = document.createElement("option");
+ option.value = "selected";
+ if (Preferences.eventListenersFilter === "selected")
+ option.selected = true;
+ option.label = WebInspector.UIString("Selected Node Only");
+ this.settingsSelectElement.appendChild(option);
+
+ 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(nodeId, eventListeners) {
+ var sectionNames = [];
+ var sectionMap = {};
+ for (var i = 0; i < eventListeners.length; ++i) {
+ var eventListener = eventListeners[i];
+ eventListener._selectedNode = (eventListener.nodeId === nodeId);
+ eventListener.node = WebInspector.domAgent.nodeForId(eventListener.nodeId);
+ delete eventListener.nodeId; // no longer needed
+ var type = eventListener.type;
+ var section = sectionMap[type];
+ if (!section) {
+ section = new WebInspector.EventListenersSection(type);
+ 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);
+ }
+ }
+
+ WebInspector.EventListeners.getEventListenersForNodeAsync(node, callback);
+ },
+
+ _changeSetting: function(event)
+ {
+ var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
+ Preferences.eventListenersFilter = selectedOption.value;
+
+ InspectorController.setSetting("event-listeners-filter", Preferences.eventListenersFilter);
+
+ for (var i = 0; i < this.sections.length; ++i)
+ this.sections[i].update();
+ }
+}
+
+WebInspector.EventListenersSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+
+WebInspector.EventListenersSection = function(title, subtitle)
+{
+ this.eventListeners = [];
+ WebInspector.PropertiesSection.call(this, title, subtitle);
+
+ // 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 (Preferences.eventListenersFilter === "selected") {
+ filteredEventListeners = [];
+ for (var i = 0; i < this.eventListeners.length; ++i) {
+ var eventListener = this.eventListeners[i];
+ if (eventListener._selectedNode)
+ 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);
+ if (i < length - 1) {
+ var connector = document.createElement("div");
+ connector.className = "event-bar-connector";
+ eventListenerBar.element.appendChild(connector);
+ }
+
+ this.eventBars.appendChild(eventListenerBar.element);
+ }
+ },
+
+ addListener: function(eventListener)
+ {
+ this.eventListeners.push(eventListener);
+ }
+}
+
+WebInspector.EventListenersSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
+
+WebInspector.EventListenerBar = function(eventListener)
+{
+ this.eventListener = eventListener;
+ WebInspector.ObjectPropertiesSection.call(this, InspectorController.wrapObject(eventListener), this._getFunctionDisplayName(), this._getNodeDisplayName());
+ this.element.className = "event-bar"; /* Changed from "section" */
+ this.propertiesElement.className = "event-properties"; /* Changed from "properties" */
+}
+
+WebInspector.EventListenerBar.prototype = {
+ _getNodeDisplayName: function()
+ {
+ var node = this.eventListener.node;
+ if (!node)
+ return "";
+
+ if (node.nodeType === Node.DOCUMENT_NODE)
+ return "document";
+
+ return appropriateSelectorForNode(node);
+ },
+
+ _getFunctionDisplayName: function()
+ {
+ // TODO: v8 does not yet provide the raw function, this handles such a case with a placeholder
+ // I didn't make this a UIString because it should be implemented eventually.
+ if (!this.eventListener.listener)
+ return "(listener)";
+
+ // Requires that Function.toString() return at least the function's signature
+ var match = this.eventListener.listener.toString().match(/function ([^\(]+?)\(/);
+ return (match ? match[1] : WebInspector.UIString("(anonymous function)"));
+ }
+}
+
+WebInspector.EventListenerBar.prototype.__proto__ = WebInspector.ObjectPropertiesSection.prototype;
diff --git a/WebCore/inspector/front-end/Images/grayConnectorPoint.png b/WebCore/inspector/front-end/Images/grayConnectorPoint.png
new file mode 100644
index 0000000..fddc7ea
Binary files /dev/null and b/WebCore/inspector/front-end/Images/grayConnectorPoint.png differ
diff --git a/WebCore/inspector/front-end/Images/whiteConnectorPoint.png b/WebCore/inspector/front-end/Images/whiteConnectorPoint.png
new file mode 100644
index 0000000..c8fb1cf
Binary files /dev/null and b/WebCore/inspector/front-end/Images/whiteConnectorPoint.png differ
diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js
index 6185aff..3582f96 100644
--- a/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -348,7 +348,7 @@ WebInspector.StylesSidebarPane.prototype = {
addBlankSection: function()
{
- var blankSection = new WebInspector.BlankStylePropertiesSection(this.appropriateSelectorForNode());
+ var blankSection = new WebInspector.BlankStylePropertiesSection(appropriateSelectorForNode(this.node, true));
blankSection.pane = this;
var elementStyleSection = this.sections[1];
@@ -367,27 +367,6 @@ WebInspector.StylesSidebarPane.prototype = {
this.sections.splice(index, 1);
if (section.element.parentNode)
section.element.parentNode.removeChild(section.element);
- },
-
- appropriateSelectorForNode: function()
- {
- var node = this.node;
- if (!node)
- return "";
-
- var id = node.getAttribute("id");
- if (id)
- return "#" + id;
-
- var className = node.getAttribute("class");
- if (className)
- return "." + className.replace(/\s+/, ".");
-
- var nodeName = node.nodeName.toLowerCase();
- if (nodeName === "input" && node.getAttribute("type"))
- return nodeName + "[type=\"" + node.getAttribute("type") + "\"]";
-
- return nodeName;
}
}
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index 0c50bb7..1aaeb3d 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -21,6 +21,7 @@
<file>Drawer.js</file>
<file>ElementsPanel.js</file>
<file>ElementsTreeOutline.js</file>
+ <file>EventListenersSidebarPane.js</file>
<file>FontView.js</file>
<file>ImageView.js</file>
<file>InjectedScript.js</file>
@@ -103,6 +104,7 @@
<file>Images/goArrow.png</file>
<file>Images/graphLabelCalloutLeft.png</file>
<file>Images/graphLabelCalloutRight.png</file>
+ <file>Images/grayConnectorPoint.png</file>
<file>Images/largerResourcesButtonGlyph.png</file>
<file>Images/localStorage.png</file>
<file>Images/nodeSearchButtonGlyph.png</file>
@@ -188,5 +190,6 @@
<file>Images/warningMediumIcon.png</file>
<file>Images/warningOrangeDot.png</file>
<file>Images/warningsErrors.png</file>
+ <file>Images/whiteConnectorPoint.png</file>
</qresource>
</RCC>
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 4513886..358c13c 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -1222,7 +1222,7 @@ body.inactive .placard.selected {
margin-top: 1px;
}
-.section:nth-last-of-type(1) {
+.section:nth-last-of-type(1), .event-bar:nth-last-of-type(1) {
margin-bottom: 1px;
}
@@ -1230,6 +1230,14 @@ body.inactive .placard.selected {
text-align: center;
}
+.event-bar:first-child {
+ margin-top: 1px;
+}
+
+.event-bar:nth-last-of-type(1) .header {
+ border-bottom: 1px solid rgb(163, 163, 163);
+}
+
.section .header {
padding: 2px 8px 4px 18px;
border-top: 1px solid rgb(145, 160, 192);
@@ -1261,7 +1269,7 @@ body.inactive .placard.selected {
content: url(Images/treeDownTriangleWhite.png);
}
-.section .header .title {
+.section .header .title, .event-bar .header .title {
color: white;
font-weight: bold;
word-wrap: break-word;
@@ -1272,11 +1280,11 @@ body.inactive .placard.selected {
font-style: italic;
}
-.section .header label {
+.section .header label, .event-bar .header label {
display: none;
}
-.section.expanded .header label {
+.section.expanded .header label, .event-bar.expanded .header label {
display: inline;
}
@@ -1289,7 +1297,7 @@ body.inactive .placard.selected {
vertical-align: 2px;
}
-.section .header .subtitle {
+.section .header .subtitle, .event-bar .header .subtitle {
float: right;
font-size: 10px;
margin-left: 5px;
@@ -1303,7 +1311,7 @@ body.inactive .placard.selected {
color: inherit;
}
-.section .properties {
+.section .properties, .event-bar .event-properties {
display: none;
margin: 0;
padding: 2px 6px 3px;
@@ -1320,11 +1328,11 @@ body.inactive .placard.selected {
opacity: 1.0;
}
-.section.expanded .properties {
+.section.expanded .properties, .event-bar.expanded .event-properties {
display: block;
}
-.section .properties li {
+.section .properties li, .event-properties li {
margin-left: 12px;
white-space: nowrap;
text-overflow: ellipsis;
@@ -1333,22 +1341,22 @@ body.inactive .placard.selected {
cursor: auto;
}
-.section .properties li.parent {
+.section .properties li.parent, .event-properties li.parent {
margin-left: 1px;
}
-.section .properties ol {
+.section .properties ol, .event-properties ol {
display: none;
margin: 0;
-webkit-padding-start: 12px;
list-style: none;
}
-.section .properties ol.expanded {
+.section .properties ol.expanded, .event-properties ol.expanded {
display: block;
}
-.section .properties li.parent::before {
+.section .properties li.parent::before, .event-properties li.parent::before {
content: url(Images/treeRightTriangleBlack.png);
opacity: 0.75;
float: left;
@@ -1360,16 +1368,79 @@ body.inactive .placard.selected {
cursor: default;
}
-.section .properties li.parent.expanded::before {
+.section .properties li.parent.expanded::before, .event-properties li.parent.expanded::before {
content: url(Images/treeDownTriangleBlack.png);
margin-top: 1px;
}
-.section .properties li .info {
+.section .properties li .info, .event-properties li .info {
padding-top: 4px;
padding-bottom: 3px;
}
+.section .event-bars {
+ display: none;
+}
+
+.section.expanded .event-bars {
+ display: block;
+}
+
+.event-bar {
+ position: relative;
+}
+
+.event-bar-connector {
+ position: absolute;
+ left: 75%;
+ bottom: -7px;
+ margin-left: -7px;
+ content: url(Images/grayConnectorPoint.png);
+ z-index: 3;
+}
+
+.event-bar.expanded .event-bar-connector {
+ content: url(Images/whiteConnectorPoint.png);
+}
+
+.event-bars .event-bar .header {
+ padding: 2px 8px 4px 18px;
+ border-top: 1px solid rgb(163, 163, 163);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(243, 243, 243)), to(rgb(207, 207, 207)));
+ min-height: 18px;
+ white-space: nowrap;
+ -webkit-background-origin: padding;
+ -webkit-background-clip: padding;
+}
+
+.event-bars .event-bar.expanded .header {
+ border-bottom: 1px solid rgb(163, 163, 163);
+}
+
+.event-bars .event-bar .header .title {
+ font-weight: bold;
+ color: #333;
+ text-shadow: white 0 1px 0;
+}
+
+.event-bars .event-bar .header .subtitle {
+ color: rgba(90, 90, 90, 0.742188);
+}
+
+.event-bars .event-bar .header::before {
+ position: absolute;
+ top: 4px;
+ left: 7px;
+ width: 8px;
+ height: 8px;
+ opacity: 0.75;
+ content: url(Images/treeRightTriangleBlack.png);
+}
+
+.event-bars .event-bar.expanded .header::before {
+ content: url(Images/treeDownTriangleBlack.png);
+}
+
.editing {
-webkit-user-select: text;
-webkit-box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;
@@ -1461,7 +1532,7 @@ li.editing .swatch, li.editing .enabled-button, li.editing-sub-part .delete-but
display: block;
}
-.section .properties .name {
+.section .properties .name, .event-properties .name {
color: rgb(136, 19, 145);
}
@@ -1469,7 +1540,7 @@ li.editing .swatch, li.editing .enabled-button, li.editing-sub-part .delete-but
color: rgb(100, 100, 100);
}
-.section .properties .number {
+.section .properties .number, .event-properties .number {
color: blue;
}
@@ -1477,11 +1548,11 @@ li.editing .swatch, li.editing .enabled-button, li.editing-sub-part .delete-but
color: rgb(128, 0, 0);
}
-.section .properties .keyword {
+.section .properties .keyword, .event-properties .keyword {
color: rgb(136, 19, 79);
}
-.section .properties .color {
+.section .properties .color, .event-properties .color {
color: rgb(118, 15, 21);
}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index 7f544fe..f54e302 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -65,6 +65,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="WatchExpressionsSidebarPane.js"></script>
<script type="text/javascript" src="MetricsSidebarPane.js"></script>
<script type="text/javascript" src="PropertiesSidebarPane.js"></script>
+ <script type="text/javascript" src="EventListenersSidebarPane.js"></script>
<script type="text/javascript" src="Color.js"></script>
<script type="text/javascript" src="StylesSidebarPane.js"></script>
<script type="text/javascript" src="Panel.js"></script>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 921bb7a..b6de65e 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -42,7 +42,8 @@ var Preferences = {
heapProfilerPresent: false,
samplingCPUProfiler: false,
showColorNicknames: true,
- colorFormat: "hex"
+ colorFormat: "hex",
+ eventListenersFilter: "all"
}
var WebInspector = {
@@ -354,6 +355,10 @@ WebInspector.loaded = function()
if (colorFormat)
Preferences.colorFormat = colorFormat;
+ var eventListenersFilter = InspectorController.setting("event-listeners-filter");
+ if (eventListenersFilter)
+ Preferences.eventListenersFilter = eventListenersFilter;
+
this.drawer = new WebInspector.Drawer();
this.console = new WebInspector.ConsoleView(this.drawer);
// TODO: Uncomment when enabling the Changes Panel
diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js
index e83c7c0..5f41b56 100644
--- a/WebCore/inspector/front-end/utilities.js
+++ b/WebCore/inspector/front-end/utilities.js
@@ -621,11 +621,38 @@ function nodeTitleInfo(hasChildren, linkify)
return info;
}
-function getDocumentForNode(node) {
+function appropriateSelectorForNode(node, justSelector)
+{
+ if (!node)
+ return "";
+
+ var lowerCaseName = node.localName || node.nodeName.toLowerCase();
+
+ var id = node.getAttribute("id");
+ if (id) {
+ var selector = "#" + id;
+ return (justSelector ? selector : lowerCaseName + selector);
+ }
+
+ var className = node.getAttribute("class");
+ if (className) {
+ var selector = "." + className.replace(/\s+/, ".");
+ return (justSelector ? selector : lowerCaseName + selector);
+ }
+
+ if (lowerCaseName === "input" && node.getAttribute("type"))
+ return lowerCaseName + "[type=\"" + node.getAttribute("type") + "\"]";
+
+ return lowerCaseName;
+}
+
+function getDocumentForNode(node)
+{
return node.nodeType == Node.DOCUMENT_NODE ? node : node.ownerDocument;
}
-function parentNode(node) {
+function parentNode(node)
+{
return node.parentNode;
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list