LayoutTests:
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Dec 2006 01:29:07 +0000 (01:29 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Dec 2006 01:29:07 +0000 (01:29 +0000)
        Reviewed by Adele.

        - test the part of http://bugs.webkit.org/show_bug.cgi?id=11628
          REGRESSION (r17597): Command-return in text fields doesn't open a new tab or window
          that can easily be tested from the DOM -- this only checks that
          simulated mouse events from clicking on a link have the key state
          from the Enter key keyboard event, which is one part of the fix
          for the bug above

        * fast/events/simulated-key-state-expected.txt: Added.
        * fast/events/simulated-key-state.html: Added.

WebCore:

        Reviewed by Adele.

        - fix another part of http://bugs.webkit.org/show_bug.cgi?id=11628
          REGRESSION (r17597): Command-return in text fields doesn't open a new tab or window

        This fixes command-return when the focus is on a link.
        Despite the title of the bug, Mitz wanted me to fix both, and I will not
        say no to him!

        Test: fast/events/simulated-key-state.html

        * dom/EventTargetNode.cpp:
        (WebCore::EventTargetNode::dispatchSimulatedMouseEvent): Instead of always passing
        false for all the key state in simulated mouse events, pass the state from the
        first underlying event in the chain that has key state; in the case in the bug,
        the keyboard event will be the underlying event itself and we'll propagate the
        alt key modifier to the mouse event, resulting in the effect we want. It's nice
        that JavaScript also gets to see the proper modifiers in the mouse event.

        * html/HTMLAnchorElement.cpp: (WebCore::HTMLAnchorElement::defaultEventHandler):
        Added code to pass in an underlying event to dispatchSimulatedClick. After looking
        at all the other callers, this seems to be the only one that needs to pass an
        event that is currently passing 0. Also removed the code that only simulated a
        click when the event has a PlatformKeyboardEvent -- no reason for that and it
        prevented me from writing a layout test for the fix.

        * dom/UIEventWithKeyState.h: Added findEventWithKeyState function that walks the
        underlyingEvent chain to find the first event that has key state. This already
        existed in WebKit, but I wanted to use it in dispatchSimulatedMouseEvent.
        * dom/UIEventWithKeyState.cpp: Added.

        * CMakeLists.txt: Added UIEventWithKeyState.cpp.
        * WebCore.vcproj/WebCore/WebCore.vcproj: Added UIEventWithKeyState.cpp.
        * WebCore.xcodeproj/project.pbxproj: Added UIEventWithKeyState.cpp.
        * WebCoreSources.bkl: Added UIEventWithKeyState.cpp.

        * WebCore.exp: Added findEventWithKeyState, used by WebKit.

WebKit:

        Reviewed by Adele.

        * WebCoreSupport/WebFrameLoaderClient.mm:
        (WebFrameLoaderClient::actionDictionary): Changed to use the new
        findEventWithKeyState function in WebCore instead of a local function
        in this file.

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/simulated-key-state-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/simulated-key-state.html [new file with mode: 0644]
WebCore/CMakeLists.txt
WebCore/ChangeLog
WebCore/WebCore.exp
WebCore/WebCore.vcproj/WebCore/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/WebCoreSources.bkl
WebCore/dom/EventTargetNode.cpp
WebCore/dom/UIEventWithKeyState.cpp [new file with mode: 0644]
WebCore/dom/UIEventWithKeyState.h
WebCore/html/HTMLAnchorElement.cpp
WebKit/ChangeLog
WebKit/WebCoreSupport/WebFrameLoaderClient.mm

index 75e56cbaabd3e9b161c3b21f01fa4e11f142d34e..34ac233029a586c4d066cd5770e9d0f95643f884 100644 (file)
@@ -1,3 +1,17 @@
+2006-12-04  Darin Adler  <darin@apple.com>
+
+        Reviewed by Adele.
+
+        - test the part of http://bugs.webkit.org/show_bug.cgi?id=11628
+          REGRESSION (r17597): Command-return in text fields doesn't open a new tab or window
+          that can easily be tested from the DOM -- this only checks that
+          simulated mouse events from clicking on a link have the key state
+          from the Enter key keyboard event, which is one part of the fix
+          for the bug above
+
+        * fast/events/simulated-key-state-expected.txt: Added.
+        * fast/events/simulated-key-state.html: Added.
+
 2006-12-02  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Darin Adler.
diff --git a/LayoutTests/fast/events/simulated-key-state-expected.txt b/LayoutTests/fast/events/simulated-key-state-expected.txt
new file mode 100644 (file)
index 0000000..941973e
--- /dev/null
@@ -0,0 +1,13 @@
+This tests that modifier keys are propagated to the fake mouse event created when you press return and a link has focus.
+
+If the test succeeds, you should see six "PASS" messages below.
+
+This is the link used for testing.
+
+PASS: click event had all the right key state.
+PASS: click event had all the right key state.
+PASS: click event had all the right key state.
+PASS: click event had all the right key state.
+PASS: click event had all the right key state.
+PASS: click event had all the right key state.
+
diff --git a/LayoutTests/fast/events/simulated-key-state.html b/LayoutTests/fast/events/simulated-key-state.html
new file mode 100644 (file)
index 0000000..7e4b846
--- /dev/null
@@ -0,0 +1,47 @@
+<p>This tests that modifier keys are propagated to the fake mouse event created when you press return and a link has focus.</p>
+<p>If the test succeeds, you should see six "PASS" messages below.</p>
+<p>This is the <a id="link" href="#" onclick="checkKeyState(event)" onmousedown="checkKeyState(event)" onmouseuup="checkKeyState(event)">link</a> used for testing.</p>
+<pre id="console">
+</pre>
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var link = document.getElementById("link");
+link.focus();
+
+var expectedCtrl;
+var expectedAlt;
+var expectedShift;
+var expectedMeta;
+
+function test(ctrlKey, altKey, shiftKey, metaKey)
+{
+    expectedCtrl = ctrlKey;
+    expectedAlt = altKey;
+    expectedShift = shiftKey;
+    expectedMeta = metaKey;
+    var event = document.createEvent("KeyboardEvents");
+    event.initKeyboardEvent("keydown", true, true, document.defaultView, "Enter", 0, ctrlKey, altKey, shiftKey, metaKey, false);
+    link.dispatchEvent(event);
+}
+
+function checkKeyState(event)
+{
+    if (event.ctrlKey == expectedCtrl && event.altKey == expectedAlt && event.shiftKey == expectedShift && event.metaKey == expectedMeta)
+        document.getElementById("console").innerHTML += "PASS: " + event.type + " event had all the right key state.\n";
+    else
+        document.getElementById("console").innerHTML += "FAIL: " + event.type + " event did not have the right key state.\n";
+}
+
+test(false, false, false, false);
+test(true, false, false, false);
+test(false, true, false, false);
+test(false, false, true, false);
+test(false, false, false, true);
+test(true, true, true, true);
+
+link.blur();
+
+</script>
index 2f99beec85dae735d476dfe769461505c44af3f8..58f61072462a935bc522667f9ed0fdc96499dd0b 100644 (file)
@@ -796,6 +796,7 @@ set(WebCore_SRCS
     dom/Traversal.cpp
     dom/TreeWalker.cpp
     dom/UIEvent.cpp
+    dom/UIEventWithKeyState.cpp
     dom/WheelEvent.cpp
     dom/XMLTokenizer.cpp
 
index c36b2b2c31b80c76be15b19b399e55447b140206..2857e2cfc28b37742113af3f60d6378780fbb2bd 100644 (file)
@@ -1,3 +1,43 @@
+2006-12-04  Darin Adler  <darin@apple.com>
+
+        Reviewed by Adele.
+
+        - fix another part of http://bugs.webkit.org/show_bug.cgi?id=11628
+          REGRESSION (r17597): Command-return in text fields doesn't open a new tab or window
+
+        This fixes command-return when the focus is on a link.
+        Despite the title of the bug, Mitz wanted me to fix both, and I will not
+        say no to him!
+
+        Test: fast/events/simulated-key-state.html
+
+        * dom/EventTargetNode.cpp:
+        (WebCore::EventTargetNode::dispatchSimulatedMouseEvent): Instead of always passing
+        false for all the key state in simulated mouse events, pass the state from the
+        first underlying event in the chain that has key state; in the case in the bug,
+        the keyboard event will be the underlying event itself and we'll propagate the
+        alt key modifier to the mouse event, resulting in the effect we want. It's nice
+        that JavaScript also gets to see the proper modifiers in the mouse event.
+
+        * html/HTMLAnchorElement.cpp: (WebCore::HTMLAnchorElement::defaultEventHandler):
+        Added code to pass in an underlying event to dispatchSimulatedClick. After looking
+        at all the other callers, this seems to be the only one that needs to pass an
+        event that is currently passing 0. Also removed the code that only simulated a
+        click when the event has a PlatformKeyboardEvent -- no reason for that and it
+        prevented me from writing a layout test for the fix. 
+
+        * dom/UIEventWithKeyState.h: Added findEventWithKeyState function that walks the
+        underlyingEvent chain to find the first event that has key state. This already
+        existed in WebKit, but I wanted to use it in dispatchSimulatedMouseEvent.
+        * dom/UIEventWithKeyState.cpp: Added.
+
+        * CMakeLists.txt: Added UIEventWithKeyState.cpp.
+        * WebCore.vcproj/WebCore/WebCore.vcproj: Added UIEventWithKeyState.cpp.
+        * WebCore.xcodeproj/project.pbxproj: Added UIEventWithKeyState.cpp.
+        * WebCoreSources.bkl: Added UIEventWithKeyState.cpp.
+
+        * WebCore.exp: Added findEventWithKeyState, used by WebKit.
+
 2006-12-04  Kevin McCullough  <KMcCullough@apple.com>
 
         Reviewed by Darin.
index 53db8aef84c8dd6bb715e24831a1733393cee63a..0d997ce7442b0fd5584d7c9a752991ddd58d612e 100644 (file)
@@ -221,6 +221,7 @@ __ZN7WebCore18PlatformMouseEventC1EP7NSEvent
 __ZN7WebCore19SelectionController5clearEv
 __ZN7WebCore19SelectionController9selectAllEv
 __ZN7WebCore21PlatformKeyboardEventC1EP7NSEventb
+__ZN7WebCore21findEventWithKeyStateEPNS_5EventE
 __ZN7WebCore21isBackForwardLoadTypeENS_13FrameLoadTypeE
 __ZN7WebCore26NetscapePlugInStreamLoader6createEPNS_5FrameEP11objc_object
 __ZN7WebCore36InitializeLoggingChannelsIfNecessaryEv
index c3368f3f8e7beba0a4ff1aa919b98dcb6a85c13c..847333f0b34a4970e446ccf977ffcb9bd4051908 100644 (file)
                                RelativePath="..\..\dom\UIEvent.h"
                                >
                        </File>
+                       <File
+                               RelativePath="..\..\dom\UIEventWithKeyState.cpp"
+                               >
+                       </File>
                        <File
                                RelativePath="..\..\dom\UIEventWithKeyState.h"
                                >
index ece07506e217028ed2abeb44f39a09ff38207901..c941d3b8178cce50e13b9e10ba8d87478dbbd241 100644 (file)
                93309EA2099EB78C0056E581 /* SharedTimerMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309E9F099EB78C0056E581 /* SharedTimerMac.cpp */; };
                93309EA3099EB78C0056E581 /* SharedTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309EA0099EB78C0056E581 /* SharedTimer.h */; };
                93309EA4099EB78C0056E581 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309EA1099EB78C0056E581 /* Timer.cpp */; };
+               93354A3C0B24F8C9003F6DEA /* UIEventWithKeyState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93354A3B0B24F8C9003F6DEA /* UIEventWithKeyState.cpp */; };
                934706AB0AACD809002C1D43 /* TextDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 932CA7420AAA198E00AD1FAD /* TextDecoder.h */; };
                9352071909BD3BA500F2038D /* StaticConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 9352071709BD3BA500F2038D /* StaticConstructors.h */; };
                9352071A09BD3BA500F2038D /* TextBoundaries.h in Headers */ = {isa = PBXBuildFile; fileRef = 9352071809BD3BA500F2038D /* TextBoundaries.h */; };
                93309E9F099EB78C0056E581 /* SharedTimerMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedTimerMac.cpp; sourceTree = "<group>"; };
                93309EA0099EB78C0056E581 /* SharedTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedTimer.h; sourceTree = "<group>"; };
                93309EA1099EB78C0056E581 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = "<group>"; };
+               93354A3B0B24F8C9003F6DEA /* UIEventWithKeyState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIEventWithKeyState.cpp; sourceTree = "<group>"; };
                9352071709BD3BA500F2038D /* StaticConstructors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticConstructors.h; sourceTree = "<group>"; };
                9352071809BD3BA500F2038D /* TextBoundaries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextBoundaries.h; sourceTree = "<group>"; };
                9352071B09BD3BBB00F2038D /* TextBoundaries.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextBoundaries.mm; sourceTree = "<group>"; };
                                1A750D3C0A90DE35000FF215 /* TreeWalker.idl */,
                                85031B370A44EFC700F992E0 /* UIEvent.cpp */,
                                85031B380A44EFC700F992E0 /* UIEvent.h */,
+                               93354A3B0B24F8C9003F6DEA /* UIEventWithKeyState.cpp */,
                                85031B390A44EFC700F992E0 /* UIEventWithKeyState.h */,
                                141B94EE09EC425A000E9413 /* UIEvent.idl */,
                                85031B3A0A44EFC700F992E0 /* WheelEvent.cpp */,
                                B2ED97710B1F55CE00257D0F /* GraphicsContextCG.cpp in Sources */,
                                B277B4040B22F37C0004BEC6 /* GraphicsContextMac.mm in Sources */,
                                ED501DC60B249F2900AE18D9 /* EditorMac.mm in Sources */,
+                               93354A3C0B24F8C9003F6DEA /* UIEventWithKeyState.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index d2576b633367c5225bfa3558001dbdb933f2f91a..c7b5334d8dac3d09ee8355393776b6eddcc630e8 100644 (file)
         dom/Traversal.cpp
         dom/TreeWalker.cpp
         dom/UIEvent.cpp
+        dom/UIEventWithKeyState.cpp
         dom/WheelEvent.cpp
         dom/XMLTokenizer.cpp
     </set>
index e30ee0a644594a7f70e4bcba6e1c0a7cfe1446c6..6ef681874c375e47ae6cb459598aeefbe9435ecb 100644 (file)
@@ -385,10 +385,22 @@ void EventTargetNode::dispatchSimulatedMouseEvent(const AtomicString& eventType,
     PassRefPtr<Event> underlyingEvent)
 {
     assert(!eventDispatchForbidden());
+
+    bool ctrlKey = false;
+    bool altKey = false;
+    bool shiftKey = false;
+    bool metaKey = false;
+    if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEvent.get())) {
+        ctrlKey = keyStateEvent->ctrlKey();
+        altKey = keyStateEvent->altKey();
+        shiftKey = keyStateEvent->shiftKey();
+        metaKey = keyStateEvent->metaKey();
+    }
+
     // Like Gecko, we just pass 0 for everything when we make a fake mouse event.
     // Internet Explorer instead gives the current mouse position and state.
     dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0,
-        false, false, false, false, true, 0, underlyingEvent);
+        ctrlKey, altKey, shiftKey, metaKey, true, 0, underlyingEvent);
 }
 
 void EventTargetNode::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)
diff --git a/WebCore/dom/UIEventWithKeyState.cpp b/WebCore/dom/UIEventWithKeyState.cpp
new file mode 100644 (file)
index 0000000..b55403c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+#include "UIEventWithKeyState.h"
+
+namespace WebCore {
+    
+UIEventWithKeyState* findEventWithKeyState(Event* event)
+{
+    for (Event* e = event; e; e = e->underlyingEvent())
+        if (e->isKeyboardEvent() || e->isMouseEvent())
+            return static_cast<UIEventWithKeyState*>(e);
+    return 0;
+}
+
+} // namespace WebCore
index df08120a2b4325fb445d1a685bd8f61f33fdce8a..752537461a7cd7ea3ea5e4588d7b74618dbfd6d2 100644 (file)
@@ -63,6 +63,8 @@ namespace WebCore {
         bool m_metaKey : 1;
     };
 
+    UIEventWithKeyState* findEventWithKeyState(Event*);
+
 } // namespace WebCore
 
 #endif // UIEventWithKeyState_h
index 01d294c4cb7379335e023d4fbabd94197416d332..f29d434b4236fd883cdd28b0e8731e9609be54bf 100644 (file)
@@ -180,11 +180,9 @@ void HTMLAnchorElement::defaultEventHandler(Event* evt)
                 HTMLElement::defaultEventHandler(evt);
                 return;
             }
-            if (k->keyEvent()) {
-                evt->setDefaultHandled();
-                dispatchSimulatedClick(0);
-                return;
-            }
+            evt->setDefaultHandled();
+            dispatchSimulatedClick(evt);
+            return;
         }
 
         String url = parseURL(getAttribute(hrefAttr));
index f51b687191ad1e9ae6499349bc622483fc5b1b4c..6a0d2c2b10bf6724883fabf395b8d51330d88325 100644 (file)
@@ -1,3 +1,12 @@
+2006-12-04  Darin Adler  <darin@apple.com>
+
+        Reviewed by Adele.
+
+        * WebCoreSupport/WebFrameLoaderClient.mm:
+        (WebFrameLoaderClient::actionDictionary): Changed to use the new
+        findEventWithKeyState function in WebCore instead of a local function
+        in this file.
+
 2006-12-04  Geoffrey Garen  <ggaren@apple.com>
 
         Rolled out the WebDashboardBehaviorUseBackwardCompatibilityModeEnabled
index 76ebfbef1e2d679373f835d7214910d3fed2ec3b..dbfe888bff92b67ebf51d5c31768c31bc6b560a1 100644 (file)
@@ -1170,14 +1170,6 @@ String WebFrameLoaderClient::userAgent()
     return [getWebView(m_webFrame.get()) _userAgent];
 }
 
-static const UIEventWithKeyState* findKeyStateEvent(const Event* event)
-{
-    for (const Event* e = event; e; e = e->underlyingEvent())
-        if (e->isMouseEvent() || e->isKeyboardEvent())
-            return static_cast<const UIEventWithKeyState*>(e);
-    return 0;
-}
-
 static const MouseEvent* findMouseEvent(const Event* event)
 {
     for (const Event* e = event; e; e = e->underlyingEvent())
@@ -1190,7 +1182,7 @@ NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& act
 {
     unsigned modifierFlags = 0;
     const Event* event = action.event();
-    if (const UIEventWithKeyState* keyStateEvent = findKeyStateEvent(event)) {
+    if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event))) {
         if (keyStateEvent->ctrlKey())
             modifierFlags |= NSControlKeyMask;
         if (keyStateEvent->altKey())