summaryrefslogtreecommitdiffstats
path: root/layout/reftests/selection
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /layout/reftests/selection
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/reftests/selection')
-rw-r--r--layout/reftests/selection/1478604-ref.html20
-rw-r--r--layout/reftests/selection/1478604.html23
-rw-r--r--layout/reftests/selection/addrange-1.html22
-rw-r--r--layout/reftests/selection/addrange-2.html23
-rw-r--r--layout/reftests/selection/addrange-ref.html18
-rw-r--r--layout/reftests/selection/disabled-1-ref.html6
-rw-r--r--layout/reftests/selection/disabled-1.html9
-rw-r--r--layout/reftests/selection/disabled-2-notref.html8
-rw-r--r--layout/reftests/selection/disabled-2.html9
-rw-r--r--layout/reftests/selection/dom-mutations-ref.html190
-rw-r--r--layout/reftests/selection/dom-mutations.html250
-rw-r--r--layout/reftests/selection/dynamic-text-1-ref.html15
-rw-r--r--layout/reftests/selection/dynamic-text-1a.html22
-rw-r--r--layout/reftests/selection/dynamic-text-1b.html20
-rw-r--r--layout/reftests/selection/extend-1-ref.html13
-rw-r--r--layout/reftests/selection/extend-1-sanity.html6
-rw-r--r--layout/reftests/selection/extend-1a.html19
-rw-r--r--layout/reftests/selection/extend-1b.html20
-rw-r--r--layout/reftests/selection/extend-1c.html20
-rw-r--r--layout/reftests/selection/extend-1d.html20
-rw-r--r--layout/reftests/selection/extend-1e.html20
-rw-r--r--layout/reftests/selection/extend-1f.html20
-rw-r--r--layout/reftests/selection/extend-1g.html20
-rw-r--r--layout/reftests/selection/extend-1h.html20
-rw-r--r--layout/reftests/selection/extend-1i.html20
-rw-r--r--layout/reftests/selection/extend-2-ref.html6
-rw-r--r--layout/reftests/selection/extend-2a.html20
-rw-r--r--layout/reftests/selection/extend-2b.html20
-rw-r--r--layout/reftests/selection/extend-3-ref.html27
-rw-r--r--layout/reftests/selection/extend-3-sanity.html17
-rw-r--r--layout/reftests/selection/extend-3a.html34
-rw-r--r--layout/reftests/selection/extend-3b.html33
-rw-r--r--layout/reftests/selection/extend-3c.html33
-rw-r--r--layout/reftests/selection/extend-3d.html33
-rw-r--r--layout/reftests/selection/extend-3e.html33
-rw-r--r--layout/reftests/selection/extend-3f.html33
-rw-r--r--layout/reftests/selection/extend-3g.html33
-rw-r--r--layout/reftests/selection/extend-3h.html33
-rw-r--r--layout/reftests/selection/extend-3i.html33
-rw-r--r--layout/reftests/selection/extend-4-ref.html17
-rw-r--r--layout/reftests/selection/extend-4a.html33
-rw-r--r--layout/reftests/selection/extend-4b.html33
-rw-r--r--layout/reftests/selection/invalidation-1-ref.html14
-rw-r--r--layout/reftests/selection/invalidation-1a.html21
-rw-r--r--layout/reftests/selection/invalidation-1b.html21
-rw-r--r--layout/reftests/selection/invalidation-1c.html21
-rw-r--r--layout/reftests/selection/invalidation-1d.html21
-rw-r--r--layout/reftests/selection/invalidation-1e.html21
-rw-r--r--layout/reftests/selection/invalidation-1f.html21
-rw-r--r--layout/reftests/selection/invalidation-2-ref.html8
-rw-r--r--layout/reftests/selection/invalidation-2a.html21
-rw-r--r--layout/reftests/selection/invalidation-2b.html21
-rw-r--r--layout/reftests/selection/invalidation-2c.html21
-rw-r--r--layout/reftests/selection/invalidation-2d.html21
-rw-r--r--layout/reftests/selection/invalidation-2e.html21
-rw-r--r--layout/reftests/selection/invalidation-2f.html21
-rw-r--r--layout/reftests/selection/modify-range-ref.html68
-rw-r--r--layout/reftests/selection/modify-range.html68
-rw-r--r--layout/reftests/selection/non-themed-widget-ref.html16
-rw-r--r--layout/reftests/selection/non-themed-widget.html12
-rw-r--r--layout/reftests/selection/pseudo-element-of-native-anonymous-ref.html13
-rw-r--r--layout/reftests/selection/pseudo-element-of-native-anonymous.html17
-rw-r--r--layout/reftests/selection/reftest.list60
-rw-r--r--layout/reftests/selection/rtl-selection-with-decoration-ref.html24
-rw-r--r--layout/reftests/selection/rtl-selection-with-decoration.html40
-rw-r--r--layout/reftests/selection/semitransparent-decoration-line-ref.html29
-rw-r--r--layout/reftests/selection/semitransparent-decoration-line.html45
-rw-r--r--layout/reftests/selection/shadow-tree-order-1-notref.html4
-rw-r--r--layout/reftests/selection/shadow-tree-order-1-ref.html13
-rw-r--r--layout/reftests/selection/shadow-tree-order-1.html18
-rw-r--r--layout/reftests/selection/splitText-normalize-ref.html40
-rw-r--r--layout/reftests/selection/splitText-normalize.html40
-rw-r--r--layout/reftests/selection/splitText-normalize.js86
-rw-r--r--layout/reftests/selection/themed-widget-ref.html13
-rw-r--r--layout/reftests/selection/themed-widget.html5
-rw-r--r--layout/reftests/selection/trailing-space-1-ref.html27
-rw-r--r--layout/reftests/selection/trailing-space-1.html27
-rw-r--r--layout/reftests/selection/writing-mode-ref.html39
-rw-r--r--layout/reftests/selection/writing-mode.html56
79 files changed, 2338 insertions, 0 deletions
diff --git a/layout/reftests/selection/1478604-ref.html b/layout/reftests/selection/1478604-ref.html
new file mode 100644
index 0000000000..1345e1966c
--- /dev/null
+++ b/layout/reftests/selection/1478604-ref.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html class="reftest-wait">
+<style>
+ input {
+ border: 0;
+ }
+</style>
+<label id="fooLabel" for="foo">Foo label</label>
+<input id="foo" type="text" value="foo" >
+<label id="barLabel" for="bar">Bar label</label>
+<input id="bar" type="text" value="bar">
+<script>
+onload = function() {
+ barLabel.click();
+ requestAnimationFrame(() => {
+ document.documentElement.className = "";
+ });
+}
+</script>
+</html>
diff --git a/layout/reftests/selection/1478604.html b/layout/reftests/selection/1478604.html
new file mode 100644
index 0000000000..5d17e5fd7b
--- /dev/null
+++ b/layout/reftests/selection/1478604.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<html class="reftest-wait">
+<style>
+ input {
+ border: 0;
+ }
+</style>
+<label id="fooLabel" for="foo">Foo label</label>
+<input id="foo" type="text" value="foo" >
+<label id="barLabel" for="bar">Bar label</label>
+<input id="bar" type="text" value="bar">
+<script>
+onload = function() {
+ fooLabel.click();
+ requestAnimationFrame(() => {
+ barLabel.click();
+ requestAnimationFrame(() => {
+ document.documentElement.className = "";
+ });
+ });
+}
+</script>
+</html>
diff --git a/layout/reftests/selection/addrange-1.html b/layout/reftests/selection/addrange-1.html
new file mode 100644
index 0000000000..648d421404
--- /dev/null
+++ b/layout/reftests/selection/addrange-1.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Testcase #2 for bug 602331</title>
+ <script type="text/javascript" charset="utf-8">
+ function selectNewlyAdded() {
+ window.getSelection().removeAllRanges();
+
+ var newNode = document.createElement('span');
+ newNode.innerHTML = "Hello Kitty";
+ document.getElementById('new_nodes').appendChild(newNode);
+ var range = document.createRange();
+ range.selectNode(newNode);
+ window.getSelection().addRange(range);
+ }
+
+ </script>
+ </head>
+ <body onload="selectNewlyAdded()">
+ * <span id="new_nodes"></span> *
+ </body>
+</html>
diff --git a/layout/reftests/selection/addrange-2.html b/layout/reftests/selection/addrange-2.html
new file mode 100644
index 0000000000..480e936780
--- /dev/null
+++ b/layout/reftests/selection/addrange-2.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Testcase #3 for bug 602331</title>
+ <script type="text/javascript" charset="utf-8">
+ function selectAllOfNewNodes() {
+ window.getSelection().removeAllRanges();
+
+ var newNode = document.createElement('span');
+ newNode.innerHTML = "Kitty";
+ document.getElementById('new_nodes').appendChild(newNode);
+ var range = document.createRange();
+ range.selectNode(document.getElementById('new_nodes'));
+ window.getSelection().addRange(range);
+
+ }
+
+ </script>
+ </head>
+ <body onload="selectAllOfNewNodes()">
+ * <span id="new_nodes"><span>Hello</span> </span> *
+ </body>
+</html>
diff --git a/layout/reftests/selection/addrange-ref.html b/layout/reftests/selection/addrange-ref.html
new file mode 100644
index 0000000000..4e6a70db2f
--- /dev/null
+++ b/layout/reftests/selection/addrange-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Testcase #1 for bug 602331</title>
+ <script type="text/javascript" charset="utf-8">
+ function selectExisting() {
+ window.getSelection().removeAllRanges();
+
+ var range = document.createRange();
+ range.selectNode(document.getElementById('existing_node'));
+ window.getSelection().addRange(range);
+ }
+ </script>
+ </head>
+ <body onload="selectExisting()">
+ * <span id="existing_node">Hello Kitty</span> *
+ </body>
+</html>
diff --git a/layout/reftests/selection/disabled-1-ref.html b/layout/reftests/selection/disabled-1-ref.html
new file mode 100644
index 0000000000..f259ca439d
--- /dev/null
+++ b/layout/reftests/selection/disabled-1-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<input id="outside" value="abc">
+<iframe srcdoc="<!doctype html>Something inside <input value='some input'>"></iframe>
+<script>
+document.getElementById("outside").select();
+</script>
diff --git a/layout/reftests/selection/disabled-1.html b/layout/reftests/selection/disabled-1.html
new file mode 100644
index 0000000000..a62971d076
--- /dev/null
+++ b/layout/reftests/selection/disabled-1.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<input id="outside" value="abc">
+<iframe srcdoc="<!doctype html>Something inside <input value='some input'>"></iframe>
+<script>
+onload = function() {
+ document.querySelector("iframe").contentDocument.querySelector("input").select();
+ document.getElementById("outside").select();
+}
+</script>
diff --git a/layout/reftests/selection/disabled-2-notref.html b/layout/reftests/selection/disabled-2-notref.html
new file mode 100644
index 0000000000..ecce9e7054
--- /dev/null
+++ b/layout/reftests/selection/disabled-2-notref.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<input id="outside" style="position: absolute; left: 200vw;"> <!-- intentionally out of view -->
+<iframe srcdoc="<!doctype html>Something inside <input value='some input'>"></iframe>
+<script>
+onload = function() {
+ document.querySelector("iframe").contentDocument.querySelector("input").select();
+}
+</script>
diff --git a/layout/reftests/selection/disabled-2.html b/layout/reftests/selection/disabled-2.html
new file mode 100644
index 0000000000..fc61d29563
--- /dev/null
+++ b/layout/reftests/selection/disabled-2.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<input id="outside" style="position: absolute; left: 200vw;"> <!-- intentionally out of view -->
+<iframe srcdoc="<!doctype html>Something inside <input value='some input'>"></iframe>
+<script>
+onload = function() {
+ document.querySelector("iframe").contentDocument.querySelector("input").select();
+ document.getElementById("outside").select();
+}
+</script>
diff --git a/layout/reftests/selection/dom-mutations-ref.html b/layout/reftests/selection/dom-mutations-ref.html
new file mode 100644
index 0000000000..5d2e29dcb5
--- /dev/null
+++ b/layout/reftests/selection/dom-mutations-ref.html
@@ -0,0 +1,190 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=619273
+-->
+<head>
+ <title>Test for Bug 619273</title>
+<script type="application/javascript">
+/** Test DOM mutations inside selection **/
+function createDOM(doc) {
+ let s = doc.createElement('span');
+ s.appendChild(doc.createTextNode('|'))
+ let s2 = doc.createElement('span');
+ s2.appendChild(doc.createTextNode('z'))
+ s.appendChild(s2)
+ return s;
+}
+
+var tests_done = 0;
+var tests = [
+ function(win,doc,sel) {
+ doc.body.innerHTML = '.I<br>B<br>C|z'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(a, 1);
+ r.setEnd(a, 2);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = '.I<br>B<br>C|z'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(doc.firstChild, 0);
+ r.setEnd(a, 2);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>.B<br>C|z'
+ let a = doc.body.firstChild;
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>.B<br>C|z'
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(doc.body, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>.B<br>C|z'
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(doc, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>.C|z'
+ let a = doc.body.firstChild;
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 2);
+ sel.addRange(r);
+ },
+
+ function(win,doc,sel) {
+ doc.body.innerHTML = '|z|zI<br>B<br>C'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(a, 4);
+ r.setEnd(a, 5);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = '|z|zI<br>B<br>C'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(doc.firstChild, 0);
+ r.setEnd(a, 5);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>|z|zB<br>C'
+ let a = doc.body.firstChild;
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>|z|zB<br>C'
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(doc.body, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>|z|zB<br>C'
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(doc, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>|z|zC'
+ let a = doc.body.firstChild;
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 5);
+ sel.addRange(r);
+ },
+
+ function(win,doc,sel) {
+ doc.body.innerHTML = '<br>B<br>CI'
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = '<br>B<br>C'
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ },
+
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I|z'
+ },
+
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'Iz|'
+
+ document.body.appendChild(document.createTextNode('I'));
+ document.body.appendChild(document.createTextNode(' '));
+ document.body.appendChild(createDOM(document));
+ },
+]
+
+function runTestInIframe(run,t) {
+ let f = document.createElement('iframe');
+ f.setAttribute('frameborder','0');
+ f.setAttribute('height','100');
+ f.setAttribute('width','200');
+ f.src = 'data:text/html,<body style="margin:0;padding:0;font-family:monospace">';
+ f.onload = function () {
+ try {
+ run(f.contentWindow, f.contentDocument, f.contentWindow.getSelection());
+ } finally { ++tests_done; }
+ }
+ return f;
+}
+
+var id;
+function checkFinished() {
+ if (window.frames.length == tests_done) {
+ clearInterval(id);
+ document.documentElement.className = "";
+ }
+}
+
+function runTest() {
+ for (let i=0; i < tests.length; ++i) {
+ let t = tests[i];
+ document.body.appendChild(runTestInIframe(t));
+ }
+ id = setInterval(checkFinished,500);
+}
+</script>
+</head>
+<body onload="runTest()"></body>
+</html>
diff --git a/layout/reftests/selection/dom-mutations.html b/layout/reftests/selection/dom-mutations.html
new file mode 100644
index 0000000000..f81267f596
--- /dev/null
+++ b/layout/reftests/selection/dom-mutations.html
@@ -0,0 +1,250 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=619273
+-->
+<head>
+ <title>Test for Bug 619273</title>
+<script type="application/javascript">
+/** Test DOM mutations inside selection **/
+function createDOM(doc) {
+ let s = doc.createElement('span');
+ s.appendChild(doc.createTextNode('|'))
+ let s2 = doc.createElement('span');
+ s2.appendChild(doc.createTextNode('z'))
+ s.appendChild(s2)
+ return s;
+}
+
+var tests_done = 0;
+var tests = [
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(a, 1);
+ sel.addRange(r);
+ doc.body.insertBefore(doc.createTextNode('.'), a);
+ doc.body.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(doc.firstChild, 0);
+ r.setEnd(a, 1);
+ sel.addRange(r);
+ doc.body.insertBefore(doc.createTextNode('.'), a);
+ doc.body.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ doc.body.insertBefore(doc.createTextNode('.'), b);
+ doc.body.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(doc.body, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ doc.body.insertBefore(doc.createTextNode('.'), b);
+ doc.body.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(doc, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ doc.body.insertBefore(doc.createTextNode('.'), b);
+ doc.body.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ doc.body.insertBefore(doc.createTextNode('.'), c);
+ doc.body.appendChild(createDOM(doc));
+ },
+
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(a, 1);
+ sel.addRange(r);
+ let span = createDOM(doc);
+ doc.body.insertBefore(span, a);
+ span.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(doc.firstChild, 0);
+ r.setEnd(a, 1);
+ sel.addRange(r);
+ let span = createDOM(doc);
+ doc.body.insertBefore(span, a);
+ span.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ let span = createDOM(doc);
+ doc.body.insertBefore(span, b);
+ span.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(doc.body, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ let span = createDOM(doc);
+ doc.body.insertBefore(span, b);
+ span.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let b = doc.body.childNodes[2];
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(doc, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ let span = createDOM(doc);
+ doc.body.insertBefore(span, b);
+ span.appendChild(createDOM(doc));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ let span = createDOM(doc);
+ doc.body.insertBefore(span, c);
+ span.appendChild(createDOM(doc));
+ },
+
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(a, 1);
+ sel.addRange(r);
+ doc.body.appendChild(a);
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(a, 1);
+ sel.addRange(r);
+ document.adoptNode(a);
+ document.body.appendChild(a);
+ document.body.appendChild(document.createTextNode(' '));
+ },
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I<br>B<br>C'
+ let a = doc.body.firstChild;
+ let c = doc.body.childNodes[4];
+ let r = doc.createRange();
+ r.setStart(a, 0);
+ r.setEnd(c, 1);
+ sel.addRange(r);
+ let span = createDOM(doc);
+ doc.body.insertBefore(span, c);
+ document.adoptNode(span);
+ document.body.appendChild(span);
+ },
+
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I'
+ let a = doc.body.firstChild;
+ let span = createDOM(doc);
+ let r = doc.createRange();
+ r.setStart(span, 0);
+ r.setEnd(span, 1);
+ sel.addRange(r);
+ doc.body.appendChild(span);
+ },
+
+ function(win,doc,sel) {
+ doc.body.innerHTML = 'I'
+ let a = doc.body.firstChild;
+ let span = createDOM(doc);
+ let r = doc.createRange();
+ r.setStart(span.firstChild, 0);
+ r.setEnd(span.firstChild, 1);
+ sel.addRange(r);
+ doc.body.appendChild(span);
+ doc.body.appendChild(span.firstChild);
+ r.setEnd(span.firstChild, 1);
+ },
+]
+
+function runTestInIframe(run,t) {
+ let f = document.createElement('iframe');
+ f.setAttribute('frameborder','0');
+ f.setAttribute('height','100');
+ f.setAttribute('width','200');
+ f.src = 'data:text/html,<body style="margin:0;padding:0;font-family:monospace">';
+ f.onload = function () {
+ try {
+ run(f.contentWindow, f.contentDocument, f.contentWindow.getSelection());
+ } finally { ++tests_done; }
+ }
+ return f;
+}
+
+var id;
+function checkFinished() {
+ if (window.frames.length == tests_done) {
+ clearInterval(id);
+ document.documentElement.className = "";
+ }
+}
+
+function runTest() {
+ for (let i=0; i < tests.length; ++i) {
+ let t = tests[i];
+ document.body.appendChild(runTestInIframe(t));
+ }
+ id = setInterval(checkFinished,500);
+}
+</script>
+</head>
+<body onload="runTest()"></body>
+</html>
diff --git a/layout/reftests/selection/dynamic-text-1-ref.html b/layout/reftests/selection/dynamic-text-1-ref.html
new file mode 100644
index 0000000000..7552979633
--- /dev/null
+++ b/layout/reftests/selection/dynamic-text-1-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body style="white-space:pre"> BC
+ FG
+ JK
+<script>
+document.body.offsetTop;
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 6);
+sel.extend(t, 8);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/dynamic-text-1a.html b/layout/reftests/selection/dynamic-text-1a.html
new file mode 100644
index 0000000000..30e56ad3bc
--- /dev/null
+++ b/layout/reftests/selection/dynamic-text-1a.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"> 00
+ BC
+ FG
+ JK
+<script>
+document.body.offsetTop;
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 11);
+sel.extend(t, 13);
+
+function doTest() {
+ t.replaceData(0, 5, '');
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/dynamic-text-1b.html b/layout/reftests/selection/dynamic-text-1b.html
new file mode 100644
index 0000000000..1ffcf2329d
--- /dev/null
+++ b/layout/reftests/selection/dynamic-text-1b.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"> FG
+ JK
+<script>
+document.body.offsetTop;
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 1);
+sel.extend(t, 3);
+
+function doTest() {
+ t.insertData(0, ' BC \n');
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1-ref.html b/layout/reftests/selection/extend-1-ref.html
new file mode 100644
index 0000000000..a3d5bd9f8d
--- /dev/null
+++ b/layout/reftests/selection/extend-1-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 2);
+sel.extend(t, 8);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1-sanity.html b/layout/reftests/selection/extend-1-sanity.html
new file mode 100644
index 0000000000..5e362a5133
--- /dev/null
+++ b/layout/reftests/selection/extend-1-sanity.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body style="white-space:pre">0123456789
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1a.html b/layout/reftests/selection/extend-1a.html
new file mode 100644
index 0000000000..b1ae4650b9
--- /dev/null
+++ b/layout/reftests/selection/extend-1a.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 2);
+sel.extend(t, 9);
+
+function doTest() {
+ sel.extend(t, 8);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1b.html b/layout/reftests/selection/extend-1b.html
new file mode 100644
index 0000000000..666158cc67
--- /dev/null
+++ b/layout/reftests/selection/extend-1b.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test newfocus < anchor < focus
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 8); // anchor
+sel.extend(t, 9); // focus
+
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1c.html b/layout/reftests/selection/extend-1c.html
new file mode 100644
index 0000000000..0a963f4405
--- /dev/null
+++ b/layout/reftests/selection/extend-1c.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test anchor < newfocus < focus
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 2); // anchor
+sel.extend(t, 9); // focus
+
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1d.html b/layout/reftests/selection/extend-1d.html
new file mode 100644
index 0000000000..027f47e24e
--- /dev/null
+++ b/layout/reftests/selection/extend-1d.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test anchor < newfocus = focus
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 2); // anchor
+sel.extend(t, 8); // focus
+
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1e.html b/layout/reftests/selection/extend-1e.html
new file mode 100644
index 0000000000..d87d105761
--- /dev/null
+++ b/layout/reftests/selection/extend-1e.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test anchor < focus < newfocus
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 2); // anchor
+sel.extend(t, 6); // focus
+
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1f.html b/layout/reftests/selection/extend-1f.html
new file mode 100644
index 0000000000..b04adbde65
--- /dev/null
+++ b/layout/reftests/selection/extend-1f.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test newfocus < focus < anchor
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 8); // anchor
+sel.extend(t, 4); // focus
+
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1g.html b/layout/reftests/selection/extend-1g.html
new file mode 100644
index 0000000000..b91d792761
--- /dev/null
+++ b/layout/reftests/selection/extend-1g.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test newfocus = focus < anchor
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 8); // anchor
+sel.extend(t, 2); // focus
+
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1h.html b/layout/reftests/selection/extend-1h.html
new file mode 100644
index 0000000000..57269776e1
--- /dev/null
+++ b/layout/reftests/selection/extend-1h.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test focus < newfocus < anchor
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 8); // anchor
+sel.extend(t, 1); // focus
+
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-1i.html b/layout/reftests/selection/extend-1i.html
new file mode 100644
index 0000000000..4165397f68
--- /dev/null
+++ b/layout/reftests/selection/extend-1i.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test focus < anchor < newfocus
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 2); // anchor
+sel.extend(t, 1); // focus
+
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-2-ref.html b/layout/reftests/selection/extend-2-ref.html
new file mode 100644
index 0000000000..5e362a5133
--- /dev/null
+++ b/layout/reftests/selection/extend-2-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body style="white-space:pre">0123456789
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-2a.html b/layout/reftests/selection/extend-2a.html
new file mode 100644
index 0000000000..20565fd72d
--- /dev/null
+++ b/layout/reftests/selection/extend-2a.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test newfocus = anchor < focus
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 2); // anchor
+sel.extend(t, 8); // focus
+
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-2b.html b/layout/reftests/selection/extend-2b.html
new file mode 100644
index 0000000000..553ead891d
--- /dev/null
+++ b/layout/reftests/selection/extend-2b.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre">0123456789
+<script>
+document.body.offsetTop;
+// Test focus < anchor = newfocus
+var t = document.body.firstChild;
+var sel = window.getSelection();
+sel.collapse(t, 8); // anchor
+sel.extend(t, 2); // focus
+
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3-ref.html b/layout/reftests/selection/extend-3-ref.html
new file mode 100644
index 0000000000..fa4ed01bbb
--- /dev/null
+++ b/layout/reftests/selection/extend-3-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 2);
+ sel.extend(t, 8);
+}
+window.addEventListener("load", loaded);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3-sanity.html b/layout/reftests/selection/extend-3-sanity.html
new file mode 100644
index 0000000000..9be4706484
--- /dev/null
+++ b/layout/reftests/selection/extend-3-sanity.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3a.html b/layout/reftests/selection/extend-3a.html
new file mode 100644
index 0000000000..54b44a52d0
--- /dev/null
+++ b/layout/reftests/selection/extend-3a.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+var sel = window.getSelection();
+// Don't start the selection until the document is loaded; we may reconstruct
+// frames for the images, which will lose their selection state (this is a bug)
+function loaded() {
+ sel.collapse(t, 2);
+ sel.extend(t, 9);
+}
+function doTest() {
+ sel.extend(t, 8);
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3b.html b/layout/reftests/selection/extend-3b.html
new file mode 100644
index 0000000000..4992fa6f99
--- /dev/null
+++ b/layout/reftests/selection/extend-3b.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+// Test newfocus < anchor < focus
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 8); // anchor
+ sel.extend(t, 9); // focus
+}
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3c.html b/layout/reftests/selection/extend-3c.html
new file mode 100644
index 0000000000..5ffd190909
--- /dev/null
+++ b/layout/reftests/selection/extend-3c.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+// Test anchor < newfocus < focus
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 2); // anchor
+ sel.extend(t, 9); // focus
+}
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3d.html b/layout/reftests/selection/extend-3d.html
new file mode 100644
index 0000000000..8d293823ec
--- /dev/null
+++ b/layout/reftests/selection/extend-3d.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+// Test anchor < newfocus = focus
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 2); // anchor
+ sel.extend(t, 8); // focus
+}
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3e.html b/layout/reftests/selection/extend-3e.html
new file mode 100644
index 0000000000..9cd8aa5b2f
--- /dev/null
+++ b/layout/reftests/selection/extend-3e.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+// Test anchor < focus < newfocus
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 2); // anchor
+ sel.extend(t, 6); // focus
+}
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3f.html b/layout/reftests/selection/extend-3f.html
new file mode 100644
index 0000000000..0b534a15d3
--- /dev/null
+++ b/layout/reftests/selection/extend-3f.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+// Test newfocus < focus < anchor
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 8); // anchor
+ sel.extend(t, 4); // focus
+}
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3g.html b/layout/reftests/selection/extend-3g.html
new file mode 100644
index 0000000000..9a4cc70823
--- /dev/null
+++ b/layout/reftests/selection/extend-3g.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+// Test newfocus = focus < anchor
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 8); // anchor
+ sel.extend(t, 2); // focus
+}
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3h.html b/layout/reftests/selection/extend-3h.html
new file mode 100644
index 0000000000..9c802bbd48
--- /dev/null
+++ b/layout/reftests/selection/extend-3h.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+// Test focus < newfocus < anchor
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 8); // anchor
+ sel.extend(t, 1); // focus
+}
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-3i.html b/layout/reftests/selection/extend-3i.html
new file mode 100644
index 0000000000..61db7b0c6b
--- /dev/null
+++ b/layout/reftests/selection/extend-3i.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+var t = document.body;
+// Test focus < anchor < newfocus
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 2); // anchor
+ sel.extend(t, 1); // focus
+}
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-4-ref.html b/layout/reftests/selection/extend-4-ref.html
new file mode 100644
index 0000000000..9be4706484
--- /dev/null
+++ b/layout/reftests/selection/extend-4-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-4a.html b/layout/reftests/selection/extend-4a.html
new file mode 100644
index 0000000000..87182829e4
--- /dev/null
+++ b/layout/reftests/selection/extend-4a.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+// Test newfocus = anchor < focus
+var t = document.body;
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 2); // anchor
+ sel.extend(t, 8); // focus
+}
+function doTest() {
+ sel.extend(t, 2); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/extend-4b.html b/layout/reftests/selection/extend-4b.html
new file mode 100644
index 0000000000..0ba691c2ca
--- /dev/null
+++ b/layout/reftests/selection/extend-4b.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body style="white-space:pre"
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+><img src="data:image/gif;base64,R0lGODlhEAAQAPAAALuWAAAAACH5BAUIAAEALAMAAwAKAAoAAAIMDI5nye0Po5xutVAAADs="
+>
+<script>
+document.body.offsetTop;
+// Test focus < anchor = newfocus
+var t = document.body;
+var sel = window.getSelection();
+function loaded() {
+ sel.collapse(t, 8); // anchor
+ sel.extend(t, 2); // focus
+}
+function doTest() {
+ sel.extend(t, 8); // newfocus
+ document.documentElement.removeAttribute('class');
+}
+window.addEventListener("load", loaded);
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-1-ref.html b/layout/reftests/selection/invalidation-1-ref.html
new file mode 100644
index 0000000000..a0f7f151e9
--- /dev/null
+++ b/layout/reftests/selection/invalidation-1-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.firstChild, 0, p2.firstChild, 2);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-1a.html b/layout/reftests/selection/invalidation-1a.html
new file mode 100644
index 0000000000..4cec34c984
--- /dev/null
+++ b/layout/reftests/selection/invalidation-1a.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.collapse(p1.firstChild, 0);
+
+function doTest() {
+ selection.extend(p2.firstChild, 2);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-1b.html b/layout/reftests/selection/invalidation-1b.html
new file mode 100644
index 0000000000..36cd3d4402
--- /dev/null
+++ b/layout/reftests/selection/invalidation-1b.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.firstChild, 0, p1.firstChild, 1);
+
+function doTest() {
+ selection.extend(p2.firstChild, 2);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-1c.html b/layout/reftests/selection/invalidation-1c.html
new file mode 100644
index 0000000000..96edcc28d8
--- /dev/null
+++ b/layout/reftests/selection/invalidation-1c.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.firstChild, 0, p1.childNodes.item(1).firstChild, 0);
+
+function doTest() {
+ selection.extend(p2.firstChild, 2);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-1d.html b/layout/reftests/selection/invalidation-1d.html
new file mode 100644
index 0000000000..d9cfa97f12
--- /dev/null
+++ b/layout/reftests/selection/invalidation-1d.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.firstChild, 0, p1.childNodes.item(1).firstChild, 1);
+
+function doTest() {
+ selection.extend(p2.firstChild, 2);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-1e.html b/layout/reftests/selection/invalidation-1e.html
new file mode 100644
index 0000000000..dac4c6ac22
--- /dev/null
+++ b/layout/reftests/selection/invalidation-1e.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.firstChild, 0, p1.lastChild, 0);
+
+function doTest() {
+ selection.extend(p2.firstChild, 2);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-1f.html b/layout/reftests/selection/invalidation-1f.html
new file mode 100644
index 0000000000..0d4bdbb607
--- /dev/null
+++ b/layout/reftests/selection/invalidation-1f.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.firstChild, 0, p1.lastChild, 1);
+
+function doTest() {
+ selection.extend(p2.firstChild, 2);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-2-ref.html b/layout/reftests/selection/invalidation-2-ref.html
new file mode 100644
index 0000000000..f79e64a999
--- /dev/null
+++ b/layout/reftests/selection/invalidation-2-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-2a.html b/layout/reftests/selection/invalidation-2a.html
new file mode 100644
index 0000000000..520cbbef8e
--- /dev/null
+++ b/layout/reftests/selection/invalidation-2a.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.firstChild, 0, p2.firstChild, 2);
+
+function doTest() {
+ selection.collapse(p2.firstChild, 3);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-2b.html b/layout/reftests/selection/invalidation-2b.html
new file mode 100644
index 0000000000..176c49cb81
--- /dev/null
+++ b/layout/reftests/selection/invalidation-2b.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.firstChild, 1, p2.firstChild, 2);
+
+function doTest() {
+ selection.collapse(p2.firstChild, 3);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-2c.html b/layout/reftests/selection/invalidation-2c.html
new file mode 100644
index 0000000000..8d3bfd15cc
--- /dev/null
+++ b/layout/reftests/selection/invalidation-2c.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.childNodes.item(1).firstChild, 0, p2.firstChild, 2);
+
+function doTest() {
+ selection.collapse(p2.firstChild, 3);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-2d.html b/layout/reftests/selection/invalidation-2d.html
new file mode 100644
index 0000000000..d2163bae77
--- /dev/null
+++ b/layout/reftests/selection/invalidation-2d.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.childNodes.item(1).firstChild, 1, p2.firstChild, 2);
+
+function doTest() {
+ selection.collapse(p2.firstChild, 3);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-2e.html b/layout/reftests/selection/invalidation-2e.html
new file mode 100644
index 0000000000..bbc8d11145
--- /dev/null
+++ b/layout/reftests/selection/invalidation-2e.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.lastChild, 0, p2.firstChild, 2);
+
+function doTest() {
+ selection.collapse(p2.firstChild, 3);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/invalidation-2f.html b/layout/reftests/selection/invalidation-2f.html
new file mode 100644
index 0000000000..f74821f90f
--- /dev/null
+++ b/layout/reftests/selection/invalidation-2f.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<body>
+<p id="first">f<span>o</span>o</p>
+<p id="second">bar</p>
+<script>
+document.body.offsetTop;
+var p1 = document.getElementById("first");
+var p2 = document.getElementById("second");
+var selection = window.getSelection();
+selection.setBaseAndExtent(p1.lastChild, 1, p2.firstChild, 2);
+
+function doTest() {
+ selection.collapse(p2.firstChild, 3);
+ document.documentElement.removeAttribute('class');
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+</script>
+</body>
+</html>
diff --git a/layout/reftests/selection/modify-range-ref.html b/layout/reftests/selection/modify-range-ref.html
new file mode 100644
index 0000000000..5086fcef8a
--- /dev/null
+++ b/layout/reftests/selection/modify-range-ref.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait"><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Testcase for bug </title>
+<script>
+var tests_done = 0;
+var tests = [
+ 'window.getSelection().getRangeAt(0).setEnd(document.getElementsByTagName("pre")[0].firstChild,9)',
+ 'window.getSelection().getRangeAt(0).setEndAfter(document.getElementsByTagName("pre")[0].firstChild)',
+ 'window.getSelection().getRangeAt(0).setEndBefore(document.getElementsByTagName("pre")[0].childNodes[1])',
+ 'pre=document.getElementsByTagName("pre")[0]; r=window.getSelection().getRangeAt(0); r.setEnd(pre.childNodes[1],3); r.setStartAfter(pre.firstChild)',
+ 'window.getSelection().getRangeAt(0).setStartBefore(document.getElementsByTagName("pre")[0].firstChild)',
+ 'window.getSelection().getRangeAt(0).selectNode(document.getElementsByTagName("pre")[0].firstChild)',
+ 'window.getSelection().getRangeAt(0).selectNodeContents(document.getElementsByTagName("pre")[0])',
+ 'window.getSelection().getRangeAt(0).collapse(true)',
+ 'window.getSelection().getRangeAt(0).surroundContents(document.createElement("span"))',
+ 'window.getSelection().getRangeAt(0).setStart(document,0)',
+ 'window.getSelection().getRangeAt(0).detach()',
+ 'window.getSelection().getRangeAt(0).extractContents()',
+ 'window.getSelection().getRangeAt(0).deleteContents()'
+];
+function init_iframe(d) {
+ var pre = d.createElement('pre');
+ pre.appendChild(d.createTextNode('first\nfirst\n'));
+ pre.appendChild(d.createTextNode('second'));
+ d.documentElement.appendChild(pre);
+ var text = pre.firstChild;
+ var sel = d.defaultView.getSelection();
+ var r = d.createRange();
+ r.setStart(text,0)
+ r.setEnd(text,3)
+ sel.addRange(r);
+ d.documentElement.offsetHeight;
+}
+function test_iframe(iframe, i) {
+ iframe.contentDocument.write(
+ '<'+'style>span { text-decoration:underline; } <'+'/style>' +
+ '<'+'script>' +
+ 'window.parent.init_iframe(document);' +
+ 'setTimeout(function(){' + window.parent.tests[i] + '; sel=window.getSelection(); try{r=sel.getRangeAt(0); sel.removeRange(r); sel.addRange(r);}catch(e){}; ++window.parent.tests_done; },0)' +
+ '<'+'/script>'
+ );
+}
+function create_iframe(i) {
+ var div = document.createElement('div');
+ document.body.appendChild(div);
+ div.innerHTML = "<iframe src='about:blank' style='height:6em; width:12em; float:left;' frameborder='0' onload='test_iframe(this,"+i+")'><iframe>"
+}
+
+var id;
+function check_if_done() {
+ if (tests_done == tests.length) {
+ clearInterval(id);
+ document.documentElement.className = "";
+ }
+}
+
+function test() {
+ for (i = 0; i < tests.length; ++i) {
+ create_iframe(i);
+ }
+ id = setInterval(check_if_done,500);
+}
+</script>
+
+</head>
+<body onload="test()"></body>
+</html>
diff --git a/layout/reftests/selection/modify-range.html b/layout/reftests/selection/modify-range.html
new file mode 100644
index 0000000000..2595511ed0
--- /dev/null
+++ b/layout/reftests/selection/modify-range.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait"><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Testcase for bug </title>
+<script>
+var tests_done = 0;
+var tests = [
+ 'window.getSelection().getRangeAt(0).setEnd(document.getElementsByTagName("pre")[0].firstChild,9)',
+ 'window.getSelection().getRangeAt(0).setEndAfter(document.getElementsByTagName("pre")[0].firstChild)',
+ 'window.getSelection().getRangeAt(0).setEndBefore(document.getElementsByTagName("pre")[0].childNodes[1])',
+ 'pre=document.getElementsByTagName("pre")[0]; r=window.getSelection().getRangeAt(0); r.setEnd(pre.childNodes[1],3); r.setStartAfter(pre.firstChild)',
+ 'window.getSelection().getRangeAt(0).setStartBefore(document.getElementsByTagName("pre")[0].firstChild)',
+ 'window.getSelection().getRangeAt(0).selectNode(document.getElementsByTagName("pre")[0].firstChild)',
+ 'window.getSelection().getRangeAt(0).selectNodeContents(document.getElementsByTagName("pre")[0])',
+ 'window.getSelection().getRangeAt(0).collapse(true)',
+ 'window.getSelection().getRangeAt(0).surroundContents(document.createElement("span"))',
+ 'window.getSelection().getRangeAt(0).setStart(document,0)',
+ 'window.getSelection().getRangeAt(0).detach()',
+ 'window.getSelection().getRangeAt(0).extractContents()',
+ 'window.getSelection().getRangeAt(0).deleteContents()'
+];
+function init_iframe(d) {
+ var pre = d.createElement('pre');
+ pre.appendChild(d.createTextNode('first\nfirst\n'));
+ pre.appendChild(d.createTextNode('second'));
+ d.documentElement.appendChild(pre);
+ var text = pre.firstChild;
+ var sel = d.defaultView.getSelection();
+ var r = d.createRange();
+ r.setStart(text,0)
+ r.setEnd(text,3)
+ sel.addRange(r);
+ d.documentElement.offsetHeight;
+}
+function test_iframe(iframe, i) {
+ iframe.contentDocument.write(
+ '<'+'style>span { text-decoration:underline; } <'+'/style>' +
+ '<'+'script>' +
+ 'window.parent.init_iframe(document);' +
+ 'setTimeout(function(){' + window.parent.tests[i] + '; ++window.parent.tests_done; },0)' +
+ '<'+'/script>'
+ );
+}
+function create_iframe(i) {
+ var div = document.createElement('div');
+ document.body.appendChild(div);
+ div.innerHTML = "<iframe src='about:blank' style='height:6em; width:12em; float:left;' frameborder='0' onload='test_iframe(this,"+i+")'><iframe>"
+}
+
+var id;
+function check_if_done() {
+ if (tests_done == tests.length) {
+ clearInterval(id);
+ document.documentElement.className = "";
+ }
+}
+
+function test() {
+ for (i = 0; i < tests.length; ++i) {
+ create_iframe(i);
+ }
+ id = setInterval(check_if_done,500);
+}
+</script>
+
+</head>
+<body onload="test()"></body>
+</html>
diff --git a/layout/reftests/selection/non-themed-widget-ref.html b/layout/reftests/selection/non-themed-widget-ref.html
new file mode 100644
index 0000000000..08faed7ec3
--- /dev/null
+++ b/layout/reftests/selection/non-themed-widget-ref.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+<style type="text/css">
+input {
+ background-color: Highlight;
+}
+input::-moz-selection {
+ background-color: HighlightText;
+ color: Highlight;
+}
+</style>
+</head>
+<body onload="document.getElementById('i').select();">
+<input id="i" value="text">
+</body>
+</html> \ No newline at end of file
diff --git a/layout/reftests/selection/non-themed-widget.html b/layout/reftests/selection/non-themed-widget.html
new file mode 100644
index 0000000000..7b8708fc1e
--- /dev/null
+++ b/layout/reftests/selection/non-themed-widget.html
@@ -0,0 +1,12 @@
+<html>
+<head>
+<style type="text/css">
+input {
+ background-color: Highlight;
+}
+</style>
+</head>
+<body onload="document.getElementById('i').select();">
+<input id="i" value="text">
+</body>
+</html> \ No newline at end of file
diff --git a/layout/reftests/selection/pseudo-element-of-native-anonymous-ref.html b/layout/reftests/selection/pseudo-element-of-native-anonymous-ref.html
new file mode 100644
index 0000000000..dbcfef7cfc
--- /dev/null
+++ b/layout/reftests/selection/pseudo-element-of-native-anonymous-ref.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<style type="text/css">
+input {
+ color: white;
+ background-color: green;
+}
+</style>
+</head>
+<body onload="document.getElementById('i').select();">
+<input value="text" id="i">
+</body>
+</html> \ No newline at end of file
diff --git a/layout/reftests/selection/pseudo-element-of-native-anonymous.html b/layout/reftests/selection/pseudo-element-of-native-anonymous.html
new file mode 100644
index 0000000000..9193f1c27c
--- /dev/null
+++ b/layout/reftests/selection/pseudo-element-of-native-anonymous.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+<style type="text/css">
+input {
+ color: white;
+ background-color: green;
+}
+input::-moz-selection {
+ color: red;
+ background-color: blue;
+}
+</style>
+</head>
+<body onload="document.getElementById('i').select();">
+<input value="text" id="i">
+</body>
+</html> \ No newline at end of file
diff --git a/layout/reftests/selection/reftest.list b/layout/reftests/selection/reftest.list
new file mode 100644
index 0000000000..a7d9ba1739
--- /dev/null
+++ b/layout/reftests/selection/reftest.list
@@ -0,0 +1,60 @@
+fuzzy(0-1,0-30) == dynamic-text-1a.html dynamic-text-1-ref.html
+fuzzy(0-1,0-40) == dynamic-text-1b.html dynamic-text-1-ref.html
+!= extend-1-sanity.html extend-1-ref.html
+fuzzy(0-1,0-1000) == extend-1a.html extend-1-ref.html
+fuzzy(0-1,0-10) == extend-1b.html extend-1-ref.html
+fuzzy(0-1,0-1000) == extend-1c.html extend-1-ref.html
+fuzzy(0-1,0-1000) == extend-1d.html extend-1-ref.html
+fuzzy(0-1,0-1000) == extend-1e.html extend-1-ref.html
+fuzzy(0-1,0-1000) == extend-1f.html extend-1-ref.html
+fuzzy(0-1,0-1000) == extend-1g.html extend-1-ref.html
+fuzzy(0-1,0-1000) == extend-1h.html extend-1-ref.html
+fuzzy(0-1,0-10) == extend-1i.html extend-1-ref.html
+== extend-2a.html extend-2-ref.html
+== extend-2b.html extend-2-ref.html
+!= extend-3-sanity.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3a.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3b.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3c.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3d.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3e.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3f.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3g.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3h.html extend-3-ref.html
+fuzzy(0-1,0-700) == extend-3i.html extend-3-ref.html
+== extend-4a.html extend-4-ref.html
+== extend-4b.html extend-4-ref.html
+# these 3 random-if(Android) are a difference of Native & Xul, see bug 739714
+random-if(Android) needs-focus != pseudo-element-of-native-anonymous.html pseudo-element-of-native-anonymous-ref.html # bug 676641
+# These tests uses Highlight and HighlightText color keywords, they are not same as text selection color on Mac.
+random-if(Android) fails-if(cocoaWidget) needs-focus == non-themed-widget.html non-themed-widget-ref.html
+random-if(Android) needs-focus == themed-widget.html themed-widget-ref.html
+== addrange-1.html addrange-ref.html
+fuzzy(0-1,0-1200) == addrange-2.html addrange-ref.html
+== splitText-normalize.html splitText-normalize-ref.html
+== modify-range.html modify-range-ref.html
+== dom-mutations.html dom-mutations-ref.html
+fuzzy-if(!OSX,0-1,0-2138) == trailing-space-1.html trailing-space-1-ref.html
+!= invalidation-1-ref.html invalidation-2-ref.html
+== invalidation-1a.html invalidation-1-ref.html
+== invalidation-1b.html invalidation-1-ref.html
+== invalidation-1c.html invalidation-1-ref.html
+== invalidation-1d.html invalidation-1-ref.html
+== invalidation-1e.html invalidation-1-ref.html
+== invalidation-1f.html invalidation-1-ref.html
+== invalidation-2a.html invalidation-2-ref.html
+== invalidation-2b.html invalidation-2-ref.html
+== invalidation-2c.html invalidation-2-ref.html
+== invalidation-2d.html invalidation-2-ref.html
+== invalidation-2e.html invalidation-2-ref.html
+== invalidation-2f.html invalidation-2-ref.html
+fuzzy(0-7,0-4) needs-focus == rtl-selection-with-decoration.html rtl-selection-with-decoration-ref.html
+needs-focus == semitransparent-decoration-line.html semitransparent-decoration-line-ref.html
+fuzzy-if(OSX,0-1,0-6) fuzzy-if(Android,0-188,0-39) needs-focus == writing-mode.html writing-mode-ref.html
+needs-focus fuzzy(0-5,0-1) == 1478604.html 1478604-ref.html # !webrender: Seems like an antialiasing+invalidation issue.
+
+needs-focus fuzzy(0-3,0-13) == disabled-1.html disabled-1-ref.html
+needs-focus != disabled-2.html disabled-2-notref.html
+
+== shadow-tree-order-1.html shadow-tree-order-1-ref.html
+!= shadow-tree-order-1.html shadow-tree-order-1-notref.html
diff --git a/layout/reftests/selection/rtl-selection-with-decoration-ref.html b/layout/reftests/selection/rtl-selection-with-decoration-ref.html
new file mode 100644
index 0000000000..6e057bf95a
--- /dev/null
+++ b/layout/reftests/selection/rtl-selection-with-decoration-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>rtl-selection-with-decoration-ref</title>
+ <style>
+ p {
+ font-size: 2em;
+ text-decoration-color: rgba(0, 0, 0, 0.3);
+ text-decoration-skip-ink: none;
+ }
+ #text1 {
+ text-decoration-line: line-through underline;
+ }
+ #text2 {
+ text-decoration-line: line-through overline;
+ }
+ </style>
+ </head>
+ <body>
+ <p id="text1" lang="he">זוהי עובדה הקורא שדעתו מבוססת של תהיה</p>
+ <p id="text2" lang="he" dir="rtl">זוהי עובדה הקורא שדעתו מבוססת של תהיה</p>
+ </body>
+</html>
diff --git a/layout/reftests/selection/rtl-selection-with-decoration.html b/layout/reftests/selection/rtl-selection-with-decoration.html
new file mode 100644
index 0000000000..942f50530b
--- /dev/null
+++ b/layout/reftests/selection/rtl-selection-with-decoration.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>rtl-selection-with-decoration</title>
+ <style>
+ p {
+ font-size: 2em;
+ text-decoration-color: rgba(0, 0, 0, 0.3);
+ text-decoration-skip-ink: none;
+ }
+ #text1 {
+ text-decoration-line: line-through underline;
+ }
+ #text2 {
+ text-decoration-line: line-through overline;
+ }
+ ::-moz-selection {
+ background-color: white;
+ color: black;
+ }
+ </style>
+ <script type="text/javascript" charset="utf-8">
+ function select() {
+ window.getSelection().removeAllRanges();
+ var elems = document.getElementsByTagName('p');
+ for (var i = 0; i < elems.length; ++i) {
+ var range = document.createRange();
+ range.setStart(elems[i].firstChild, 2);
+ range.setEnd(elems[i].firstChild, 9);
+ window.getSelection().addRange(range);
+ }
+ }
+ </script>
+ </head>
+ <body onload="select()">
+ <p id="text1" lang="he">זוהי עובדה הקורא שדעתו מבוססת של תהיה</p>
+ <p id="text2" lang="he" dir="rtl">זוהי עובדה הקורא שדעתו מבוססת של תהיה</p>
+ </body>
+</html>
diff --git a/layout/reftests/selection/semitransparent-decoration-line-ref.html b/layout/reftests/selection/semitransparent-decoration-line-ref.html
new file mode 100644
index 0000000000..75163e97fc
--- /dev/null
+++ b/layout/reftests/selection/semitransparent-decoration-line-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>semitransparent-decoration-line-ref</title>
+ <style>
+ *{
+ text-decoration-skip-ink: none;
+ }
+ .underline {
+ text-decoration: underline rgba(0,0,0,0.3);
+ font-size: 2em;
+ }
+ .overline {
+ text-decoration: overline rgba(0,0,0,0.3);
+ font-size: 2em;
+ }
+ .line-through {
+ text-decoration: line-through rgba(0,0,0,0.3);
+ font-size: 2em;
+ }
+ </style>
+ </head>
+ <body>
+ <p class="underline">Lorem ipsum dolor sit amet</p>
+ <p class="overline">Lorem ipsum dolor sit amet</p>
+ <p class="line-through">Lorem ipsum dolor sit amet</p>
+ </body>
+</html>
diff --git a/layout/reftests/selection/semitransparent-decoration-line.html b/layout/reftests/selection/semitransparent-decoration-line.html
new file mode 100644
index 0000000000..bdddf67931
--- /dev/null
+++ b/layout/reftests/selection/semitransparent-decoration-line.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>semitransparent-decoration-line</title>
+ <style>
+ * {
+ text-decoration-skip-ink: none;
+ }
+ .underline {
+ text-decoration: underline rgba(0,0,0,0.3);
+ font-size: 2em;
+ }
+ .overline {
+ text-decoration: overline rgba(0,0,0,0.3);
+ font-size: 2em;
+ }
+ .line-through {
+ text-decoration: line-through rgba(0,0,0,0.3);
+ font-size: 2em;
+ }
+ ::-moz-selection {
+ background-color: white;
+ color: black;
+ }
+ </style>
+ <script type="text/javascript" charset="utf-8">
+ function select() {
+ window.getSelection().removeAllRanges();
+ var elems = document.getElementsByTagName('p');
+ for (var i = 0; i < elems.length; ++i) {
+ var range = document.createRange();
+ range.setStart(elems[i].firstChild, 2);
+ range.setEnd(elems[i].firstChild, 9);
+ window.getSelection().addRange(range);
+ }
+ }
+ </script>
+ </head>
+ <body onload="select()">
+ <p class="underline">Lorem ipsum dolor sit amet</p>
+ <p class="overline">Lorem ipsum dolor sit amet</p>
+ <p class="line-through">Lorem ipsum dolor sit amet</p>
+ </body>
+</html>
diff --git a/layout/reftests/selection/shadow-tree-order-1-notref.html b/layout/reftests/selection/shadow-tree-order-1-notref.html
new file mode 100644
index 0000000000..35258d862f
--- /dev/null
+++ b/layout/reftests/selection/shadow-tree-order-1-notref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<p>Something to <span>find</span> above</p>
+<p>Something to <span>find</span> in the shadow</p>
+<p>Something to <span>find</span> below</p>
diff --git a/layout/reftests/selection/shadow-tree-order-1-ref.html b/layout/reftests/selection/shadow-tree-order-1-ref.html
new file mode 100644
index 0000000000..4651a2c6fd
--- /dev/null
+++ b/layout/reftests/selection/shadow-tree-order-1-ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<p>Something to <span>find</span> above</p>
+<p>Something to <span>find</span> in the shadow</p>
+<p>Something to <span>find</span> below</p>
+<script>
+ let selection = getSelection();
+ selection.removeAllRanges();
+ for (let span of document.querySelectorAll("span")) {
+ let range = document.createRange();
+ range.selectNode(span);
+ selection.addRange(range);
+ }
+</script>
diff --git a/layout/reftests/selection/shadow-tree-order-1.html b/layout/reftests/selection/shadow-tree-order-1.html
new file mode 100644
index 0000000000..916fa6ab5f
--- /dev/null
+++ b/layout/reftests/selection/shadow-tree-order-1.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<p id="above">Something to <span>find</span> above</p>
+<p id="host"></p>
+<p id="below">Something to <span>find</span> below</p>
+<script>
+ document.getElementById("host").attachShadow({ mode: "open" }).innerHTML = `
+ Something to <span>find</span> in the shadow
+ `.trim();
+ let selection = getSelection();
+ selection.removeAllRanges();
+ for (let id of ["above", "host", "below"]) {
+ let element = document.getElementById(id);
+ let span = (element.shadowRoot || element).querySelector("span");
+ let range = document.createRange();
+ range.selectNode(span);
+ selection.addRange(range);
+ }
+</script>
diff --git a/layout/reftests/selection/splitText-normalize-ref.html b/layout/reftests/selection/splitText-normalize-ref.html
new file mode 100644
index 0000000000..7af1d34d47
--- /dev/null
+++ b/layout/reftests/selection/splitText-normalize-ref.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=191864
+-->
+<head>
+ <title>Test for Bug 191864</title>
+ <script type="application/javascript" src="splitText-normalize.js"></script>
+<script type="application/javascript">
+var id;
+function checkFinished() {
+ if (window.frames.length == tests_done) {
+ clearInterval(id);
+ document.documentElement.className = "";
+ }
+}
+
+function runTest() {
+ let col1 = document.getElementById('col1');
+ let col2 = document.getElementById('col2');
+ let col3 = document.getElementById('col3');
+ let col4 = document.getElementById('col4');
+ for (let i=0; i < tests.length; ++i) {
+ let t = tests[i];
+ col1.appendChild(createFrame(test_ref,t));
+ col2.appendChild(createFrame(test_ref,t));
+ col3.appendChild(createFrame(test_ref,t));
+ col4.appendChild(createFrame(test_ref,t));
+ }
+ id = setInterval(checkFinished,500);
+}
+</script>
+</head>
+<body onload="runTest()">
+<span id="col1" style="float:left; height:800px; width:180px;"></span>
+<span id="col2" style="float:left; height:800px; width:180px;"></span>
+<span id="col3" style="float:left; height:800px; width:180px;"></span>
+<span id="col4" style="float:left; height:800px; width:180px;"></span>
+</body>
+</html>
diff --git a/layout/reftests/selection/splitText-normalize.html b/layout/reftests/selection/splitText-normalize.html
new file mode 100644
index 0000000000..5a7ed98869
--- /dev/null
+++ b/layout/reftests/selection/splitText-normalize.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=191864
+-->
+<head>
+ <title>Test for Bug 191864</title>
+ <script type="application/javascript" src="splitText-normalize.js"></script>
+<script type="application/javascript">
+var id;
+function checkFinished() {
+ if (window.frames.length == tests_done) {
+ clearInterval(id);
+ document.documentElement.className = "";
+ }
+}
+
+function runTest() {
+ let col1 = document.getElementById('col1');
+ let col2 = document.getElementById('col2');
+ let col3 = document.getElementById('col3');
+ let col4 = document.getElementById('col4');
+ for (let i=0; i < tests.length; ++i) {
+ let t = tests[i];
+ col1.appendChild(createFrame(test_split,t));
+ col2.appendChild(createFrame(test_split_merge,t));
+ col3.appendChild(createFrame(test_merge,t));
+ col4.appendChild(createFrame(test_split_insert,t));
+ }
+ id = setInterval(checkFinished,500);
+}
+</script>
+</head>
+<body onload="runTest()">
+<span id="col1" style="float:left; height:800px; width:180px;"></span>
+<span id="col2" style="float:left; height:800px; width:180px;"></span>
+<span id="col3" style="float:left; height:800px; width:180px;"></span>
+<span id="col4" style="float:left; height:800px; width:180px;"></span>
+</body>
+</html>
diff --git a/layout/reftests/selection/splitText-normalize.js b/layout/reftests/selection/splitText-normalize.js
new file mode 100644
index 0000000000..ae3dd312fa
--- /dev/null
+++ b/layout/reftests/selection/splitText-normalize.js
@@ -0,0 +1,86 @@
+/** Test for Bug 191864 **/
+var tests_done = 0;
+var tests = [
+ [ {}, [0,4], "012345678" ],
+ [ {}, [0,0], "012345678" ],
+ [ {}, [0,9], "012345678" ],
+ [ {startOffset:4}, [0,4], "012345678" ],
+ [ {startOffset:5}, [0,4], "012345678" ],
+ [ {startOffset:5,endOffset:6}, [0,4], "012345678" ],
+ [ {endOffset:5}, [0,4], "012345678" ],
+ [ {endOffset:4}, [0,4], "012345678" ],
+ [ {endOffset:3}, [0,4], "012345678" ],
+ [ {startOffset:1,endOffset:3}, [0,4], "012345678" ],
+ [ {startOffset:7,endOffset:7}, [0,4], "012345678" ],
+ [ {startOffset:4,endOffset:4}, [0,4], "012345678" ],
+ [ {endNode:1}, [0,4], "012345678", "" ],
+ [ {endNode:1}, [0,4], "01234567", "8" ],
+ [ {endNode:1}, [1,4], "0", "12345678" ],
+ [ {startOffset:1,endNode:1}, [0,0], "0", "12345678" ],
+ [ {endNode:2}, [1,4], "0", "12345", "678" ],
+]
+
+function runtest(f,t,nosplit) {
+ // create content
+ let doc = f.contentDocument;
+ for (let i = 2; i < t.length; ++i) {
+ c = doc.createTextNode(t[i]);
+ doc.body.appendChild(c);
+ }
+
+ // setup selection
+ let sel = t[0]
+ let startNode = sel.startNode === undefined ? doc.body.firstChild : doc.body.childNodes[sel.startNode];
+ let startOffset = sel.startOffset === undefined ? 0 : sel.startOffset;
+ let endNode = sel.endNode === undefined ? startNode : doc.body.childNodes[sel.endNode];
+ let endOffset = sel.endOffset === undefined ? endNode.length : sel.endOffset;
+ let selection = f.contentWindow.getSelection();
+ let r = doc.createRange();
+ r.setStart(startNode, startOffset);
+ r.setEnd(endNode, endOffset);
+ selection.addRange(r);
+
+ // splitText
+ let split = t[1]
+ if (!nosplit)
+ doc.body.childNodes[split[0]].splitText(split[1])
+}
+function test_ref(f,t,nosplit) {
+ runtest(f,t,true);
+}
+function test_split(f,t) {
+ runtest(f,t);
+}
+function test_split_insert(f,t) {
+ runtest(f,t);
+ let doc = f.contentDocument;
+ doc.body.firstChild;
+ let split = t[1]
+ let text1 = doc.body.childNodes[split[0]]
+ let text2 = doc.body.childNodes[split[0]+1]
+ if (text2.textContent.length==0) return;
+ let c = doc.createTextNode(text2.textContent[0]);
+ doc.body.insertBefore(c,text2);
+ let r = doc.createRange();
+ r.setStart(text2, 0);
+ r.setEnd(text2, 1);
+ r.deleteContents();
+}
+function test_split_merge(f,t) {
+ runtest(f,t);
+ f.contentDocument.body.normalize();
+}
+function test_merge(f,t) {
+ runtest(f,t,true);
+ f.contentDocument.body.normalize();
+}
+
+function createFrame(run,t) {
+ let f = document.createElement('iframe');
+ f.setAttribute('height','22');
+ f.setAttribute('frameborder','0');
+ f.setAttribute('width','200');
+ f.src = 'data:text/html,<body style="margin:0;padding:0">';
+ f.onload = function () { try { run(f, t); } finally { ++tests_done; } }
+ return f;
+}
diff --git a/layout/reftests/selection/themed-widget-ref.html b/layout/reftests/selection/themed-widget-ref.html
new file mode 100644
index 0000000000..1a932c3037
--- /dev/null
+++ b/layout/reftests/selection/themed-widget-ref.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<style type="text/css">
+input::-moz-selection {
+ background-color: Highlight;
+ color: HighlightText;
+}
+</style>
+</head>
+<body onload="document.getElementById('i').select();">
+<input id="i" value="text">
+</body>
+</html> \ No newline at end of file
diff --git a/layout/reftests/selection/themed-widget.html b/layout/reftests/selection/themed-widget.html
new file mode 100644
index 0000000000..6d94f5584b
--- /dev/null
+++ b/layout/reftests/selection/themed-widget.html
@@ -0,0 +1,5 @@
+<html>
+<body onload="document.getElementById('i').select();">
+<input id="i" value="text">
+</body>
+</html> \ No newline at end of file
diff --git a/layout/reftests/selection/trailing-space-1-ref.html b/layout/reftests/selection/trailing-space-1-ref.html
new file mode 100644
index 0000000000..bb33604a72
--- /dev/null
+++ b/layout/reftests/selection/trailing-space-1-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>Test for bug 1146754</title>
+ <script>
+ function selectTest() {
+ window.getSelection().removeAllRanges();
+ var range = document.createRange();
+ range.selectNode(document.querySelector('#test'));
+ window.getSelection().addRange(range);
+ }
+ </script>
+ <style>
+ body { padding: 1em; }
+ div>div { height: 2em; }
+ </style>
+ </head>
+ <body onload="selectTest()" contenteditable>
+ <div id="test">
+ <div>123 <span style="color:transparent;font-size:0">x</span></div>
+ <div style="text-shadow:8px 3px 0 red;">456 <span style="color:transparent;font-size:0">x</span></div>
+ <div><u>789</u> <span style="color:transparent;font-size:0">x</span></div>
+ <div style="text-shadow:-4px 3px 0 red;"><u>012</u> <span style="color:transparent;font-size:0">x</span></div>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/selection/trailing-space-1.html b/layout/reftests/selection/trailing-space-1.html
new file mode 100644
index 0000000000..487cd726e7
--- /dev/null
+++ b/layout/reftests/selection/trailing-space-1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>Test for bug 1146754</title>
+ <script>
+ function selectTest() {
+ window.getSelection().removeAllRanges();
+ var range = document.createRange();
+ range.selectNode(document.querySelector('#test'));
+ window.getSelection().addRange(range);
+ }
+ </script>
+ <style>
+ body { padding: 1em; }
+ div>div { height: 2em; }
+ </style>
+ </head>
+ <body onload="selectTest()" contenteditable>
+ <div id="test">
+ <div>123 </div>
+ <div style="text-shadow:8px 3px 0 red;">456 </div>
+ <div style="text-decoration:underline">789 </div>
+ <div style="text-decoration:underline; text-shadow:-4px 3px 0 red;">012 </div>
+ </div>
+ </body>
+</html>
diff --git a/layout/reftests/selection/writing-mode-ref.html b/layout/reftests/selection/writing-mode-ref.html
new file mode 100644
index 0000000000..3619c1811f
--- /dev/null
+++ b/layout/reftests/selection/writing-mode-ref.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>writing-mode-ref</title>
+ <style>
+ p {
+ display: inline-block;
+ margin: 10px;
+ }
+ .line-through {
+ text-decoration: line-through wavy rgba(0, 0, 0, 0.3);
+ }
+ .wm-vertical-lr {
+ writing-mode: vertical-lr;
+ }
+ .wm-vertical-rl {
+ writing-mode: vertical-rl;
+ }
+ .wm-sideways-lr {
+ writing-mode: sideways-lr;
+ }
+ .wm-sideways-rl {
+ writing-mode: sideways-rl;
+ }
+ </style>
+ </head>
+ <body>
+ <p lang="zh" dir="ltr" class="wm-vertical-lr line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="ltr" class="wm-vertical-rl line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="ltr" class="wm-sideways-lr line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="ltr" class="wm-sideways-rl line-through">你好世界!Hello World!</p>
+ <br/>
+ <p lang="zh" dir="rtl" class="wm-vertical-lr line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="rtl" class="wm-vertical-rl line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="rtl" class="wm-sideways-lr line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="rtl" class="wm-sideways-rl line-through">你好世界!Hello World!</p>
+ </body>
+</html>
diff --git a/layout/reftests/selection/writing-mode.html b/layout/reftests/selection/writing-mode.html
new file mode 100644
index 0000000000..e74728c589
--- /dev/null
+++ b/layout/reftests/selection/writing-mode.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>writing-mode</title>
+ <style>
+ p {
+ display: inline-block;
+ margin: 10px;
+ }
+ .line-through {
+ text-decoration: line-through wavy rgba(0, 0, 0, 0.3);
+ }
+ ::-moz-selection {
+ background-color: white;
+ color: black;
+ }
+ .wm-vertical-lr {
+ writing-mode: vertical-lr;
+ display: inline-block;
+ }
+ .wm-vertical-rl {
+ writing-mode: vertical-rl;
+ }
+ .wm-sideways-lr {
+ writing-mode: sideways-lr;
+ }
+ .wm-sideways-rl {
+ writing-mode: sideways-rl;
+ }
+ </style>
+ <script type="text/javascript" charset="utf-8">
+ function select() {
+ window.getSelection().removeAllRanges();
+ var elems = document.getElementsByTagName('p');
+ for (var i = 0; i < elems.length; ++i) {
+ var range = document.createRange();
+ range.setStart(elems[i].firstChild, 2);
+ range.setEnd(elems[i].firstChild, 9);
+ window.getSelection().addRange(range);
+ }
+ }
+ </script>
+ </head>
+ <body onload="select()">
+ <p lang="zh" dir="ltr" class="wm-vertical-lr line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="ltr" class="wm-vertical-rl line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="ltr" class="wm-sideways-lr line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="ltr" class="wm-sideways-rl line-through">你好世界!Hello World!</p>
+ <br/>
+ <p lang="zh" dir="rtl" class="wm-vertical-lr line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="rtl" class="wm-vertical-rl line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="rtl" class="wm-sideways-lr line-through">你好世界!Hello World!</p>
+ <p lang="zh" dir="rtl" class="wm-sideways-rl line-through">你好世界!Hello World!</p>
+ </body>
+</html>