Skip to content

Commit

Permalink
Move selection to end when textarea value is assigned
Browse files Browse the repository at this point in the history
Issue #19171
  • Loading branch information
jonleighton committed Nov 25, 2017
1 parent ac57691 commit a7a5bab
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 56 deletions.
21 changes: 18 additions & 3 deletions components/script/dom/htmltextareaelement.rs
Expand Up @@ -34,7 +34,7 @@ use std::default::Default;
use std::ops::Range;
use style::attr::AttrValue;
use style::element_state::ElementState;
use textinput::{KeyReaction, Lines, SelectionDirection, TextInput};
use textinput::{Direction, KeyReaction, Lines, Selection, SelectionDirection, TextInput};

#[dom_struct]
pub struct HTMLTextAreaElement {
Expand Down Expand Up @@ -232,10 +232,25 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement {

// https://html.spec.whatwg.org/multipage/#dom-textarea-value
fn SetValue(&self, value: DOMString) {
// TODO move the cursor to the end of the field
self.textinput.borrow_mut().set_content(value);
let mut textinput = self.textinput.borrow_mut();

// Step 1
let old_value = textinput.get_content();
let old_selection = textinput.selection_begin;

// Step 2
textinput.set_content(value);

// Step 3
self.value_changed.set(true);

if old_value != textinput.get_content() {
// Step 4
textinput.adjust_horizontal_to_limit(Direction::Forward, Selection::NotSelected);
} else {
textinput.selection_begin = old_selection;
}

self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/wpt/metadata/MANIFEST.json
Expand Up @@ -542604,7 +542604,7 @@
"testharness"
],
"html/semantics/forms/textfieldselection/selection-value-interactions.html": [
"c568d7fe10cb4c2071b5d38530ad601988a789ea",
"39fe9646bbc2741e9bd3296d4e01513c99106151",
"testharness"
],
"html/semantics/forms/textfieldselection/selection.html": [
Expand Down
Expand Up @@ -3,33 +3,3 @@
[Setting selectionStart to a value larger than selectionEnd should increase selectionEnd]
expected: FAIL

[Setting selectionEnd to a value smaller than selectionStart should decrease selectionStart]
expected: FAIL

[selectionStart edge-case values]
expected: FAIL

[Initial .value set on textarea-appended should set selectionStart to end of value]
expected: FAIL

[Initial .value set on textarea-not-appended should set selectionStart to end of value]
expected: FAIL

[Initial .value set on textarea-appended-prefocused should set selectionStart to end of value]
expected: FAIL

[Initial .value set on textarea-not-appended-prefocused should set selectionStart to end of value]
expected: FAIL

[Initial .value set on textarea-appended should set selectionEnd to end of value]
expected: FAIL

[Initial .value set on textarea-not-appended should set selectionEnd to end of value]
expected: FAIL

[Initial .value set on textarea-appended-prefocused should set selectionEnd to end of value]
expected: FAIL

[Initial .value set on textarea-not-appended-prefocused should set selectionEnd to end of value]
expected: FAIL

Expand Up @@ -36,15 +36,9 @@
[test SelectionStart offset for textarea that is appended]
expected: FAIL

[test SelectionStart offset for textarea that is not appended]
expected: FAIL

[test SelectionEnd offset for input that is appended]
expected: FAIL

[test SelectionEnd offset for textarea that is appended]
expected: FAIL

[test SelectionEnd offset for textarea that is not appended]
expected: FAIL

Expand Up @@ -97,22 +97,31 @@
var el = document.createElement(tag);
document.body.appendChild(el);
this.add_cleanup(() => el.remove());
el.value = "";
assert_equals(el.selectionStart, el.value.length,
"element.selectionStart should be value.length");
assert_equals(el.selectionEnd, el.value.length,
"element.selectionEnd should be value.length");
el.value = "foo";
assert_equals(el.selectionStart, el.value.length,
"element.selectionStart should be value.length");
assert_equals(el.selectionEnd, el.value.length,
"element.selectionEnd should be value.length");
el.value = "foobar";
assert_equals(el.selectionStart, el.value.length,
"element.selectionStart should be value.length");
assert_equals(el.selectionEnd, el.value.length,
"element.selectionEnd should be value.length");
}, `selection is always collapsed to the end after setting values on ${tag}`);

for (let val of ["", "foo", "foobar"]) {
el.value = val;
assert_equals(el.selectionStart, val.length,
"element.selectionStart should be value.length");
assert_equals(el.selectionEnd, val.length,
"element.selectionEnd should be value.length");
}
}, `selection is collapsed to the end after changing values on ${tag}`);

test(function() {
var el = document.createElement(tag);
document.body.appendChild(el);
this.add_cleanup(() => el.remove());

el.value = "foobar"
el.selectionStart = 2
el.selectionEnd = 4
el.value = "foobar"

assert_equals(el.selectionStart, 2,
"element.selectionStart should be unchanged");
assert_equals(el.selectionEnd, 4,
"element.selectionEnd should be unchanged");
}, `selection is not collapsed to the end when value is set to its existing value on ${tag}`);
}

</script>

0 comments on commit a7a5bab

Please sign in to comment.