Diff
Modified: trunk/Source/WebCore/ChangeLog (142574 => 142575)
--- trunk/Source/WebCore/ChangeLog 2013-02-12 04:34:21 UTC (rev 142574)
+++ trunk/Source/WebCore/ChangeLog 2013-02-12 04:43:56 UTC (rev 142575)
@@ -1,3 +1,64 @@
+2013-02-11 Hayato Ito <[email protected]>
+
+ Factor EventContext and introduces MouseOrFocusEventContext.
+ https://bugs.webkit.org/show_bug.cgi?id=109278
+
+ Reviewed by Dimitri Glazkov.
+
+ To supoort Touch event retargeting (bug 107800), we have to factor
+ event retargeting code so that it can support not only MouseEvent or FocusEvent,
+ but also other events.
+
+ This is the first attempt to refactor event retargeting code, a
+ separated patch from bug 109156. EventContext is now factored and
+ MouseOrFocusEventContext was introduced to support MouseEvent or
+ FocusEvent separately.
+
+ In following patches, I'll introduce TouchEventContext and
+ TouchEventDispatchMediator to support Touch event retargeting.
+
+ No new tests. No change in functionality.
+
+ * dom/EventContext.cpp:
+ (WebCore::EventContext::EventContext): Factor relatedTarget out from EventContext into MouseOrFocusEventContext.
+ (WebCore::EventContext::~EventContext):
+ (WebCore):
+ (WebCore::EventContext::handleLocalEvents):
+ (WebCore::EventContext::isMouseOrFocusEventContext):
+ (WebCore::MouseOrFocusEventContext::MouseOrFocusEventContext): New. Handles MouseEvent's (or FocusEvent's) relatedTarget retargeting.
+ (WebCore::MouseOrFocusEventContext::~MouseOrFocusEventContext):
+ (WebCore::MouseOrFocusEventContext::handleLocalEvents):
+ (WebCore::MouseOrFocusEventContext::isMouseOrFocusEventContext):
+ * dom/EventContext.h:
+ (EventContext):
+ (WebCore::EventContext::node):
+ (WebCore::EventContext::target):
+ (WebCore::EventContext::currentTargetSameAsTarget):
+ (WebCore):
+ (MouseOrFocusEventContext):
+ (WebCore::MouseOrFocusEventContext::relatedTarget):
+ (WebCore::MouseOrFocusEventContext::setRelatedTarget):
+ * dom/EventDispatcher.cpp:
+ (WebCore::EventRelatedTargetAdjuster::adjust):
+ (WebCore::EventDispatcher::adjustRelatedTarget):
+ (WebCore::EventDispatcher::ensureEventPath): Renamad from ensureEventAncestors. Use the DOM Core terminology.
+ (WebCore::EventDispatcher::dispatchEvent):
+ (WebCore::EventDispatcher::dispatchEventAtCapturing):
+ (WebCore::EventDispatcher::dispatchEventAtTarget):
+ (WebCore::EventDispatcher::dispatchEventAtBubbling):
+ (WebCore::EventDispatcher::dispatchEventPostProcess):
+ (WebCore::EventDispatcher::topEventContext):
+ * dom/EventDispatcher.h:
+ (EventRelatedTargetAdjuster):
+ (EventDispatcher):
+ * inspector/InspectorInstrumentation.cpp:
+ (WebCore):
+ (WebCore::eventHasListeners):
+ (WebCore::InspectorInstrumentation::willDispatchEventImpl):
+ * inspector/InspectorInstrumentation.h:
+ (InspectorInstrumentation):
+ (WebCore::InspectorInstrumentation::willDispatchEvent):
+
2013-02-11 [email protected] <[email protected]>
[Curl] setCookiesFromDOM function does not save cookies to disk.
Modified: trunk/Source/WebCore/dom/EventContext.cpp (142574 => 142575)
--- trunk/Source/WebCore/dom/EventContext.cpp 2013-02-12 04:34:21 UTC (rev 142574)
+++ trunk/Source/WebCore/dom/EventContext.cpp 2013-02-12 04:43:56 UTC (rev 142575)
@@ -40,21 +40,50 @@
: m_node(node)
, m_currentTarget(currentTarget)
, m_target(target)
- , m_relatedTarget(0)
{
ASSERT(m_node);
ASSERT(!isUnreachableNode(m_target.get()));
}
+EventContext::~EventContext()
+{
+}
+
void EventContext::handleLocalEvents(Event* event) const
{
event->setTarget(m_target.get());
event->setCurrentTarget(m_currentTarget.get());
+ m_node->handleLocalEvents(event);
+}
+
+bool EventContext::isMouseOrFocusEventContext() const
+{
+ return false;
+}
+
+MouseOrFocusEventContext::MouseOrFocusEventContext(PassRefPtr<Node> node, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target)
+ : EventContext(node, currentTarget, target)
+ , m_relatedTarget(0)
+{
+}
+
+MouseOrFocusEventContext::~MouseOrFocusEventContext()
+{
+}
+
+void MouseOrFocusEventContext::handleLocalEvents(Event* event) const
+{
+ ASSERT(event->isMouseEvent() || event->isFocusEvent());
if (m_relatedTarget.get() && event->isMouseEvent())
toMouseEvent(event)->setRelatedTarget(m_relatedTarget.get());
else if (m_relatedTarget.get() && event->isFocusEvent())
- toFocusEvent(event)->setRelatedTarget(m_relatedTarget);
- m_node->handleLocalEvents(event);
+ toFocusEvent(event)->setRelatedTarget(m_relatedTarget.get());
+ EventContext::handleLocalEvents(event);
}
+bool MouseOrFocusEventContext::isMouseOrFocusEventContext() const
+{
+ return true;
}
+
+}
Modified: trunk/Source/WebCore/dom/EventContext.h (142574 => 142575)
--- trunk/Source/WebCore/dom/EventContext.h 2013-02-12 04:34:21 UTC (rev 142574)
+++ trunk/Source/WebCore/dom/EventContext.h 2013-02-12 04:43:56 UTC (rev 142575)
@@ -40,15 +40,15 @@
public:
// FIXME: Use ContainerNode instead of Node.
EventContext(PassRefPtr<Node>, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target);
+ virtual ~EventContext();
- Node* node() const;
- EventTarget* target() const;
- EventTarget* relatedTarget() const;
- bool currentTargetSameAsTarget() const;
- void handleLocalEvents(Event*) const;
- void setRelatedTarget(PassRefPtr<EventTarget>);
+ Node* node() const { return m_node.get(); }
+ EventTarget* target() const { return m_target.get(); }
+ bool currentTargetSameAsTarget() const { return m_currentTarget.get() == m_target.get(); }
+ virtual void handleLocalEvents(Event*) const;
+ virtual bool isMouseOrFocusEventContext() const;
-private:
+protected:
#ifndef NDEBUG
bool isUnreachableNode(EventTarget*);
bool isReachable(Node*);
@@ -56,35 +56,23 @@
RefPtr<Node> m_node;
RefPtr<EventTarget> m_currentTarget;
RefPtr<EventTarget> m_target;
- RefPtr<EventTarget> m_relatedTarget;
};
-inline Node* EventContext::node() const
-{
- return m_node.get();
-}
+typedef Vector<OwnPtr<EventContext>, 32> EventPath;
-inline EventTarget* EventContext::target() const
-{
- return m_target.get();
-}
+class MouseOrFocusEventContext : public EventContext {
+public:
+ MouseOrFocusEventContext(PassRefPtr<Node>, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target);
+ virtual ~MouseOrFocusEventContext();
+ EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
+ void setRelatedTarget(PassRefPtr<EventTarget>);
+ virtual void handleLocalEvents(Event*) const OVERRIDE;
+ virtual bool isMouseOrFocusEventContext() const OVERRIDE;
-inline bool EventContext::currentTargetSameAsTarget() const
-{
- return m_currentTarget.get() == m_target.get();
-}
+private:
+ RefPtr<EventTarget> m_relatedTarget;
+};
-inline EventTarget* EventContext::relatedTarget() const
-{
- return m_relatedTarget.get();
-}
-
-inline void EventContext::setRelatedTarget(PassRefPtr<EventTarget> relatedTarget)
-{
- ASSERT(!isUnreachableNode(relatedTarget.get()));
- m_relatedTarget = relatedTarget;
-}
-
#ifndef NDEBUG
inline bool EventContext::isUnreachableNode(EventTarget* target)
{
@@ -104,6 +92,12 @@
}
#endif
+inline void MouseOrFocusEventContext::setRelatedTarget(PassRefPtr<EventTarget> relatedTarget)
+{
+ ASSERT(!isUnreachableNode(relatedTarget.get()));
+ m_relatedTarget = relatedTarget;
}
+}
+
#endif // EventContext_h
Modified: trunk/Source/WebCore/dom/EventDispatcher.cpp (142574 => 142575)
--- trunk/Source/WebCore/dom/EventDispatcher.cpp 2013-02-12 04:34:21 UTC (rev 142574)
+++ trunk/Source/WebCore/dom/EventDispatcher.cpp 2013-02-12 04:43:56 UTC (rev 142575)
@@ -60,7 +60,7 @@
ASSERT(m_relatedTarget);
}
-void EventRelatedTargetAdjuster::adjust(Vector<EventContext, 32>& ancestors)
+void EventRelatedTargetAdjuster::adjust(EventPath& eventPath)
{
// Synthetic mouse events can have a relatedTarget which is identical to the target.
bool targetIsIdenticalToToRelatedTarget = (m_node.get() == m_relatedTarget.get());
@@ -86,24 +86,26 @@
lastTreeScope = 0;
EventTarget* adjustedRelatedTarget = 0;
- for (Vector<EventContext, 32>::iterator iter = ancestors.begin(); iter < ancestors.end(); ++iter) {
- TreeScope* scope = iter->node()->treeScope();
+ for (EventPath::iterator iter = eventPath.begin(); iter < eventPath.end(); ++iter) {
+ ASSERT((*iter)->isMouseOrFocusEventContext());
+ MouseOrFocusEventContext* mosueOrFocusEventContext = static_cast<MouseOrFocusEventContext*>(iter->get());
+ TreeScope* scope = mosueOrFocusEventContext->node()->treeScope();
if (scope == lastTreeScope) {
// Re-use the previous adjustedRelatedTarget if treeScope does not change. Just for the performance optimization.
- iter->setRelatedTarget(adjustedRelatedTarget);
+ mosueOrFocusEventContext->setRelatedTarget(adjustedRelatedTarget);
} else {
adjustedRelatedTarget = findRelatedTarget(scope);
- iter->setRelatedTarget(adjustedRelatedTarget);
+ mosueOrFocusEventContext->setRelatedTarget(adjustedRelatedTarget);
}
lastTreeScope = scope;
if (targetIsIdenticalToToRelatedTarget) {
- if (m_node->treeScope()->rootNode() == iter->node()) {
- ancestors.shrink(iter + 1 - ancestors.begin());
+ if (m_node->treeScope()->rootNode() == mosueOrFocusEventContext->node()) {
+ eventPath.shrink(iter + 1 - eventPath.begin());
break;
}
- } else if (iter->target() == adjustedRelatedTarget) {
+ } else if (mosueOrFocusEventContext->target() == adjustedRelatedTarget) {
// Event dispatching should be stopped here.
- ancestors.shrink(iter - ancestors.begin());
+ eventPath.shrink(iter - eventPath.begin());
break;
}
}
@@ -169,13 +171,13 @@
return;
if (!m_node.get())
return;
- ensureEventAncestors(event);
- EventRelatedTargetAdjuster(m_node, relatedTarget.release()).adjust(m_ancestors);
+ ensureEventPath(event);
+ EventRelatedTargetAdjuster(m_node, relatedTarget.release()).adjust(m_eventPath);
}
EventDispatcher::EventDispatcher(Node* node)
: m_node(node)
- , m_ancestorsInitialized(false)
+ , m_eventPathInitialized(false)
#ifndef NDEBUG
, m_eventDispatched(false)
#endif
@@ -184,13 +186,14 @@
m_view = node->document()->view();
}
-void EventDispatcher::ensureEventAncestors(Event* event)
+void EventDispatcher::ensureEventPath(Event* event)
{
- if (m_ancestorsInitialized)
+ if (m_eventPathInitialized)
return;
- m_ancestorsInitialized = true;
+ m_eventPathInitialized = true;
bool inDocument = m_node->inDocument();
bool isSVGElement = m_node->isSVGElement();
+ bool isMouseOrFocusEvent = event->isMouseEvent() || event->isFocusEvent();
Vector<EventTarget*, 32> targetStack;
for (AncestorChainWalker walker(m_node.get()); walker.get(); walker.parent()) {
Node* node = walker.get();
@@ -198,7 +201,10 @@
targetStack.append(eventTargetRespectingTargetRules(node));
else if (walker.crossingInsertionPoint())
targetStack.append(targetStack.last());
- m_ancestors.append(EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last()));
+ if (isMouseOrFocusEvent)
+ m_eventPath.append(adoptPtr(new MouseOrFocusEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
+ else
+ m_eventPath.append(adoptPtr(new EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
if (!inDocument)
return;
if (!node->isShadowRoot())
@@ -260,9 +266,9 @@
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
ASSERT(event->target());
ASSERT(!event->type().isNull()); // _javascript_ code can create an event with an empty name, but not null.
- ensureEventAncestors(event.get());
+ ensureEventPath(event.get());
WindowEventContext windowEventContext(event.get(), m_node.get(), topEventContext());
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowEventContext.window(), m_node.get(), m_ancestors);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowEventContext.window(), m_node.get(), m_eventPath);
void* preDispatchEventHandlerResult;
if (dispatchEventPreProcess(event, preDispatchEventHandlerResult) == ContinueDispatching)
@@ -284,7 +290,7 @@
{
// Give the target node a chance to do some work before DOM event handlers get a crack.
preDispatchEventHandlerResult = m_node->preDispatchEventHandler(event.get());
- return (m_ancestors.isEmpty() || event->propagationStopped()) ? DoneDispatching : ContinueDispatching;
+ return (m_eventPath.isEmpty() || event->propagationStopped()) ? DoneDispatching : ContinueDispatching;
}
inline EventDispatchContinuation EventDispatcher::dispatchEventAtCapturing(PassRefPtr<Event> event, WindowEventContext& windowEventContext)
@@ -295,8 +301,8 @@
if (windowEventContext.handleLocalEvents(event.get()) && event->propagationStopped())
return DoneDispatching;
- for (size_t i = m_ancestors.size() - 1; i > 0; --i) {
- const EventContext& eventContext = m_ancestors[i];
+ for (size_t i = m_eventPath.size() - 1; i > 0; --i) {
+ const EventContext& eventContext = *m_eventPath[i];
if (eventContext.currentTargetSameAsTarget()) {
if (event->bubbles())
continue;
@@ -314,7 +320,7 @@
inline EventDispatchContinuation EventDispatcher::dispatchEventAtTarget(PassRefPtr<Event> event)
{
event->setEventPhase(Event::AT_TARGET);
- m_ancestors[0].handleLocalEvents(event.get());
+ m_eventPath[0]->handleLocalEvents(event.get());
return event->propagationStopped() ? DoneDispatching : ContinueDispatching;
}
@@ -324,9 +330,9 @@
// Trigger bubbling event handlers, starting at the bottom and working our way up.
event->setEventPhase(Event::BUBBLING_PHASE);
- size_t size = m_ancestors.size();
+ size_t size = m_eventPath.size();
for (size_t i = 1; i < size; ++i) {
- const EventContext& eventContext = m_ancestors[i];
+ const EventContext& eventContext = *m_eventPath[i];
if (eventContext.currentTargetSameAsTarget())
event->setEventPhase(Event::AT_TARGET);
else
@@ -361,9 +367,9 @@
// For bubbling events, call default event handlers on the same targets in the
// same order as the bubbling phase.
if (event->bubbles()) {
- size_t size = m_ancestors.size();
+ size_t size = m_eventPath.size();
for (size_t i = 1; i < size; ++i) {
- m_ancestors[i].node()->defaultEventHandler(event.get());
+ m_eventPath[i]->node()->defaultEventHandler(event.get());
ASSERT(!event->defaultPrevented());
if (event->defaultHandled())
return;
@@ -374,7 +380,7 @@
const EventContext* EventDispatcher::topEventContext()
{
- return m_ancestors.isEmpty() ? 0 : &m_ancestors.last();
+ return m_eventPath.isEmpty() ? 0 : m_eventPath.last().get();
}
static inline bool inTheSameScope(ShadowRoot* shadowRoot, EventTarget* target)
Modified: trunk/Source/WebCore/dom/EventDispatcher.h (142574 => 142575)
--- trunk/Source/WebCore/dom/EventDispatcher.h 2013-02-12 04:34:21 UTC (rev 142574)
+++ trunk/Source/WebCore/dom/EventDispatcher.h 2013-02-12 04:43:56 UTC (rev 142575)
@@ -58,7 +58,7 @@
class EventRelatedTargetAdjuster {
public:
EventRelatedTargetAdjuster(PassRefPtr<Node>, PassRefPtr<Node> relatedTarget);
- void adjust(Vector<EventContext, 32>&);
+ void adjust(EventPath&);
private:
typedef HashMap<TreeScope*, EventTarget*> RelatedTargetMap;
EventTarget* findRelatedTarget(TreeScope*);
@@ -84,7 +84,7 @@
EventDispatchBehavior determineDispatchBehavior(Event*, ShadowRoot*, EventTarget*);
- void ensureEventAncestors(Event*);
+ void ensureEventPath(Event*);
const EventContext* topEventContext();
EventDispatchContinuation dispatchEventPreProcess(PassRefPtr<Event>, void*& preDispatchEventHandlerResult);
@@ -93,10 +93,10 @@
EventDispatchContinuation dispatchEventAtBubbling(PassRefPtr<Event>, WindowEventContext&);
void dispatchEventPostProcess(PassRefPtr<Event>, void* preDispatchEventHandlerResult);
- Vector<EventContext, 32> m_ancestors;
+ EventPath m_eventPath;
RefPtr<Node> m_node;
RefPtr<FrameView> m_view;
- bool m_ancestorsInitialized;
+ bool m_eventPathInitialized;
#ifndef NDEBUG
bool m_eventDispatched;
#endif
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (142574 => 142575)
--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp 2013-02-12 04:34:21 UTC (rev 142574)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp 2013-02-12 04:43:56 UTC (rev 142575)
@@ -93,7 +93,7 @@
int InspectorInstrumentation::s_frontendCounter = 0;
-static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
+static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const EventPath& eventPath)
{
if (window && window->hasEventListeners(eventType))
return true;
@@ -101,9 +101,8 @@
if (node->hasEventListeners(eventType))
return true;
- for (size_t i = 0; i < ancestors.size(); i++) {
- Node* ancestor = ancestors[i].node();
- if (ancestor->hasEventListeners(eventType))
+ for (size_t i = 0; i < eventPath.size(); i++) {
+ if (eventPath[i]->node()->hasEventListeners(eventType))
return true;
}
@@ -387,11 +386,11 @@
timelineAgent->didDispatchXHRReadyStateChangeEvent();
}
-InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents* instrumentingAgents, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors, Document* document)
+InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents* instrumentingAgents, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath, Document* document)
{
int timelineAgentId = 0;
InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent();
- if (timelineAgent && eventHasListeners(event.type(), window, node, ancestors)) {
+ if (timelineAgent && eventHasListeners(event.type(), window, node, eventPath)) {
timelineAgent->willDispatchEvent(event, document->frame());
timelineAgentId = timelineAgent->id();
}
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (142574 => 142575)
--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h 2013-02-12 04:34:21 UTC (rev 142574)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h 2013-02-12 04:43:56 UTC (rev 142575)
@@ -35,6 +35,7 @@
#include "ConsoleAPITypes.h"
#include "ConsoleTypes.h"
#include "Element.h"
+#include "EventContext.h"
#include "Frame.h"
#include "HitTestResult.h"
#include "Page.h"
@@ -143,7 +144,7 @@
static void didCallFunction(const InspectorInstrumentationCookie&);
static InspectorInstrumentationCookie willDispatchXHRReadyStateChangeEvent(ScriptExecutionContext*, XMLHttpRequest*);
static void didDispatchXHRReadyStateChangeEvent(const InspectorInstrumentationCookie&);
- static InspectorInstrumentationCookie willDispatchEvent(Document*, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors);
+ static InspectorInstrumentationCookie willDispatchEvent(Document*, const Event&, DOMWindow*, Node*, const EventPath&);
static void didDispatchEvent(const InspectorInstrumentationCookie&);
static InspectorInstrumentationCookie willHandleEvent(ScriptExecutionContext*, Event*);
static void didHandleEvent(const InspectorInstrumentationCookie&);
@@ -347,7 +348,7 @@
static void didCallFunctionImpl(const InspectorInstrumentationCookie&);
static InspectorInstrumentationCookie willDispatchXHRReadyStateChangeEventImpl(InstrumentingAgents*, XMLHttpRequest*, ScriptExecutionContext*);
static void didDispatchXHRReadyStateChangeEventImpl(const InspectorInstrumentationCookie&);
- static InspectorInstrumentationCookie willDispatchEventImpl(InstrumentingAgents*, const Event&, DOMWindow*, Node*, const Vector<EventContext>& ancestors, Document*);
+ static InspectorInstrumentationCookie willDispatchEventImpl(InstrumentingAgents*, const Event&, DOMWindow*, Node*, const EventPath&, Document*);
static InspectorInstrumentationCookie willHandleEventImpl(InstrumentingAgents*, Event*);
static void didHandleEventImpl(const InspectorInstrumentationCookie&);
static void didDispatchEventImpl(const InspectorInstrumentationCookie&);
@@ -864,12 +865,12 @@
#endif
}
-inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
+inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath)
{
#if ENABLE(INSPECTOR)
FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie());
if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document))
- return willDispatchEventImpl(instrumentingAgents, event, window, node, ancestors, document);
+ return willDispatchEventImpl(instrumentingAgents, event, window, node, eventPath, document);
#else
UNUSED_PARAM(document);
UNUSED_PARAM(event);