Bug 1546835 - Adjust start position of the target element as scroll offset in the scroll element. r=jfkthame
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Thu, 25 Apr 2019 12:54:11 +0000
changeset 530193 96fc6f317e8430b1666f8bf89846fc2676b9da24
parent 530192 ad09822ed130815c71376f093e9518400ee1faa2
child 530194 f04e1e9c54aaf387c1ee748cd59328bee2bbd687
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1546835
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1546835 - Adjust start position of the target element as scroll offset in the scroll element. r=jfkthame Depends on D28755 Differential Revision: https://phabricator.services.mozilla.com/D28756
layout/generic/nsGfxScrollFrame.cpp
testing/web-platform/tests/css/css-scroll-snap/snap-inline-block.html
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -6605,17 +6605,19 @@ static void AppendScrollPositionsForSnap
 
   const nsStyleDisplay* styleDisplay = aFrame->StyleDisplay();
   nscoord containerBSize = logicalSnapportRect.BSize(aWritingModeOnScroller);
   switch (styleDisplay->mScrollSnapAlign.block) {
     case StyleScrollSnapAlignKeyword::None:
       break;
     case StyleScrollSnapAlignKeyword::Start:
       blockDirectionPosition.emplace(
-          logicalTargetRect.BStart(aWritingModeOnScroller));
+          aWritingModeOnScroller.IsVerticalRL()
+              ? -logicalTargetRect.BStart(aWritingModeOnScroller)
+              : logicalTargetRect.BStart(aWritingModeOnScroller));
       break;
     case StyleScrollSnapAlignKeyword::End:
       if (aWritingModeOnScroller.IsVerticalRL()) {
         blockDirectionPosition.emplace(
             containerBSize - logicalTargetRect.BEnd(aWritingModeOnScroller));
       } else {
         // What we need here is the scroll position instead of the snap position
         // itself, so we need, for example, the top edge of the scroll port
@@ -6643,17 +6645,19 @@ static void AppendScrollPositionsForSnap
   }
 
   nscoord containerISize = logicalSnapportRect.ISize(aWritingModeOnScroller);
   switch (styleDisplay->mScrollSnapAlign.inline_) {
     case StyleScrollSnapAlignKeyword::None:
       break;
     case StyleScrollSnapAlignKeyword::Start:
       inlineDirectionPosition.emplace(
-          logicalTargetRect.IStart(aWritingModeOnScroller));
+          aWritingModeOnScroller.IsInlineReversed()
+              ? -logicalTargetRect.IStart(aWritingModeOnScroller)
+              : logicalTargetRect.IStart(aWritingModeOnScroller));
       break;
     case StyleScrollSnapAlignKeyword::End:
       if (aWritingModeOnScroller.IsInlineReversed()) {
         inlineDirectionPosition.emplace(
             containerISize - logicalTargetRect.IEnd(aWritingModeOnScroller));
       } else {
         // Same as above BEnd case, we subtract containerISize.
         inlineDirectionPosition.emplace(
--- a/testing/web-platform/tests/css/css-scroll-snap/snap-inline-block.html
+++ b/testing/web-platform/tests/css/css-scroll-snap/snap-inline-block.html
@@ -17,17 +17,16 @@ div {
   width: 1000px;
   height: 1000px;
 }
 #target {
   width: 200px;
   height: 200px;
   left: 300px;
   top: 300px;
-  scroll-snap-align: end start;
 }
 </style>
 
 <div id="scroller">
   <div id="space"></div>
   <div id="target"></div>
 </div>
 
@@ -37,19 +36,76 @@ const scroller_height = scroller.clientH
 [
   ["horizontal-tb", 300,                  500 - scroller_height],
   ["vertical-lr",   500 - scroller_width, 300],
   ["vertical-rl",   scroller_width - 700, 300]
 ].forEach(([writing_mode, left, top]) => {
   test(() => {
     const target_left = getComputedStyle(target).left;
     scroller.style.writingMode = writing_mode;
+    target.style.scrollSnapAlign = "end start";
+    if (writing_mode == "vertical-rl") {
+      target.style.left = (scroller_width - 700) + "px";
+    }
+    scroller.scrollTo(0, 0);
+    assert_equals(scroller.scrollLeft, left, "aligns correctly on x");
+    assert_equals(scroller.scrollTop, top, "aligns correctly on y");
+    target.style.left = target_left;
+    scroller.style.writingMode = "";
+  }, "Snaps correctly for " + writing_mode +
+     " writing mode with 'scroll-snap-align: end start' alignment");
+});
+
+[
+  ["horizontal-tb", 500 - scroller_width,     300],
+  ["vertical-lr",   300,                      500 - scroller_height],
+  ["vertical-rl",   target.clientWidth - 700, 500 - scroller_height]
+].forEach(([writing_mode, left, top]) => {
+  test(() => {
+    const target_left = getComputedStyle(target).left;
+    scroller.style.writingMode = writing_mode;
+    target.style.scrollSnapAlign = "start end";
     if (writing_mode == "vertical-rl") {
       target.style.left = (scroller_width - 700) + "px";
     }
     scroller.scrollTo(0, 0);
     assert_equals(scroller.scrollLeft, left, "aligns correctly on x");
     assert_equals(scroller.scrollTop, top, "aligns correctly on y");
     target.style.left = target_left;
+    scroller.style.writingMode = "";
   }, "Snaps correctly for " + writing_mode +
-     " writing mode with 'inline' and 'block' alignments");
-})
+     " writing mode with 'scroll-snap-align: start end' alignment");
+});
+
+test(() => {
+  const target_left = getComputedStyle(target).left;
+  scroller.style.direction = "rtl";
+  target.style.scrollSnapAlign = "end start";
+  target.style.left = (scroller_width - 700) + "px";
+
+  scroller.scrollTo(0, 0);
+  assert_equals(scroller.scrollLeft, target.clientWidth - 700,
+                "aligns correctly on x");
+  assert_equals(scroller.scrollTop, 500 - scroller_height,
+                "aligns correctly on y");
+
+  target.style.left = target_left;
+  scroller.style.direction = "";
+}, "Snaps correctly for 'direction: rtl' with 'scroll-snap-align: end start' " +
+   "alignment");
+
+test(() => {
+  const target_left = getComputedStyle(target).left;
+  scroller.style.direction = "rtl";
+  target.style.scrollSnapAlign = "start end";
+  target.style.left = (scroller_width - 700) + "px";
+
+  scroller.scrollTo(0, 0);
+  assert_equals(scroller.scrollLeft, scroller_width - 700,
+                "aligns correctly on x");
+  assert_equals(scroller.scrollTop, 300, "aligns correctly on y");
+
+  target.style.left = target_left;
+  scroller.style.direction = "";
+}, "Snaps correctly for 'direction: rtl' with 'scroll-snap-align: start end' " +
+   "alignment");
+
 </script>