Bug 1368521 Selection::SelectFrames() shouldn't skip first content invalidation if it's different from handled text node r?mats draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 31 May 2017 15:57:53 +0900
changeset 587037 e85da080583ef7fa858949ff5f3cb472afa8b1a7
parent 586849 925230851743b9a969a3142f00aea5014a33cb02
child 588190 e055dbaa81b8e58e627c883ab3999191a878769b
child 588191 ba07335f2d4fe9835441a54276cb4a3d81030cb1
push id61602
push usermasayuki@d-toybox.com
push dateWed, 31 May 2017 13:01:11 +0000
reviewersmats
bugs1368521
milestone55.0a1
Bug 1368521 Selection::SelectFrames() shouldn't skip first content invalidation if it's different from handled text node r?mats The first node of |iter| in Selection::SelectFrames() may be different from the start parent of given range. Therefore, if they are different, it shouldn't skip first item of |iter|. MozReview-Commit-ID: DgE2dSziaxo
layout/generic/nsSelection.cpp
layout/reftests/selection/invalidation-1-ref.html
layout/reftests/selection/invalidation-1a.html
layout/reftests/selection/invalidation-1b.html
layout/reftests/selection/invalidation-1c.html
layout/reftests/selection/invalidation-1d.html
layout/reftests/selection/invalidation-1e.html
layout/reftests/selection/invalidation-1f.html
layout/reftests/selection/invalidation-2-ref.html
layout/reftests/selection/invalidation-2a.html
layout/reftests/selection/invalidation-2b.html
layout/reftests/selection/invalidation-2c.html
layout/reftests/selection/invalidation-2d.html
layout/reftests/selection/invalidation-2e.html
layout/reftests/selection/invalidation-2f.html
layout/reftests/selection/reftest.list
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -4577,17 +4577,18 @@ Selection::SelectFrames(nsPresContext* a
     if (!isFirstContentTextNode) {
       SelectFramesForContent(startContent, aSelect);
     }
     return NS_OK;
   }
 
   nsCOMPtr<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
   iter->Init(aRange);
-  if (isFirstContentTextNode && !iter->IsDone()) {
+  if (isFirstContentTextNode && !iter->IsDone() &&
+      iter->GetCurrentNode() == startNode) {
     iter->Next(); // first content has already been handled.
   }
   nsCOMPtr<nsIContentIterator> inneriter = NS_NewContentIterator();
   for (; !iter->IsDone(); iter->Next()) {
     nsINode* node = iter->GetCurrentNode();
     MOZ_ASSERT(node);
     nsIContent* content = node->IsContent() ? node->AsContent() : nullptr;
     SelectAllFramesForContent(inneriter, content, aSelect);
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
new file mode 100644
--- /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>
--- a/layout/reftests/selection/reftest.list
+++ b/layout/reftests/selection/reftest.list
@@ -30,8 +30,21 @@ random-if(Android) needs-focus != pseudo
 random-if(Android) fails-if(cocoaWidget) needs-focus == non-themed-widget.html non-themed-widget-ref.html
 random-if(Android) fails-if(cocoaWidget) needs-focus == themed-widget.html themed-widget-ref.html
 == addrange-1.html addrange-ref.html
 fuzzy-if(skiaContent,1,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==1010,9,1) fuzzy-if(OSX&&skiaContent,6,1) fuzzy-if(skiaContent&&!OSX,1,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