Title: [118442] trunk
Revision
118442
Author
[email protected]
Date
2012-05-24 16:36:12 -0700 (Thu, 24 May 2012)

Log Message

Submit button doesn't submit the form if the form is wrapped by an anchor tag
https://bugs.webkit.org/show_bug.cgi?id=86719

Patch by Pablo Flouret <[email protected]> on 2012-05-24
Reviewed by Ryosuke Niwa.

Source/WebCore:

When a form's button is clicked or activated with the keyboard a
DOMActivate event is dispatched internally and the default handler for
it takes care of processing the form submission, but the underlying
event that prompted it is not set as handled and so it ends up
navigating the anchor, thereby cancelling the form submission.

This patch sets the original click event as handled if the DOMActivate
event was handled. This matches the rest of the browsers for form
controls that submit a form (input type=submit, button type=submit,
input type=image, etc), and matches IE for the rest of the controls
(basically, IE never activates the anchor when clicking on form
controls, Presto and Gecko mostly don't either, except in a few cases.

Test: fast/forms/form-in-anchor-controls-activation.html

* dom/Node.cpp:
(WebCore::Node::dispatchDOMActivateEvent):
(WebCore::Node::defaultEventHandler):
* dom/Node.h:
(Node):
* html/HTMLButtonElement.cpp:
(WebCore::HTMLButtonElement::defaultEventHandler):

LayoutTests:

* fast/forms/form-in-anchor-controls-activation-expected.txt: Added.
* fast/forms/form-in-anchor-controls-activation.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (118441 => 118442)


--- trunk/LayoutTests/ChangeLog	2012-05-24 23:16:13 UTC (rev 118441)
+++ trunk/LayoutTests/ChangeLog	2012-05-24 23:36:12 UTC (rev 118442)
@@ -1,3 +1,13 @@
+2012-05-24  Pablo Flouret  <[email protected]>
+
+        Submit button doesn't submit the form if the form is wrapped by an anchor tag
+        https://bugs.webkit.org/show_bug.cgi?id=86719
+
+        Reviewed by Ryosuke Niwa.
+
+        * fast/forms/form-in-anchor-controls-activation-expected.txt: Added.
+        * fast/forms/form-in-anchor-controls-activation.html: Added.
+
 2012-05-24  Jessie Berlin  <[email protected]>
 
         Assertion failure in replaySavedEvents() when running editing/selection/drag-in-iframe.html

Added: trunk/LayoutTests/fast/events/domactivate-sets-underlying-click-event-as-handled-expected.txt (0 => 118442)


--- trunk/LayoutTests/fast/events/domactivate-sets-underlying-click-event-as-handled-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/domactivate-sets-underlying-click-event-as-handled-expected.txt	2012-05-24 23:36:12 UTC (rev 118442)
@@ -0,0 +1,40 @@
+To test manually, click on all the form elements (except the textbox) and the details/summary element. The anchor shouldn't be activated (i.e. you shouldn't see any "anchor activated" messages).
+
+Focusing [object HTMLInputElement] type=text and pressing enter
+form submitted
+
+Activated [object HTMLInputElement] type=submit
+form submitted
+
+Focusing [object HTMLInputElement] type=submit and pressing enter
+Activated [object HTMLInputElement] type=submit
+form submitted
+
+Activated [object HTMLInputElement] type=image
+form submitted
+
+Focusing [object HTMLInputElement] type=image and pressing enter
+Activated [object HTMLInputElement] type=image
+form submitted
+
+Activated [object HTMLButtonElement] type=submit
+form submitted
+
+Focusing [object HTMLButtonElement] type=submit and pressing enter
+Activated [object HTMLButtonElement] type=submit
+form submitted
+
+Activated [object HTMLInputElement] type=reset
+Focusing [object HTMLInputElement] type=reset and pressing enter
+Activated [object HTMLInputElement] type=reset
+Activated [object HTMLButtonElement] type=reset
+Focusing [object HTMLButtonElement] type=reset and pressing enter
+Activated [object HTMLButtonElement] type=reset
+Activated [object HTMLInputElement] type=checkbox
+Activated [object HTMLInputElement] type=radio
+Activated [object HTMLInputElement] type=file
+Focusing [object HTMLInputElement] type=file and pressing enter
+Activated [object HTMLInputElement] type=file
+
+The details element was opened
+

Added: trunk/LayoutTests/fast/events/domactivate-sets-underlying-click-event-as-handled.html (0 => 118442)


--- trunk/LayoutTests/fast/events/domactivate-sets-underlying-click-event-as-handled.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/domactivate-sets-underlying-click-event-as-handled.html	2012-05-24 23:36:12 UTC (rev 118442)
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+To test manually, click on all the form elements (except the textbox) and the details/summary
+element. The anchor shouldn't be activated (i.e. you shouldn't see any "anchor activated" messages).
+<a href=""
+    <form action=""
+        <input type=text>
+        <input type=submit>
+        <input type=image>
+        <button>button</button>
+        <input type=reset>
+        <button type=reset>button reset</button>
+        <input type=checkbox>
+        <input type=radio>
+        <input type=file>
+	</form>
+    <details><summary>summary</summary>details</details>
+</a>
+
+<pre>
+
+</pre>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(message) { document.querySelector("pre").innerHTML += message + "\n"; }
+function formSubmitted() { log("form submitted\n"); }
+function anchorActivated() { log("anchor activated\n"); }
+
+document.forms[0].children[0].value = "blah";
+
+for (var i=0; i < document.forms[0].children.length; i++) {
+    var element = document.forms[0].children[i];
+
+    element.addEventListener("click", function () {
+        log("Activated " + this + " type=" + this.type);
+    }, false);
+
+    if (!window.eventSender)
+        continue;
+
+    if (element.type == "text") {
+        log("Focusing " + element + " type=" + element.type + " and pressing enter");
+        element.focus();
+        eventSender.keyDown("\n");
+        continue;
+    }
+
+    eventSender.mouseMoveTo(element.offsetLeft + element.clientWidth / 2, element.offsetTop + element.clientHeight / 2);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+
+    if (element.type == "radio" || element.type == "checkbox")
+        continue;
+
+    log("Focusing " + element + " type=" + element.type + " and pressing enter");
+    element.focus();
+    eventSender.keyDown("\n");
+}
+
+if (window.eventSender) {
+    var details = document.querySelector("details");
+    eventSender.mouseMoveTo(details.offsetLeft + details.clientWidth / 2, details.offsetTop + details.clientHeight / 2);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    log("\nThe details element was " + (details.open ? "" : "not ") + "opened");
+}
+
+if (window.layoutTestController)
+    document.querySelector("a").style.display = "none";
+</script>

Modified: trunk/Source/WebCore/ChangeLog (118441 => 118442)


--- trunk/Source/WebCore/ChangeLog	2012-05-24 23:16:13 UTC (rev 118441)
+++ trunk/Source/WebCore/ChangeLog	2012-05-24 23:36:12 UTC (rev 118442)
@@ -1,3 +1,33 @@
+2012-05-24  Pablo Flouret  <[email protected]>
+
+        Submit button doesn't submit the form if the form is wrapped by an anchor tag
+        https://bugs.webkit.org/show_bug.cgi?id=86719
+
+        Reviewed by Ryosuke Niwa.
+
+        When a form's button is clicked or activated with the keyboard a
+        DOMActivate event is dispatched internally and the default handler for
+        it takes care of processing the form submission, but the underlying
+        event that prompted it is not set as handled and so it ends up
+        navigating the anchor, thereby cancelling the form submission.
+
+        This patch sets the original click event as handled if the DOMActivate
+        event was handled. This matches the rest of the browsers for form
+        controls that submit a form (input type=submit, button type=submit,
+        input type=image, etc), and matches IE for the rest of the controls
+        (basically, IE never activates the anchor when clicking on form
+        controls, Presto and Gecko mostly don't either, except in a few cases.
+
+        Test: fast/forms/form-in-anchor-controls-activation.html
+
+        * dom/Node.cpp:
+        (WebCore::Node::dispatchDOMActivateEvent):
+        (WebCore::Node::defaultEventHandler):
+        * dom/Node.h:
+        (Node):
+        * html/HTMLButtonElement.cpp:
+        (WebCore::HTMLButtonElement::defaultEventHandler):
+
 2012-05-24  Crystal Zhang  <[email protected]>
 
         [BlackBerry] Implement select popup and remove old hook to air popup

Modified: trunk/Source/WebCore/dom/Node.cpp (118441 => 118442)


--- trunk/Source/WebCore/dom/Node.cpp	2012-05-24 23:16:13 UTC (rev 118441)
+++ trunk/Source/WebCore/dom/Node.cpp	2012-05-24 23:36:12 UTC (rev 118442)
@@ -2749,12 +2749,13 @@
     dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(UIEvent::create(eventType, true, false, document()->defaultView(), 0), newFocusedNode));
 }
 
-void Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent)
+bool Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent)
 {
     ASSERT(!eventDispatchForbidden());
     RefPtr<UIEvent> event = UIEvent::create(eventNames().DOMActivateEvent, true, true, document()->defaultView(), detail);
     event->setUnderlyingEvent(underlyingEvent);
-    dispatchScopedEvent(event.release());
+    dispatchScopedEvent(event);
+    return event->defaultHandled();
 }
 
 bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& event)
@@ -2831,7 +2832,8 @@
                 frame->eventHandler()->defaultKeyboardEventHandler(static_cast<KeyboardEvent*>(event));
     } else if (eventType == eventNames().clickEvent) {
         int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
-        dispatchDOMActivateEvent(detail, event);
+        if (dispatchDOMActivateEvent(detail, event))
+            event->setDefaultHandled();
 #if ENABLE(CONTEXT_MENUS)
     } else if (eventType == eventNames().contextmenuEvent) {
         if (Frame* frame = document()->frame())

Modified: trunk/Source/WebCore/dom/Node.h (118441 => 118442)


--- trunk/Source/WebCore/dom/Node.h	2012-05-24 23:16:13 UTC (rev 118441)
+++ trunk/Source/WebCore/dom/Node.h	2012-05-24 23:36:12 UTC (rev 118442)
@@ -606,7 +606,7 @@
     void dispatchRegionLayoutUpdateEvent();
 
     void dispatchSubtreeModifiedEvent();
-    void dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
+    bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
     void dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Node> oldFocusedNode);
     void dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Node> newFocusedNode);
 

Modified: trunk/Source/WebCore/html/HTMLButtonElement.cpp (118441 => 118442)


--- trunk/Source/WebCore/html/HTMLButtonElement.cpp	2012-05-24 23:16:13 UTC (rev 118441)
+++ trunk/Source/WebCore/html/HTMLButtonElement.cpp	2012-05-24 23:36:12 UTC (rev 118442)
@@ -110,10 +110,13 @@
         if (form() && m_type == SUBMIT) {
             m_isActivatedSubmit = true;
             form()->prepareForSubmission(event);
+            event->setDefaultHandled();
             m_isActivatedSubmit = false; // Do this in case submission was canceled.
         }
-        if (form() && m_type == RESET)
+        if (form() && m_type == RESET) {
             form()->reset();
+            event->setDefaultHandled();
+        }
     }
 
     if (event->isKeyboardEvent()) {
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to