summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-after-content-change.html
blob: 60390085c6d93475ac94d880bc976995561740fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<!doctype html>
<meta charset="utf-8">
<title>Selection indices after content change</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<input id="i1" type="text" value="hello">
<textarea id="t1">hello</textarea>

<script>
"use strict";

// This helper ensures that when the selection direction is reset, it always is reset to the same value consistently
// (which must be one of either "none" or "forward"). This helps catch bugs like one observed in Chrome, where textareas
// reset to "none" but inputs reset to "forward".
let observedResetSelectionDirection;
function assertSelectionDirectionIsReset(element) {
  if (!observedResetSelectionDirection) {
    assert_in_array(element.selectionDirection, ["none", "forward"],
      "selectionDirection must be set to either none or forward");
    observedResetSelectionDirection = element.selectionDirection;
  } else {
    assert_equals(element.selectionDirection, observedResetSelectionDirection,
      `selectionDirection must be reset to ${observedResetSelectionDirection} (which was previously observed to be ` +
      `the value after resetting the selection direction)`);
  }
}

runInputTest("input out of document", () => {
  const input = document.createElement("input");
  input.value = "hello";
  return input;
});

runInputTest("input in document", () => {
  const input = document.querySelector("#i1");
  input.value = "hello";
  return input;
});

runInputTest("input in document, with focus", () => {
  const input = document.querySelector("#i1");
  input.value = "hello";
  input.focus();
  return input;
});

runTextareaTest("textarea out of document", () => {
  const textarea = document.createElement("textarea");
  textarea.value = "hello";
  return textarea;
});

runTextareaTest("textarea in document", () => {
  const textarea = document.querySelector("#t1");
  textarea.value = "hello";
  return textarea;
});

runTextareaTest("textarea in document, with focus", () => {
  const textarea = document.querySelector("#t1");
  textarea.value = "hello";
  textarea.focus();
  return textarea;
});

function runTest(descriptor, elementFactory) {
  test(() => {
    const element = elementFactory();
    element.setSelectionRange(1, 3, "backward");

    assert_equals(element.selectionStart, 1, "Sanity check: selectionStart was set correctly");
    assert_equals(element.selectionEnd, 3, "Sanity check: selectionEnd was set correctly");
    assert_equals(element.selectionDirection, "backward", "Sanity check: selectionDirection was set correctly");

    element.value = "hello";

    assert_equals(element.selectionStart, 1, "selectionStart must not change");
    assert_equals(element.selectionEnd, 3, "selectionEnd must not change");
    assert_equals(element.selectionDirection, "backward", "selectionDirection must not change");
  }, `${descriptor}: selection must not change when setting the same value`);

  test(() => {
    const element = elementFactory();
    element.setSelectionRange(1, 3, "backward");

    assert_equals(element.selectionStart, 1, "Sanity check: selectionStart was set correctly");
    assert_equals(element.selectionEnd, 3, "Sanity check: selectionEnd was set correctly");
    assert_equals(element.selectionDirection, "backward", "Sanity check: selectionDirection was set correctly");

    element.value = "hello2";

    assert_equals(element.selectionStart, element.value.length, "selectionStart must be reset to the end");
    assert_equals(element.selectionEnd, element.value.length, "selectionEnd must be reset to the end");
    assertSelectionDirectionIsReset(element);
  }, `${descriptor}: selection must change when setting a different value`);
}

function runInputTest(descriptor, elementFactory) {
  runTest(descriptor, elementFactory);

  test(() => {
    const input = elementFactory();
    input.setSelectionRange(1, 3, "backward");

    assert_equals(input.selectionStart, 1, "Sanity check: selectionStart was set correctly");
    assert_equals(input.selectionEnd, 3, "Sanity check: selectionEnd was set correctly");
    assert_equals(input.selectionDirection, "backward", "Sanity check: selectionDirection was set correctly");

    input.value = "he\nllo";

    assert_equals(input.selectionStart, 1, "selectionStart must not change");
    assert_equals(input.selectionEnd, 3, "selectionEnd must not change");
    assert_equals(input.selectionDirection, "backward", "selectionDirection must not change");
  }, `${descriptor}: selection must not change when setting a value that becomes the same after the value ` +
     `sanitization algorithm`);
}

function runTextareaTest(descriptor, elementFactory) {
  runTest(descriptor, elementFactory);

  test(() => {
    const textarea = elementFactory();
    textarea.value = "hell\no";
    textarea.setSelectionRange(1, 3, "backward");

    assert_equals(textarea.selectionStart, 1, "Sanity check: selectionStart was set correctly");
    assert_equals(textarea.selectionEnd, 3, "Sanity check: selectionEnd was set correctly");
    assert_equals(textarea.selectionDirection, "backward", "Sanity check: selectionDirection was set correctly");

    textarea.value = "hell\r\no";

    assert_equals(textarea.selectionStart, 1, "selectionStart must not change when setting to CRLF");
    assert_equals(textarea.selectionEnd, 3, "selectionEnd must not change when setting to CRLF");
    assert_equals(textarea.selectionDirection, "backward", "selectionDirection must not change when setting to CRLF");

    textarea.value = "hell\ro";

    assert_equals(textarea.selectionStart, 1, "selectionStart must not change when setting to CR");
    assert_equals(textarea.selectionEnd, 3, "selectionEnd must not change when setting to CR");
    assert_equals(textarea.selectionDirection, "backward", "selectionDirection must not change when setting to CR");
  }, `${descriptor}: selection must not change when setting the same normalized value`);
}
</script>