Bug 950444 - Make setRangeText() work for a collapsed range. r=ehsan
authorMats Palmgren <matspal@gmail.com>
Tue, 17 Dec 2013 13:30:24 +0000
changeset 171026 dacb4796c71c836612bcadcc243a18e5d946de04
parent 171025 be08b976b3151c7796af6ad1f435f3276ca7593a
child 171027 ec75b7fa730186ac33ce79e38e4cd6f102bbb417
push id5166
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:47:54 +0000
treeherdermozilla-aurora@977eb2548b2d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs950444
milestone29.0a1
Bug 950444 - Make setRangeText() work for a collapsed range. r=ehsan
content/html/content/src/HTMLInputElement.cpp
content/html/content/src/HTMLTextAreaElement.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
@@ -5083,17 +5083,17 @@ HTMLInputElement::SetRangeText(const nsA
         if (state && state->IsSelectionCached()) {
           aSelectionStart = state->GetSelectionProperties().mStart;
           aSelectionEnd = state->GetSelectionProperties().mEnd;
           aRv = NS_OK;
         }
       }
   }
 
-  if (aStart < aEnd) {
+  if (aStart <= aEnd) {
     value.Replace(aStart, aEnd - aStart, aReplacement);
     SetValueInternal(value, false, false);
   }
 
   uint32_t newEnd = aStart + aReplacement.Length();
   int32_t delta =  aReplacement.Length() - (aEnd - aStart);
 
   switch (aSelectMode) {
--- a/content/html/content/src/HTMLTextAreaElement.cpp
+++ b/content/html/content/src/HTMLTextAreaElement.cpp
@@ -944,17 +944,17 @@ HTMLTextAreaElement::SetRangeText(const 
         if (mState.IsSelectionCached()) {
           aSelectionStart = mState.GetSelectionProperties().mStart;
           aSelectionEnd = mState.GetSelectionProperties().mEnd;
           aRv = NS_OK;
         }
       }
   }
 
-  if (aStart < aEnd) {
+  if (aStart <= aEnd) {
     value.Replace(aStart, aEnd - aStart, aReplacement);
     SetValueInternal(value, false);
   }
 
   uint32_t newEnd = aStart + aReplacement.Length();
   int32_t delta =  aReplacement.Length() - (aEnd - aStart);
 
   switch (aSelectMode) {
--- a/content/html/content/test/forms/test_set_range_text.html
+++ b/content/html/content/test/forms/test_set_range_text.html
@@ -85,25 +85,69 @@ https://bugzilla.mozilla.org/show_bug.cg
           ok(false, "Too many select events were fired");
         }
       }, false);
 
       elem.addEventListener("input", function (aEvent) {
         ok(false, "input event should NOT be fired for " + + aEvent.target.id);
       }, false);
 
-      //test setRange(replacement)
+      var test = " setRange(replacement), shrink";
       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");
+      is(elem.value, "0xyz6789ABCDEF", msg + test);
+      is(elem.selectionStart, 1, msg + test);
+      is(elem.selectionEnd, 4, msg + test);
+      elem.setRangeText("mnk");
+      is(elem.value, "0mnk6789ABCDEF", msg + test);
+      expectedNumOfSelectCalls += 2;
+
+      test = " setRange(replacement), expand";
+      elem.value = "0123456789ABCDEF";
+      elem.setSelectionRange(1, 2);
+      elem.setRangeText("xyz");
+      is(elem.value, "0xyz23456789ABCDEF", msg + test);
+      is(elem.selectionStart, 1, msg + test);
+      is(elem.selectionEnd, 4, msg + test);
       elem.setRangeText("mnk");
-      is(elem.value, "0mnk6789ABCDEF", msg + ".value == \"0mnk6789ABCDEF\"");
+      is(elem.value, "0mnk23456789ABCDEF", msg + test);
+      expectedNumOfSelectCalls += 2;
+
+      test = " setRange(replacement) pure insertion at start";
+      elem.value = "0123456789ABCDEF";
+      elem.setSelectionRange(0, 0);
+      elem.setRangeText("xyz");
+      is(elem.value, "xyz0123456789ABCDEF", msg + test);
+      is(elem.selectionStart, 0, msg + test);
+      is(elem.selectionEnd, 0, msg + test);
+      elem.setRangeText("mnk");
+      is(elem.value, "mnkxyz0123456789ABCDEF", msg + test);
+      expectedNumOfSelectCalls += 2;
+
+      test = " setRange(replacement) pure insertion in the middle";
+      elem.value = "0123456789ABCDEF";
+      elem.setSelectionRange(4, 4);
+      elem.setRangeText("xyz");
+      is(elem.value, "0123xyz456789ABCDEF", msg + test);
+      is(elem.selectionStart, 4, msg + test);
+      is(elem.selectionEnd, 4, msg + test);
+      elem.setRangeText("mnk");
+      is(elem.value, "0123mnkxyz456789ABCDEF", msg + test);
+      expectedNumOfSelectCalls += 2;
+
+      test = " setRange(replacement) pure insertion at the end";
+      elem.value = "0123456789ABCDEF";
+      elem.setSelectionRange(16, 16);
+      elem.setRangeText("xyz");
+      is(elem.value, "0123456789ABCDEFxyz", msg + test);
+      is(elem.selectionStart, 16, msg + test);
+      is(elem.selectionEnd, 16, msg + test);
+      elem.setRangeText("mnk");
+      is(elem.value, "0123456789ABCDEFmnkxyz", msg + test);
       expectedNumOfSelectCalls += 2;
 
       //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);
       }