Extend EventDispatcher::dispatchSimulatedClick to allow sending a mouseover event
authorjonlee@apple.com <jonlee@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Nov 2012 09:11:52 +0000 (09:11 +0000)
committerjonlee@apple.com <jonlee@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Nov 2012 09:11:52 +0000 (09:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102610
<rdar://problem/12725663>

Reviewed by Darin Adler.

Update the dispatchSimulatedClick() to take option enums for dispatching events.

* dom/SimulatedClickOptions.h: Added. Define two options enums. One tracks which mouse
events to send. The other determines whether to force the element to repaint.

* dom/EventDispatcher.cpp:
(WebCore::EventDispatcher::dispatchSimulatedClick): Refactor to use the option enums.
* dom/EventDispatcher.h:
(EventDispatcher): Update function signature.

* dom/Node.cpp: Refactor parameters to use the options enums rather than booleans.
(WebCore::Node::dispatchSimulatedClick):
* dom/Node.h:

Refactor. Remove redundant comments.
* html/BaseCheckableInputType.cpp:
(WebCore::BaseCheckableInputType::accessKeyAction):
* html/BaseClickableWithKeyInputType.cpp:
(WebCore::BaseClickableWithKeyInputType::accessKeyAction):
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::accessKeyAction):
* html/HTMLButtonElement.cpp:
(WebCore::HTMLButtonElement::accessKeyAction):
* html/HTMLElement.cpp:
(WebCore::HTMLElement::click):
(WebCore::HTMLElement::accessKeyAction):
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::accessKeyAction):
* html/RadioInputType.cpp:
(WebCore::RadioInputType::handleKeydownEvent):
* html/RangeInputType.cpp:
(WebCore::RangeInputType::accessKeyAction):

Add SimulatedClickOptions.h.
* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@135690 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/EventDispatcher.cpp
Source/WebCore/dom/EventDispatcher.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/SimulatedClickOptions.h [new file with mode: 0644]
Source/WebCore/html/BaseCheckableInputType.cpp
Source/WebCore/html/BaseClickableWithKeyInputType.cpp
Source/WebCore/html/HTMLAnchorElement.cpp
Source/WebCore/html/HTMLButtonElement.cpp
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLSelectElement.cpp
Source/WebCore/html/RadioInputType.cpp
Source/WebCore/html/RangeInputType.cpp

index facdc08..3847a52 100644 (file)
@@ -1,3 +1,51 @@
+2012-11-26  Jon Lee  <jonlee@apple.com>
+
+        Extend EventDispatcher::dispatchSimulatedClick to allow sending a mouseover event
+        https://bugs.webkit.org/show_bug.cgi?id=102610
+        <rdar://problem/12725663>
+
+        Reviewed by Darin Adler.
+
+        Update the dispatchSimulatedClick() to take option enums for dispatching events.
+
+        * dom/SimulatedClickOptions.h: Added. Define two options enums. One tracks which mouse
+        events to send. The other determines whether to force the element to repaint.
+
+        * dom/EventDispatcher.cpp:
+        (WebCore::EventDispatcher::dispatchSimulatedClick): Refactor to use the option enums.
+        * dom/EventDispatcher.h:
+        (EventDispatcher): Update function signature.
+
+        * dom/Node.cpp: Refactor parameters to use the options enums rather than booleans.
+        (WebCore::Node::dispatchSimulatedClick):
+        * dom/Node.h:
+
+        Refactor. Remove redundant comments.
+        * html/BaseCheckableInputType.cpp:
+        (WebCore::BaseCheckableInputType::accessKeyAction):
+        * html/BaseClickableWithKeyInputType.cpp:
+        (WebCore::BaseClickableWithKeyInputType::accessKeyAction):
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::accessKeyAction):
+        * html/HTMLButtonElement.cpp:
+        (WebCore::HTMLButtonElement::accessKeyAction):
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::click):
+        (WebCore::HTMLElement::accessKeyAction):
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::accessKeyAction):
+        * html/RadioInputType.cpp:
+        (WebCore::RadioInputType::handleKeydownEvent):
+        * html/RangeInputType.cpp:
+        (WebCore::RangeInputType::accessKeyAction):
+
+        Add SimulatedClickOptions.h.
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+
 2012-11-26  Shinya Kawanaka  <shinyak@chromium.org>
 
         [Shadow] Attaching children of a shadow host takes O(N^2) where N is the number of host children
index bba602c..70e1087 100644 (file)
@@ -2924,6 +2924,7 @@ webcore_sources += \
        Source/WebCore/dom/SelectorQuery.h \
        Source/WebCore/dom/ShadowRoot.cpp \
        Source/WebCore/dom/ShadowRoot.h \
+       Source/WebCore/dom/SimulatedClickOptions.h \
        Source/WebCore/dom/SpaceSplitString.cpp \
        Source/WebCore/dom/SpaceSplitString.h \
        Source/WebCore/dom/StaticHashSetNodeList.cpp \
index 998084b..c970f5e 100644 (file)
@@ -1621,6 +1621,7 @@ HEADERS += \
     dom/ScriptExecutionContext.h \
     dom/SelectorQuery.h \
     dom/ShadowRoot.h \
+    dom/SimulatedClickOptions.h \
     dom/SpaceSplitString.h \
     dom/StaticNodeList.h \
     dom/StyledElement.h \
index 47ee481..294885c 100644 (file)
             'dom/ScriptExecutionContext.h',
             'dom/ScriptRunner.h',
             'dom/ShadowRoot.h',
+            'dom/SimulatedClickOptions.h',
             'dom/SpaceSplitString.h',
             'dom/StyledElement.h',
             'dom/Text.h',
             'dom/SelectorQuery.h',
             'dom/ShadowRoot.cpp',
             'dom/ShadowRoot.h',
+            'dom/SimulatedClickOptions.h',
             'dom/SpaceSplitString.cpp',
             'dom/StaticHashSetNodeList.cpp',
             'dom/StaticHashSetNodeList.h',
index bcffb16..5b02b25 100755 (executable)
                                >
                        </File>
                        <File
+                               RelativePath="..\dom\SimulatedClickOptions.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\dom\SpaceSplitString.cpp"
                                >
                                <FileConfiguration
index e3afdb5..cd7327a 100644 (file)
                316FE1180E6E1DA700BF6088 /* ImplicitAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 316FE10E0E6E1DA700BF6088 /* ImplicitAnimation.h */; };
                316FE1190E6E1DA700BF6088 /* KeyframeAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 316FE10F0E6E1DA700BF6088 /* KeyframeAnimation.cpp */; };
                316FE11A0E6E1DA700BF6088 /* KeyframeAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 316FE1100E6E1DA700BF6088 /* KeyframeAnimation.h */; };
+               31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 31741AAB16635E45008A5B7E /* SimulatedClickOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                3194616213020B20004BB3F8 /* JSWebKitAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3194616013020B20004BB3F8 /* JSWebKitAnimation.cpp */; };
                3194616313020B20004BB3F8 /* JSWebKitAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 3194616113020B20004BB3F8 /* JSWebKitAnimation.h */; };
                3194616A13020B66004BB3F8 /* DOMWebKitAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 3194616813020B66004BB3F8 /* DOMWebKitAnimation.h */; };
                316FE10E0E6E1DA700BF6088 /* ImplicitAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ImplicitAnimation.h; path = animation/ImplicitAnimation.h; sourceTree = "<group>"; };
                316FE10F0E6E1DA700BF6088 /* KeyframeAnimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyframeAnimation.cpp; path = animation/KeyframeAnimation.cpp; sourceTree = "<group>"; };
                316FE1100E6E1DA700BF6088 /* KeyframeAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeyframeAnimation.h; path = animation/KeyframeAnimation.h; sourceTree = "<group>"; };
+               31741AAB16635E45008A5B7E /* SimulatedClickOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SimulatedClickOptions.h; sourceTree = "<group>"; };
                3194616013020B20004BB3F8 /* JSWebKitAnimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebKitAnimation.cpp; sourceTree = "<group>"; };
                3194616113020B20004BB3F8 /* JSWebKitAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebKitAnimation.h; sourceTree = "<group>"; };
                3194616813020B66004BB3F8 /* DOMWebKitAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMWebKitAnimation.h; sourceTree = "<group>"; };
                                A6D169611346B49B000EB770 /* ShadowRoot.cpp */,
                                A6D169631346B4C1000EB770 /* ShadowRoot.h */,
                                A7DB418114CE1F0A00A2E316 /* ShadowRoot.idl */,
+                               31741AAB16635E45008A5B7E /* SimulatedClickOptions.h */,
                                D01A27AB10C9BFD800026A42 /* SpaceSplitString.cpp */,
                                D01A27AC10C9BFD800026A42 /* SpaceSplitString.h */,
                                CEA3949A11D45CDA003094CF /* StaticHashSetNodeList.cpp */,
                                53EF766B16530A61004CBE49 /* SettingsMacros.h in Headers */,
                                447958041643B49A001E0A7F /* ParsedContentType.h in Headers */,
                                FB2C15C3165D649D0039C9F8 /* CachedSVGDocumentReference.h in Headers */,
+                               31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 6540958..73ac319 100644 (file)
@@ -208,7 +208,7 @@ void EventDispatcher::dispatchScopedEvent(Node* node, PassRefPtr<EventDispatchMe
     ScopedEventQueue::instance()->enqueueEventDispatchMediator(mediator);
 }
 
-void EventDispatcher::dispatchSimulatedClick(Node* node, Event* underlyingEvent, bool sendMouseEvents, bool showPressedLook)
+void EventDispatcher::dispatchSimulatedClick(Node* node, Event* underlyingEvent, SimulatedClickMouseEventOptions mouseEventOptions, SimulatedClickVisualOptions visualOptions)
 {
     if (node->disabled())
         return;
@@ -220,11 +220,13 @@ void EventDispatcher::dispatchSimulatedClick(Node* node, Event* underlyingEvent,
 
     gNodesDispatchingSimulatedClicks->add(node);
 
-    // send mousedown and mouseup before the click, if requested
-    if (sendMouseEvents)
+    if (mouseEventOptions == SendMouseOverUpDownEvents)
+        EventDispatcher(node).dispatchEvent(SimulatedMouseEvent::create(eventNames().mouseoverEvent, node->document()->defaultView(), underlyingEvent));
+
+    if (mouseEventOptions != SendNoEvents)
         EventDispatcher(node).dispatchEvent(SimulatedMouseEvent::create(eventNames().mousedownEvent, node->document()->defaultView(), underlyingEvent));
-    node->setActive(true, showPressedLook);
-    if (sendMouseEvents)
+    node->setActive(true, visualOptions == ShowPressedLook);
+    if (mouseEventOptions != SendNoEvents)
         EventDispatcher(node).dispatchEvent(SimulatedMouseEvent::create(eventNames().mouseupEvent, node->document()->defaultView(), underlyingEvent));
     node->setActive(false);
 
index e73d316..c858509 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef EventDispatcher_h
 #define EventDispatcher_h
 
+#include "SimulatedClickOptions.h"
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/Vector.h>
@@ -72,7 +73,7 @@ public:
     static bool dispatchEvent(Node*, PassRefPtr<EventDispatchMediator>);
     static void dispatchScopedEvent(Node*, PassRefPtr<EventDispatchMediator>);
 
-    static void dispatchSimulatedClick(Node*, Event* underlyingEvent, bool sendMouseEvents, bool showPressedLook);
+    static void dispatchSimulatedClick(Node*, Event* underlyingEvent, SimulatedClickMouseEventOptions, SimulatedClickVisualOptions);
 
     bool dispatchEvent(PassRefPtr<Event>);
     void adjustRelatedTarget(Event*, PassRefPtr<EventTarget> prpRelatedTarget);
index 2ad32e7..5686e6b 100644 (file)
@@ -2604,9 +2604,9 @@ bool Node::dispatchGestureEvent(const PlatformGestureEvent& event)
 }
 #endif
 
-void Node::dispatchSimulatedClick(Event* underlyingEvent, bool sendMouseEvents, bool showPressedLook)
+void Node::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions eventOptions, SimulatedClickVisualOptions visualOptions)
 {
-    EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, sendMouseEvents, showPressedLook);
+    EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions, visualOptions);
 }
 
 bool Node::dispatchBeforeLoadEvent(const String& sourceURL)
index baa62d7..d3ab3bb 100644 (file)
@@ -32,6 +32,7 @@
 #include "MutationObserver.h"
 #include "RenderStyleConstants.h"
 #include "ScriptWrappable.h"
+#include "SimulatedClickOptions.h"
 #include "TreeShared.h"
 #include <wtf/Forward.h>
 #include <wtf/ListHashSet.h>
@@ -637,7 +638,7 @@ public:
 #if ENABLE(GESTURE_EVENTS)
     bool dispatchGestureEvent(const PlatformGestureEvent&);
 #endif
-    void dispatchSimulatedClick(Event* underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
+    void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents, SimulatedClickVisualOptions = ShowPressedLook);
     bool dispatchBeforeLoadEvent(const String& sourceURL);
 
     virtual void dispatchFocusEvent(PassRefPtr<Node> oldFocusedNode);
diff --git a/Source/WebCore/dom/SimulatedClickOptions.h b/Source/WebCore/dom/SimulatedClickOptions.h
new file mode 100644 (file)
index 0000000..a49ed74
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SimulatedClickOptions_h
+#define SimulatedClickOptions_h
+
+namespace WebCore {
+
+enum SimulatedClickMouseEventOptions {
+    SendNoEvents,
+    SendMouseUpDownEvents,
+    SendMouseOverUpDownEvents
+};
+
+enum SimulatedClickVisualOptions {
+    DoNotShowPressedLook,
+    ShowPressedLook
+};
+
+} // namespace WebCore
+
+#endif // SimulatedClickOptions_h
index 2812173..cb61c7e 100644 (file)
@@ -89,9 +89,7 @@ void BaseCheckableInputType::accessKeyAction(bool sendMouseEvents)
 {
     InputType::accessKeyAction(sendMouseEvents);
 
-    // Send mouse button events if the caller specified sendMouseEvents.
-    // FIXME: The comment above is no good. It says what we do, but not why.
-    element()->dispatchSimulatedClick(0, sendMouseEvents);
+    element()->dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
 }
 
 String BaseCheckableInputType::fallbackValue() const
index 329c512..2a09b2f 100644 (file)
@@ -75,9 +75,7 @@ void BaseClickableWithKeyInputType::handleKeyupEvent(InputType& inputType, Keybo
 // FIXME: Could share this with BaseCheckableInputType and RangeInputType if we had a common base class.
 void BaseClickableWithKeyInputType::accessKeyAction(HTMLInputElement* element, bool sendMouseEvents)
 {
-    // Send mouse button events if the caller specified sendMouseEvents.
-    // FIXME: The comment above is no good. It says what we do, but not why.
-    element->dispatchSimulatedClick(0, sendMouseEvents);
+    element->dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
 }
 
 void BaseClickableWithKeyInputType::handleKeydownEvent(KeyboardEvent* event)
index d60e359..d571a4a 100644 (file)
@@ -241,8 +241,7 @@ void HTMLAnchorElement::parseAttribute(const QualifiedName& name, const AtomicSt
 
 void HTMLAnchorElement::accessKeyAction(bool sendMouseEvents)
 {
-    // send the mouse button events if the caller specified sendMouseEvents
-    dispatchSimulatedClick(0, sendMouseEvents);
+    dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
 }
 
 bool HTMLAnchorElement::isURLAttribute(const Attribute& attribute) const
index 1c9d53d..eff6fd8 100644 (file)
@@ -192,8 +192,8 @@ bool HTMLButtonElement::appendFormData(FormDataList& formData, bool)
 void HTMLButtonElement::accessKeyAction(bool sendMouseEvents)
 {
     focus();
-    // Send the mouse button events if the caller specified sendMouseEvents
-    dispatchSimulatedClick(0, sendMouseEvents);
+
+    dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
 }
 
 bool HTMLButtonElement::isURLAttribute(const Attribute& attribute) const
index 5716532..87b7e26 100644 (file)
@@ -690,12 +690,12 @@ void HTMLElement::setSpellcheck(bool enable)
 
 void HTMLElement::click()
 {
-    dispatchSimulatedClick(0, false, false);
+    dispatchSimulatedClick(0, SendNoEvents, DoNotShowPressedLook);
 }
 
 void HTMLElement::accessKeyAction(bool sendMouseEvents)
 {
-    dispatchSimulatedClick(0, sendMouseEvents);
+    dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
 }
 
 String HTMLElement::title() const
index 0527a91..23ac57a 100644 (file)
@@ -393,7 +393,7 @@ void HTMLSelectElement::optionElementChildrenChanged()
 void HTMLSelectElement::accessKeyAction(bool sendMouseEvents)
 {
     focus();
-    dispatchSimulatedClick(0, sendMouseEvents);
+    dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
 }
 
 void HTMLSelectElement::setMultiple(bool multiple)
index 076e22a..a9d86f3 100644 (file)
@@ -96,7 +96,7 @@ void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
             break;
         if (inputElement->isRadioButton() && inputElement->name() == element()->name() && inputElement->isFocusable()) {
             document->setFocusedNode(inputElement);
-            inputElement->dispatchSimulatedClick(event, false, false);
+            inputElement->dispatchSimulatedClick(event, SendNoEvents, DoNotShowPressedLook);
             event->setDefaultHandled();
             return;
         }
index 2ddf4c3..c37f6b7 100644 (file)
@@ -286,9 +286,7 @@ void RangeInputType::accessKeyAction(bool sendMouseEvents)
 {
     InputType::accessKeyAction(sendMouseEvents);
 
-    // Send mouse button events if the caller specified sendMouseEvents.
-    // FIXME: The comment above is no good. It says what we do, but not why.
-    element()->dispatchSimulatedClick(0, sendMouseEvents);
+    element()->dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
 }
 
 void RangeInputType::minOrMaxAttributeChanged()