Bug 918940 - Part a: Make HTMLInputElement::SetSelectionRange fire select event asynchronously per spec. r=ehsan
authorAndrew Quartey <andrew.quartey@gmail.com>
Fri, 04 Oct 2013 11:30:07 -0400
changeset 149910 dd3a2bdd7edb39a988965df0bb8a57bf291dd4e2
parent 149909 89c055d49a4611796e139633d040178dc70add40
child 149911 1e32e9c242ad399fb7e116bd20bf71235d16b7a0
push idunknown
push userunknown
push dateunknown
reviewersehsan
bugs918940
milestone27.0a1
Bug 918940 - Part a: Make HTMLInputElement::SetSelectionRange fire select event asynchronously per spec. r=ehsan
content/html/content/src/HTMLInputElement.cpp
content/html/content/test/forms/test_set_range_text.html
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -4518,22 +4518,20 @@ HTMLInputElement::SetSelectionRange(int3
       nsITextControlFrame::SelectionDirection dir = nsITextControlFrame::eForward;
       if (aDirection.WasPassed() && aDirection.Value().EqualsLiteral("backward")) {
         dir = nsITextControlFrame::eBackward;
       }
 
       aRv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd, dir);
       if (!aRv.Failed()) {
         aRv = textControlFrame->ScrollSelectionIntoView();
+        nsRefPtr<nsAsyncDOMEvent> event =
+          new nsAsyncDOMEvent(this, NS_LITERAL_STRING("select"), true, false);
+        event->PostDOMEvent();
       }
-
-      nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
-                                           static_cast<nsIDOMHTMLInputElement*>(this),
-                                           NS_LITERAL_STRING("select"), true,
-                                           false);
     }
   }
 }
 
 NS_IMETHODIMP
 HTMLInputElement::SetSelectionRange(int32_t aSelectionStart,
                                     int32_t aSelectionEnd,
                                     const nsAString& aDirection)
--- a/content/html/content/test/forms/test_set_range_text.html
+++ b/content/html/content/test/forms/test_set_range_text.html
@@ -57,127 +57,141 @@ https://bugzilla.mozilla.org/show_bug.cg
       try {
         elem.setRangeText("abc");
       } catch (ex) {
        opThrows = true;
       }
       ok(opThrows, msg + " should throw NotSupportedError");
     }
 
+    var numOfSelectCalls = 0, expectedNumOfSelectCalls = 0;
     //Supported types should not throw
     for (i = 0; i < SupportedTypes.length; ++i) {
       opThrows = false;
       msg = "input_" + SupportedTypes[i];
       elem = document.getElementById(msg);
       elem.focus();
       try {
         elem.setRangeText("abc");
       } catch (ex) {
           opThrows = true;
       }
       is(opThrows, false, msg + " should not throw NotSupportedError");
 
       elem.addEventListener("select", function (aEvent) {
-        ok(true, "select event should be fired for "+ msg);
+        ok(true, "select event should be fired for " + aEvent.target.id);
+        if (++numOfSelectCalls == expectedNumOfSelectCalls) {
+          SimpleTest.finish();
+        }
       }, false);
 
       elem.addEventListener("input", function (aEvent) {
-        ok(false, "input event should NOT be fired for " + msg);
+        ok(false, "input event should NOT be fired for " + + aEvent.target.id);
       }, false);
 
       //test setRange(replacement)
       elem.value = "0123456789ABCDEF";
       elem.setSelectionRange(1, 6);
       elem.setRangeText("xyz");
       is(elem.value, "0xyz6789ABCDEF", msg + ".value == \"0xyz6789ABCDEF\"");
       is(elem.selectionStart, 1, msg + ".selectionStart == 1");
       is(elem.selectionEnd, 4, msg + ".selectionEnd == 4");
       elem.setRangeText("mnk");
       is(elem.value, "0mnk6789ABCDEF", msg + ".value == \"0mnk6789ABCDEF\"");
+      expectedNumOfSelectCalls += 3;
 
       //test SetRange(replacement, start, end, mode) with start > end
       try {
         elem.setRangeText("abc", 20, 4);
       } catch (ex) {
         opThrows = (ex.name == "IndexSizeError" && ex.code == DOMException.INDEX_SIZE_ERR);
       }
       is(opThrows, true, msg + " should throw IndexSizeError");
+      expectedNumOfSelectCalls += 1;
 
       //test SelectionMode 'select'
       elem.value = "0123456789ABCDEF";
       elem.setRangeText("xyz", 4, 9, "select");
       is(elem.value, "0123xyz9ABCDEF", msg + ".value == \"0123xyz9ABCDEF\"");
       is(elem.selectionStart, 4, msg + ".selectionStart == 4, with \"select\"");
       is(elem.selectionEnd, 7, msg + ".selectionEnd == 7, with \"select\"");
+      expectedNumOfSelectCalls += 1;
 
       elem.setRangeText("pqm", 6, 25, "select");
       is(elem.value, "0123xypqm", msg + ".value == \"0123xypqm\"");
       is(elem.selectionStart, 6, msg + ".selectionStart == 6, with \"select\"");
       is(elem.selectionEnd, 9, msg + ".selectionEnd == 9, with \"select\"");
+      expectedNumOfSelectCalls += 1;
 
       //test SelectionMode 'start'
       elem.value = "0123456789ABCDEF";
       elem.setRangeText("xyz", 4, 9, "start");
       is(elem.value, "0123xyz9ABCDEF", msg + ".value == \"0123xyz9ABCDEF\"");
       is(elem.selectionStart, 4, msg + ".selectionStart == 4, with \"start\"");
       is(elem.selectionEnd, 4, msg + ".selectionEnd == 4, with \"start\"");
+      expectedNumOfSelectCalls += 1;
 
       elem.setRangeText("pqm", 6, 25, "start");
       is(elem.value, "0123xypqm", msg + ".value == \"0123xypqm\"");
       is(elem.selectionStart, 6, msg + ".selectionStart == 6, with \"start\"");
       is(elem.selectionEnd, 6, msg + ".selectionEnd == 6, with \"start\"");
+      expectedNumOfSelectCalls += 1;
 
       //test SelectionMode 'end'
       elem.value = "0123456789ABCDEF";
       elem.setRangeText("xyz", 4, 9, "end");
       is(elem.value, "0123xyz9ABCDEF", msg + ".value == \"0123xyz9ABCDEF\"");
       is(elem.selectionStart, 7, msg + ".selectionStart == 7, with \"end\"");
       is(elem.selectionEnd, 7, msg + ".selectionEnd == 7, with \"end\"");
+      expectedNumOfSelectCalls += 1;
 
       elem.setRangeText("pqm", 6, 25, "end");
       is(elem.value, "0123xypqm", msg + ".value == \"0123xypqm\"");
       is(elem.selectionStart, 9, msg + ".selectionStart == 9, with \"end\"");
       is(elem.selectionEnd, 9, msg + ".selectionEnd == 9, with \"end\"");
+      expectedNumOfSelectCalls += 1;
 
       //test SelectionMode 'preserve' (default)
 
       //subcase: selection{Start|End} > end
       elem.value = "0123456789";
       elem.setSelectionRange(6, 9);
       elem.setRangeText("Z", 1, 2, "preserve");
       is(elem.value, "0Z23456789", msg + ".value == \"0Z23456789\"");
       is(elem.selectionStart, 6, msg + ".selectionStart == 6, with \"preserve\"");
       is(elem.selectionEnd, 9, msg + ".selectionEnd == 9, with \"preserve\"");
+      expectedNumOfSelectCalls += 2;
 
       //subcase: selection{Start|End} < end
       elem.value = "0123456789";
       elem.setSelectionRange(4, 5);
       elem.setRangeText("QRST", 2, 9, "preserve");
       is(elem.value, "01QRST9", msg + ".value == \"01QRST9\"");
       is(elem.selectionStart, 2, msg + ".selectionStart == 2, with \"preserve\"");
       is(elem.selectionEnd, 6, msg + ".selectionEnd == 6, with \"preserve\"");
+      expectedNumOfSelectCalls += 2;
 
       //subcase: selectionStart > end, selectionEnd < end
       elem.value = "0123456789";
       elem.setSelectionRange(8, 4);
       elem.setRangeText("QRST", 1, 5);
       is(elem.value, "0QRST56789", msg + ".value == \"0QRST56789\"");
       is(elem.selectionStart, 1, msg + ".selectionStart == 1, with \"default\"");
       is(elem.selectionEnd, 5, msg + ".selectionEnd == 5, with \"default\"");
+      expectedNumOfSelectCalls += 2;
 
       //subcase: selectionStart < end, selectionEnd > end
       elem.value = "0123456789";
       elem.setSelectionRange(4, 9);
       elem.setRangeText("QRST", 2, 6);
       is(elem.value, "01QRST6789", msg + ".value == \"01QRST6789\"");
       is(elem.selectionStart, 2, msg + ".selectionStart == 2, with \"default\"");
       is(elem.selectionEnd, 9, msg + ".selectionEnd == 9, with \"default\"");
+      expectedNumOfSelectCalls += 2;
     }
-
-    SimpleTest.finish();
   }
 
   addLoadEvent(TestInputs);
 
 </script>
 </pre>
 </body>
 </html>