Reviewed by John (fix for Radar bug) and Vicki (all the rest).
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 May 2005 05:48:41 +0000 (05:48 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 May 2005 05:48:41 +0000 (05:48 +0000)
        - fixed <rdar://problem/4105097> REGRESSION (138-139): Hitting Enter on a checkbox toggles check mark instead of submitting form
        - fixed other problems discovered while trying to make a layout test to test this work:
            - added newer DOM 3 event type constants
            - fixed prototype setup bug preventing event initialization functions from being called
            - fixed bug where any function taking an event parameter would crash with a nil-deref
            - fixed incorrect ref/deref bug in MutationEventImpl that would cause a crash crash

        Test cases added:
        * layout-tests/fast/forms/check-box-enter-key-expected.txt: Added.
        * layout-tests/fast/forms/check-box-enter-key.html: Added.
        * layout-tests/fast/events/event-creation-expected.txt: Added.
        * layout-tests/fast/events/event-creation.html: Added.

        * khtml/html/html_formimpl.cpp: (DOM::HTMLInputElementImpl::defaultEventHandler): Separate the checks for
        the space bar and the Enter key and make Enter submit the form on a check box or radio button.

        * khtml/ecma/kjs_events.cpp:
        (KJS::toEvent): Fixed bug where this was checking for DOMNode rather than DOMEvent, so always returning 0.
        Without this, both test cases above will crash.
        (KJS::DOMUIEvent::DOMUIEvent): Set prototype; without this, the event-creation test case will fail.
        (KJS::DOMMouseEvent::DOMMouseEvent): Set prototype; without this, the event-creation test case will fail.
        (KJS::DOMKeyboardEvent::DOMKeyboardEvent): Set prototype; without this, both test cases above will fail.
        (KJS::DOMMutationEvent::DOMMutationEvent): Set prototype; without this, both test cases above will fail.

        * khtml/xml/dom2_eventsimpl.cpp:
        (MutationEventImpl::MutationEventImpl): Fix typo where the wrong object was ref'd.
        (MutationEventImpl::initMutationEvent): Ditto. This was causing the layout tests to crash with the new tests above.

        * khtml/xml/dom_docimpl.cpp: (DocumentImpl::createEvent): Added new event types to match the current DOM
        Level 3 specification. The test above tests both the new event types and the old ones.

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

LayoutTests/fast/events/event-creation-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/event-creation.html [new file with mode: 0644]
LayoutTests/fast/forms/check-box-enter-key-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/check-box-enter-key.html [new file with mode: 0644]
WebCore/ChangeLog-2005-08-23
WebCore/khtml/ecma/kjs_events.cpp
WebCore/khtml/html/html_formimpl.cpp
WebCore/khtml/xml/dom2_eventsimpl.cpp
WebCore/khtml/xml/dom_docimpl.cpp

diff --git a/LayoutTests/fast/events/event-creation-expected.txt b/LayoutTests/fast/events/event-creation-expected.txt
new file mode 100644 (file)
index 0000000..f77cc71
--- /dev/null
@@ -0,0 +1,15 @@
+This test checks to see if we can create and initialize events of various types. This wouldn't work in older versions because we had prototypes hooked up incorrectly.
+
+If the test passes, you should see one line below about each of ten different events being successfully created.
+
+Created an Event object.
+Created a UIEvent object.
+Created a MouseEvent object.
+Created a KeyboardEvent object.
+Created a MutationEvent object.
+Created an Event object with the old HTMLEvents event type.
+Created a UIEvent object with the old UIEvents event type.
+Created a MouseEvent object with the old MouseEvents event type.
+Created a KeyboardEvent object with the old KeyboardEvents event type.
+Created a MutationEvent object with the old MutationEvents event type.
+
diff --git a/LayoutTests/fast/events/event-creation.html b/LayoutTests/fast/events/event-creation.html
new file mode 100644 (file)
index 0000000..f378d38
--- /dev/null
@@ -0,0 +1,43 @@
+<head>
+<script>
+function print(message)
+{
+    var paragraph = document.createElement("li");
+    paragraph.appendChild(document.createTextNode(message));
+    document.getElementById("console").appendChild(paragraph);
+}
+function test()
+{
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+
+    document.createEvent("Event").initEvent("generic", true, true);
+    print("Created an Event object.");
+    document.createEvent("UIEvent").initUIEvent("DOMActivate", true, true, document.defaultView, 1);
+    print("Created a UIEvent object.");
+    document.createEvent("MouseEvent").initMouseEvent("click", true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, document);
+    print("Created a MouseEvent object.");
+    document.createEvent("KeyboardEvent").initKeyboardEvent("keydown", true, true, document.defaultView, "Enter", 0, false, false, false, false, false);
+    print("Created a KeyboardEvent object.");
+    document.createEvent("MutationEvent").initMutationEvent("DOMSubtreeModified", true, false, document, null, null, null, 1);
+    print("Created a MutationEvent object.");
+
+    document.createEvent("HTMLEvents").initEvent("generic", true, true);
+    print("Created an Event object with the old HTMLEvents event type.");
+    document.createEvent("UIEvents").initUIEvent("DOMActivate", true, true, document.defaultView, 1);
+    print("Created a UIEvent object with the old UIEvents event type.");
+    document.createEvent("MouseEvents").initMouseEvent("click", true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, document);
+    print("Created a MouseEvent object with the old MouseEvents event type.");
+    document.createEvent("KeyboardEvents").initKeyboardEvent("keydown", true, true, document.defaultView, "Enter", 0, false, false, false, false, false);
+    print("Created a KeyboardEvent object with the old KeyboardEvents event type.");
+    document.createEvent("MutationEvents").initMutationEvent("DOMSubtreeModified", true, false, document, null, null, null, 1);
+    print("Created a MutationEvent object with the old MutationEvents event type.");
+}
+</script>
+</head>
+<body onload="test()">
+<p>This test checks to see if we can create and initialize events of various types. This wouldn't work in older versions because we had prototypes hooked up incorrectly.</p>
+<p>If the test passes, you should see one line below about each of ten different events being successfully created.</p>
+<hr>
+<p><ol id=console></ol></p>
+</body>
diff --git a/LayoutTests/fast/forms/check-box-enter-key-expected.txt b/LayoutTests/fast/forms/check-box-enter-key-expected.txt
new file mode 100644 (file)
index 0000000..bc37659
--- /dev/null
@@ -0,0 +1,8 @@
+This test checks to see if hitting the Enter key on a check box submits the form or checks the check box.
+
+If the test passes, the text below should say both "tried to submit form" and "check box is not checked".
+
+
+Tried to submit form.
+Check box is not checked.
+
diff --git a/LayoutTests/fast/forms/check-box-enter-key.html b/LayoutTests/fast/forms/check-box-enter-key.html
new file mode 100644 (file)
index 0000000..724bc1f
--- /dev/null
@@ -0,0 +1,40 @@
+<head>
+<script>
+function print(message)
+{
+    var paragraph = document.createElement("li");
+    paragraph.appendChild(document.createTextNode(message));
+    document.getElementById("console").appendChild(paragraph);
+}
+function submitHandler(e)
+{
+    e.preventDefault();
+    print("Tried to submit form.");
+    if (document.getElementById("check").checked) {
+        print("Check box is checked.");
+    } else {
+        print("Check box is not checked.");
+    }
+}
+function test()
+{
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+
+    document.getElementById("form").onsubmit = submitHandler;
+    var event = document.createEvent("KeyboardEvents");
+    event.initKeyboardEvent("keypress", true, true, document.defaultView, "Enter", 0, false, false, false, false, false);
+    document.getElementById("check").dispatchEvent(event);
+}
+</script>
+</head>
+<body onload="test()">
+<p>This test checks to see if hitting the Enter key on a check box submits the form or checks the check box.</p>
+<p>If the test passes, the text below should say both "tried to submit form" and "check box is not checked".</p>
+<hr>
+<form id=form>
+<input id=check type=checkbox>
+</form>
+<hr>
+<p><ol id=console></ol></p>
+</body>
index 23d1e0a2eabd240842c8ae2dae47c91db752e465..34944d7f21734717f6b487cf9d1641974aafb6e7 100644 (file)
@@ -1,3 +1,38 @@
+2005-05-30  Darin Adler  <darin@apple.com>
+
+        Reviewed by John (fix for Radar bug) and Vicki (all the rest).
+
+        - fixed <rdar://problem/4105097> REGRESSION (138-139): Hitting Enter on a checkbox toggles check mark instead of submitting form
+        - fixed other problems discovered while trying to make a layout test to test this work:
+            - added newer DOM 3 event type constants
+            - fixed prototype setup bug preventing event initialization functions from being called
+            - fixed bug where any function taking an event parameter would crash with a nil-deref
+            - fixed incorrect ref/deref bug in MutationEventImpl that would cause a crash crash
+
+        Test cases added:
+        * layout-tests/fast/forms/check-box-enter-key-expected.txt: Added.
+        * layout-tests/fast/forms/check-box-enter-key.html: Added.
+        * layout-tests/fast/events/event-creation-expected.txt: Added.
+        * layout-tests/fast/events/event-creation.html: Added.
+
+        * khtml/html/html_formimpl.cpp: (DOM::HTMLInputElementImpl::defaultEventHandler): Separate the checks for
+        the space bar and the Enter key and make Enter submit the form on a check box or radio button.
+
+        * khtml/ecma/kjs_events.cpp:
+        (KJS::toEvent): Fixed bug where this was checking for DOMNode rather than DOMEvent, so always returning 0.
+        Without this, both test cases above will crash.
+        (KJS::DOMUIEvent::DOMUIEvent): Set prototype; without this, the event-creation test case will fail.
+        (KJS::DOMMouseEvent::DOMMouseEvent): Set prototype; without this, the event-creation test case will fail.
+        (KJS::DOMKeyboardEvent::DOMKeyboardEvent): Set prototype; without this, both test cases above will fail.
+        (KJS::DOMMutationEvent::DOMMutationEvent): Set prototype; without this, both test cases above will fail.
+
+        * khtml/xml/dom2_eventsimpl.cpp:
+        (MutationEventImpl::MutationEventImpl): Fix typo where the wrong object was ref'd.
+        (MutationEventImpl::initMutationEvent): Ditto. This was causing the layout tests to crash with the new tests above.
+
+        * khtml/xml/dom_docimpl.cpp: (DocumentImpl::createEvent): Added new event types to match the current DOM
+        Level 3 specification. The test above tests both the new event types and the old ones.
+
 2005-05-30  Darin Adler  <darin@apple.com>
 
         Reviewed by John.
index 80af9d3550ed281e6d85265555cf2edbc7053562..83271a5b7b9a24cffba61f6febfe5c37560b8b6d 100644 (file)
@@ -551,7 +551,7 @@ ValueImp *getDOMEvent(ExecState *exec, EventImpl *e)
 
 EventImpl *toEvent(ValueImp *val)
 {
-    if (!val || !val->isObject(&DOMNode::info))
+    if (!val || !val->isObject(&DOMEvent::info))
         return 0;
     return static_cast<DOMEvent *>(val)->impl();
 }
@@ -607,6 +607,7 @@ IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMUIEventProto,DOMUIEventProtoFunc,DOMEventProt
 DOMUIEvent::DOMUIEvent(ExecState *exec, UIEventImpl *e)
   : DOMEvent(exec, e)
 {
+  setPrototype(DOMUIEventProto::self(exec));
 }
 
 DOMUIEvent::~DOMUIEvent()
@@ -700,6 +701,7 @@ IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMMouseEventProto,DOMMouseEventProtoFunc,DOMUIE
 DOMMouseEvent::DOMMouseEvent(ExecState *exec, MouseEventImpl *e)
   : DOMUIEvent(exec, e)
 {
+  setPrototype(DOMMouseEventProto::self(exec));
 }
 
 DOMMouseEvent::~DOMMouseEvent()
@@ -845,6 +847,7 @@ IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMKeyboardEventProto, DOMKeyboardEventProtoFunc
 DOMKeyboardEvent::DOMKeyboardEvent(ExecState *exec, KeyboardEventImpl *e)
   : DOMUIEvent(exec, e)
 {
+  setPrototype(DOMKeyboardEventProto::self(exec));
 }
 
 DOMKeyboardEvent::~DOMKeyboardEvent()
@@ -962,6 +965,7 @@ IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMMutationEventProto,DOMMutationEventProtoFunc,
 DOMMutationEvent::DOMMutationEvent(ExecState *exec, MutationEventImpl *e)
   : DOMEvent(exec, e)
 {
+  setPrototype(DOMMutationEventProto::self(exec));
 }
 
 DOMMutationEvent::~DOMMutationEvent()
index f16d297de46268d3d9c1f6a20a891db3fa6cbb3f..b701f6ff5674276581d4fe55ca223d3b1d9609de 100644 (file)
@@ -2176,34 +2176,64 @@ void HTMLInputElementImpl::defaultEventHandler(EventImpl *evt)
     // Use key press event here since sending simulated mouse events
     // on key down blocks the proper sending of the key press event.
     if (evt->id() == EventImpl::KEYPRESS_EVENT && evt->isKeyboardEvent()) {
+        bool clickElement = false;
+        bool clickDefaultFormButton = false;
+
         DOMString key = static_cast<KeyboardEventImpl *>(evt)->keyIdentifier();
-        switch (m_type) {
-            case BUTTON:
-            case CHECKBOX:
-            case FILE:
-            case IMAGE:
-            case RADIO:
-            case RESET:
-            case SUBMIT:
-                // Simulate mouse click for enter or spacebar for these types of elements.
-                // The AppKit already does this for spacebar for some, but not all, of them.
-                if (key == "U+000020" || key == "Enter") {
-                    click(false);
-                    evt->setDefaultHandled();
-                }
-                break;
-            case HIDDEN:
-            case ISINDEX:
-            case PASSWORD:
-            case RANGE:
-            case SEARCH:
-            case TEXT:
-                // Simulate mouse click on the default form button for enter for these types of elements.
-                if (key == "Enter" && m_form) {
-                    m_form->submitClick();
-                    evt->setDefaultHandled();
-                }
-                break;
+
+        if (key == "U+000020") {
+            switch (m_type) {
+                case BUTTON:
+                case CHECKBOX:
+                case FILE:
+                case IMAGE:
+                case RADIO:
+                case RESET:
+                case SUBMIT:
+                    // Simulate mouse click for spacebar for these types of elements.
+                    // The AppKit already does this for some, but not all, of them.
+                    clickElement = true;
+                    break;
+                case HIDDEN:
+                case ISINDEX:
+                case PASSWORD:
+                case RANGE:
+                case SEARCH:
+                case TEXT:
+                    break;
+            }
+        }
+
+        if (key == "Enter") {
+            switch (m_type) {
+                case BUTTON:
+                case CHECKBOX:
+                case HIDDEN:
+                case ISINDEX:
+                case PASSWORD:
+                case RANGE:
+                case SEARCH:
+                case TEXT:
+                    // Simulate mouse click on the default form button for enter for these types of elements.
+                    clickDefaultFormButton = true;
+                    break;
+                case FILE:
+                case IMAGE:
+                case RADIO:
+                case RESET:
+                case SUBMIT:
+                    // Simulate mouse click for enter for these types of elements.
+                    clickElement = true;
+                    break;
+            }
+        }
+
+        if (clickElement) {
+            click(false);
+            evt->setDefaultHandled();
+        } else if (clickDefaultFormButton && m_form) {
+            m_form->submitClick();
+            evt->setDefaultHandled();
         }
     }
 #endif
index 42e120a4d479f43da7bb62fd8d90370569365c6f..4d6dcec99a60bfe829025dd3ceb5f1d097935645 100644 (file)
@@ -720,8 +720,8 @@ MutationEventImpl::MutationEventImpl(EventId _id,
     if (m_newValue)
        m_newValue->ref();
     m_attrName = attrNameArg.implementation();
-    if (m_newValue)
-       m_newValue->ref();
+    if (m_attrName)
+       m_attrName->ref();
     m_attrChange = attrChangeArg;
 }
 
@@ -767,8 +767,8 @@ void MutationEventImpl::initMutationEvent(const DOMString &typeArg,
     if (m_newValue)
        m_newValue->ref();
     m_attrName = attrNameArg.implementation();
-    if (m_newValue)
-       m_newValue->ref();
+    if (m_attrName)
+       m_attrName->ref();
     m_attrChange = attrChangeArg;
 }
 
index 5b2bff293d70fe992caeda7f4461e1d6ff5f73cc..fb9b06f7a4ee6b5fc27beef65f98367e3a32d421 100644 (file)
@@ -2653,15 +2653,15 @@ AbstractViewImpl *DocumentImpl::defaultView() const
 
 EventImpl *DocumentImpl::createEvent(const DOMString &eventType, int &exceptioncode)
 {
-    if (eventType == "UIEvents")
+    if (eventType == "UIEvents" || eventType == "UIEvent")
         return new UIEventImpl();
-    else if (eventType == "MouseEvents")
+    else if (eventType == "MouseEvents" || eventType == "MouseEvent")
         return new MouseEventImpl();
-    else if (eventType == "MutationEvents")
+    else if (eventType == "MutationEvents" || eventType == "MutationEvent")
         return new MutationEventImpl();
-    else if (eventType == "KeyboardEvents")
+    else if (eventType == "KeyboardEvents" || eventType == "KeyboardEvent")
         return new KeyboardEventImpl();
-    else if (eventType == "HTMLEvents")
+    else if (eventType == "HTMLEvents" || eventType == "Event")
         return new EventImpl();
     else {
         exceptioncode = DOMException::NOT_SUPPORTED_ERR;