File: test_bug1315065.html

package info (click to toggle)
firefox 147.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,484 kB
  • sloc: cpp: 7,607,246; javascript: 6,533,185; ansic: 3,775,227; python: 1,415,393; xml: 634,561; asm: 438,951; java: 186,241; sh: 62,752; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (143 lines) | stat: -rw-r--r-- 6,387 bytes parent folder | download | duplicates (2)
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
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1315065
-->
<head>
  <meta charset="utf-8">
  <title>Test for Bug 1315065</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script src="/tests/SimpleTest/EventUtils.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1315065">Mozilla Bug 1315065</a>
<div contenteditable><p>abc<br></p></div>
<script type="application/javascript">
/** Test for Bug 1315065 */
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(() => {
  const editor = document.getElementsByTagName("div")[0];
  function initForBackspace(aSelectionCollapsedTo /* = 0 ~ 3 */) {
    editor.innerHTML = "<p id='p'>abc<br></p>";
    const p = document.getElementById("p");
    // FYI: We cannot inserting empty text nodes as expected with
    //      Node.appendChild() nor Node.insertBefore(). Therefore, let's use
    //      Range.insertNode() like actual web apps.
    const selection = window.getSelection();
    selection.collapse(p, 1);
    const range = selection.getRangeAt(0);
    const emptyTextNode3 = document.createTextNode("");
    range.insertNode(emptyTextNode3);
    const emptyTextNode2 = document.createTextNode("");
    range.insertNode(emptyTextNode2);
    const emptyTextNode1 = document.createTextNode("");
    range.insertNode(emptyTextNode1);
    is(p.childNodes.length, 5, "Failed to initialize the editor");
    is(p.childNodes.item(1), emptyTextNode1, "1st text node should be emptyTextNode1");
    is(p.childNodes.item(2), emptyTextNode2, "2nd text node should be emptyTextNode2");
    is(p.childNodes.item(3), emptyTextNode3, "3rd text node should be emptyTextNode3");
    switch (aSelectionCollapsedTo) {
      case 0:
        selection.collapse(p.firstChild, 3); // next to 'c'
        break;
      case 1:
        selection.collapse(emptyTextNode1, 0);
        break;
      case 2:
        selection.collapse(emptyTextNode2, 0);
        break;
      case 3:
        selection.collapse(emptyTextNode3, 0);
        break;
      default:
        ok(false, "aSelectionCollapsedTo is illegal value");
    }
  }

  for (let i = 0; i < 4; i++) {
    const kDescription = i == 0 ? "Backspace from immediately after the last character" :
                                  "Backspace from " + i + "th empty text node";
    editor.focus();
    initForBackspace(i);
    synthesizeKey("KEY_Backspace");
    const p = document.getElementById("p");
    ok(p, kDescription + ": <p> element shouldn't be removed by Backspace key press");
    is(p.tagName.toLowerCase(), "p", kDescription + ": <p> element shouldn't be removed by Backspace key press");
    // When Backspace key is pressed even in empty text nodes, Gecko should not remove empty text nodes for now
    // because we should keep our traditional behavior (same as Edge) for backward compatibility as far as possible.
    // In this case, Chromium removes all empty text nodes, but Edge doesn't remove any empty text nodes.
    // XXX It's fine to delete empty text nodes too if it's reasonable for handling deletion.
    is(p.childNodes.length, 4, kDescription + ": <p> should have 4 children after pressing Backspace key");
    is(p.childNodes.item(0).textContent, "ab", kDescription + ": 'c' should be removed by pressing Backspace key");
    is(p.childNodes.item(1).textContent, "", kDescription + ": 1st empty text node should not be removed by pressing Backspace key");
    is(p.childNodes.item(2).textContent, "", kDescription + ": 2nd empty text node should not be removed by pressing Backspace key");
    is(p.childNodes.item(3).textContent, "", kDescription + ": 3rd empty text node should not be removed by pressing Backspace key");
    editor.blur();
  }

  function initForDelete(aSelectionCollapsedTo /* = 0 ~ 3 */) {
    editor.innerHTML = "<p id='p'>abc<br></p>";
    const p = document.getElementById("p");
    // FYI: We cannot inserting empty text nodes as expected with
    //      Node.appendChild() nor Node.insertBefore(). Therefore, let's use
    //      Range.insertNode() like actual web apps.
    const selection = window.getSelection();
    selection.collapse(p, 0);
    const range = selection.getRangeAt(0);
    const emptyTextNode1 = document.createTextNode("");
    range.insertNode(emptyTextNode1);
    const emptyTextNode2 = document.createTextNode("");
    range.insertNode(emptyTextNode2);
    const emptyTextNode3 = document.createTextNode("");
    range.insertNode(emptyTextNode3);
    is(p.childNodes.length, 5, "Failed to initialize the editor");
    is(p.childNodes.item(0), emptyTextNode3, "1st text node should be emptyTextNode3");
    is(p.childNodes.item(1), emptyTextNode2, "2nd text node should be emptyTextNode2");
    is(p.childNodes.item(2), emptyTextNode1, "3rd text node should be emptyTextNode1");
    switch (aSelectionCollapsedTo) {
      case 0:
        selection.collapse(p.childNodes.item(3), 0); // next to 'a'
        break;
      case 1:
        selection.collapse(emptyTextNode1, 0);
        break;
      case 2:
        selection.collapse(emptyTextNode2, 0);
        break;
      case 3:
        selection.collapse(emptyTextNode3, 0);
        break;
      default:
        ok(false, "aSelectionCollapsedTo is illegal value");
    }
  }

  for (let i = 0; i < 4; i++) {
    const kDescription = i == 0 ? "Delete from immediately before the first character" :
                                  "Delete from " + i + "th empty text node";
    editor.focus();
    initForDelete(i);
    synthesizeKey("KEY_Delete");
    const p = document.getElementById("p");
    ok(p, kDescription + ": <p> element shouldn't be removed by Delete key press");
    is(p.tagName.toLowerCase(), "p", kDescription + ": <p> element shouldn't be removed by Delete key press");
    // If Delete key is pressed in an empty text node, it's fine to delete all
    // empty text nodes, but the non-empty text node should be modified.
    is(
      p.childNodes.length,
      2,
      `${kDescription}: <p> should have at least one text node after pressing Delete key`
    );
    is(
      p.textContent,
      "bc",
      `${kDescription}: empty text nodes and 'a' should be removed by pressing Delete key`
    );
    editor.blur();
  }
  SimpleTest.finish();
});
</script>
</body>
</html>