2010-11-30 Daniel Bates <dbates@rim.com>
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Nov 2010 20:35:49 +0000 (20:35 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Nov 2010 20:35:49 +0000 (20:35 +0000)
        Reviewed by Alexey Proskuryakov.

        Change and focus events happen in different order if using tab vs. clicking
        https://bugs.webkit.org/show_bug.cgi?id=6181

        Tests to ensure adherence to section 7.4.2 of the HTML5 spec.
        <http://www.w3.org/TR/html5/editing.html#focus-management> with respect to
        focusing on an <input>, modifying its contents, and defocusing it either by
        pressing the tab key or clicking on another element.

        * fast/events/check-defocus-event-order-when-triggered-by-mouse-click-expected.txt: Added.
        * fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html: Added.
        * fast/events/check-defocus-event-order-when-triggered-by-tab-expected.txt: Added.
        * fast/events/check-defocus-event-order-when-triggered-by-tab.html: Added.
        * fast/events/resources/record-events.js: Added.
        (registerElementsAndEventsToRecord):
        (beginRecordingEvents.callback):
        (beginRecordingEvents):
        (endRecordingEvents.callback):
        (endRecordingEvents):
        (_processEachRegisteredElement):
        (_recordEvent):
        (checkThatEventsFiredInOrder.eventTarget):
        (checkThatEventsFiredInOrder.elementIdOrTagName):
        (checkThatEventsFiredInOrder):

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

LayoutTests/ChangeLog
LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-mouse-click-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html [new file with mode: 0644]
LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-tab-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-tab.html [new file with mode: 0644]
LayoutTests/fast/events/resources/record-events.js [new file with mode: 0644]

index 65089f8..7f84d2f 100644 (file)
@@ -1,3 +1,31 @@
+2010-11-30  Daniel Bates  <dbates@rim.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Change and focus events happen in different order if using tab vs. clicking
+        https://bugs.webkit.org/show_bug.cgi?id=6181
+
+        Tests to ensure adherence to section 7.4.2 of the HTML5 spec.
+        <http://www.w3.org/TR/html5/editing.html#focus-management> with respect to
+        focusing on an <input>, modifying its contents, and defocusing it either by
+        pressing the tab key or clicking on another element.
+
+        * fast/events/check-defocus-event-order-when-triggered-by-mouse-click-expected.txt: Added.
+        * fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html: Added.
+        * fast/events/check-defocus-event-order-when-triggered-by-tab-expected.txt: Added.
+        * fast/events/check-defocus-event-order-when-triggered-by-tab.html: Added.
+        * fast/events/resources/record-events.js: Added.
+        (registerElementsAndEventsToRecord):
+        (beginRecordingEvents.callback):
+        (beginRecordingEvents):
+        (endRecordingEvents.callback):
+        (endRecordingEvents):
+        (_processEachRegisteredElement):
+        (_recordEvent):
+        (checkThatEventsFiredInOrder.eventTarget):
+        (checkThatEventsFiredInOrder.elementIdOrTagName):
+        (checkThatEventsFiredInOrder):
+
 2010-11-30  Xiaomei Ji  <xji@chromium.org>
 
         Reviewed by David Hyatt.
diff --git a/LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-mouse-click-expected.txt b/LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-mouse-click-expected.txt
new file mode 100644 (file)
index 0000000..74558fc
--- /dev/null
@@ -0,0 +1,14 @@
+This test checks that when a user focuses on the "first input" text field, modifies its contents, and then defocuses it by clicking on the "second input" text field that the following DOM events are fired in order: Focus, Change, Blur, Focus (on "second input"), Click (on "second input"). Note, this test must be run by Dump Render Tree.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+  
+PASS fired event is (firstInput, focus).
+PASS fired event is (firstInput, change).
+PASS fired event is (firstInput, blur).
+PASS fired event is (secondInput, focus).
+PASS fired event is (secondInput, click).
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html b/LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html
new file mode 100644 (file)
index 0000000..420f593
--- /dev/null
@@ -0,0 +1,47 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script src="resources/record-events.js"></script>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+window.onload = runTest;
+
+function runTest()
+{
+    if (!window.eventSender)
+        return;
+
+    var firstInput = document.getElementById("firstInput");
+    var secondInput = document.getElementById("secondInput");
+    registerElementsAndEventsToRecord([firstInput, secondInput], ["focus", "blur", "change", "click"]);
+
+    beginRecordingEvents();
+    firstInput.focus();
+    eventSender.keyDown("A");
+    eventSender.mouseMoveTo(secondInput.offsetLeft, secondInput.offsetTop);
+    eventSender.mouseDown();
+    eventSender.mouseUp(); // Transfers focus to text field "second input".
+    endRecordingEvents();
+    checkThatEventsFiredInOrder([["firstInput", "focus"], ["firstInput", "change"], ["firstInput", "blur"], ["secondInput", "focus"], ["secondInput", "click"]]);
+    debug('<br /><span class="pass">TEST COMPLETE</span>');
+}
+</script>
+</head>
+<body>
+<p id="description"></p>
+<div id="test-container">
+    <input type="text" id="firstInput" placeholder="first input" />
+    <input type="text" id="secondInput" placeholder="second input" />
+</div>
+<div id="console"></div>
+<script>
+    description("This test checks that when a user focuses on the &quot;first input&quot; text field, modifies its contents, and then " +
+                "defocuses it by clicking on the &quot;second input&quot; text field that the following DOM events are fired in order: " +
+                "Focus, Change, Blur, Focus (on &quot;second input&quot;), Click (on &quot;second input&quot;). Note, this test must be run by Dump Render Tree.");
+    var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-tab-expected.txt b/LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-tab-expected.txt
new file mode 100644 (file)
index 0000000..d2b97e3
--- /dev/null
@@ -0,0 +1,13 @@
+This test checks that when a user focuses on the "first input" text field, modifies its contents, and then defocuses it by pressing the tab key that the following DOM events are fired in order: Focus, Change, Blur, Focus (on "second input"). Note, this test must be run by Dump Render Tree.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+  
+PASS fired event is (firstInput, focus).
+PASS fired event is (firstInput, change).
+PASS fired event is (firstInput, blur).
+PASS fired event is (secondInput, focus).
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-tab.html b/LayoutTests/fast/events/check-defocus-event-order-when-triggered-by-tab.html
new file mode 100644 (file)
index 0000000..d52cbb4
--- /dev/null
@@ -0,0 +1,45 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script src="resources/record-events.js"></script>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+window.onload = runTest;
+
+function runTest()
+{
+    if (!window.eventSender)
+        return;
+
+    var firstInput = document.getElementById("firstInput");
+    var secondInput = document.getElementById("secondInput");
+    registerElementsAndEventsToRecord([firstInput, secondInput], ["focus", "blur", "change", "click"]);
+
+    beginRecordingEvents();
+    firstInput.focus();
+    eventSender.keyDown("A");
+    eventSender.keyDown("\t"); // Transfers focus to text field "second input".
+    endRecordingEvents();
+    checkThatEventsFiredInOrder([["firstInput", "focus"], ["firstInput", "change"], ["firstInput", "blur"], ["secondInput", "focus"]]);
+    debug('<br /><span class="pass">TEST COMPLETE</span>');
+}
+</script>
+</head>
+<body>
+<p id="description"></p>
+<div id="test-container">
+    <input type="text" id="firstInput" placeholder="first input" />
+    <input type="text" id="secondInput" placeholder="second input" />
+</div>
+<div id="console"></div>
+<script>
+    description("This test checks that when a user focuses on the &quot;first input&quot; text field, modifies its contents, and then " +
+                "defocuses it by pressing the tab key that the following DOM events are fired in order: Focus, Change, Blur, Focus " +
+                "(on &quot;second input&quot;). Note, this test must be run by Dump Render Tree.");
+    var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/resources/record-events.js b/LayoutTests/fast/events/resources/record-events.js
new file mode 100644 (file)
index 0000000..92174e3
--- /dev/null
@@ -0,0 +1,80 @@
+// NOTE: You must include fast/js/resources/js-test-pre.js before this file in a test case since
+// this file makes use of functions in js-test-pre.js.
+
+var replayEventQueue = []; // Global queue of recorded events.
+var registeredElementsAndEventsStruct; // Global structure of registered elements and events.
+
+function registerElementsAndEventsToRecord(elementsToRecord, eventsToRecord)
+{
+    registeredElementsAndEventsStruct = {"elementsToRecord": elementsToRecord, "eventsToRecord": eventsToRecord};
+}
+
+function beginRecordingEvents()
+{
+    function callback(element, eventName)
+    {
+        element.addEventListener(eventName, _recordEvent, false);
+    }
+    _processEachRegisteredElement(callback);
+}
+
+function endRecordingEvents()
+{
+    function callback(element, eventName)
+    {
+        element.removeEventListener(eventName, _recordEvent, false);
+    }
+    _processEachRegisteredElement(callback);
+}
+
+function _processEachRegisteredElement(callback)
+{
+    if (!registeredElementsAndEventsStruct)
+        return;
+    var elements = registeredElementsAndEventsStruct.elementsToRecord;
+    var events = registeredElementsAndEventsStruct.eventsToRecord;
+    for (var i = 0; i < elements.length; ++i) {
+        for (var j = 0; j < events.length; ++j)
+            callback(elements[i], events[j])
+    }
+}
+
+function _recordEvent(event)
+{
+    replayEventQueue.push(event);
+}
+
+function checkThatEventsFiredInOrder(expectedOrderQueue)
+{
+    function eventTarget(event)
+    {
+        // In Internet Explorer an Event object does not have a "target" property.
+        // The analagous property is called "srcElement".
+        return event.target || event.srcElement;
+    }
+
+    function elementIdOrTagName(element)
+    {
+        return element.id || element.tagName;
+    }
+
+    while (replayEventQueue.length && expectedOrderQueue.length) {
+        var replayedEvent = replayEventQueue.shift();
+        var expectedEvent = expectedOrderQueue.shift();
+        var replayedEventTargetName = elementIdOrTagName(eventTarget(replayedEvent));
+        if (replayedEventTargetName === expectedEvent[0] && replayedEvent.type === expectedEvent[1])
+            testPassed('fired event is (' + replayedEventTargetName + ', ' + replayedEvent.type + ').');
+        else {
+            testFailed('fired event is (' + replayedEventTargetName + ', ' + replayedEvent.type + '). ' +
+                       'Should be (' + expectedEvent[0] + ', ' + expectedEvent[1] + ').');
+        }
+    }
+    while (replayEventQueue.length) {
+        var replayedEvent = replayEventQueue.shift();
+        testFailed('should not have fired event (' + elementIdOrTagName(eventTarget(replayedEvent)) + ', ' + replayedEvent.type + '). But did.');
+    }
+    while (expectedOrderQueue.length) {
+        var expectedEvent = expectedOrderQueue.shift();
+        testFailed('should have fired event (' + expectedEvent[0] + ', ' + expectedEvent[1] + '). But did not.');
+    }
+}