tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

scroll-behavior-smooth-positions.html (8484B)


      1 <!DOCTYPE html>
      2 <title>Testing scroll positions when scrolling an element with smooth behavior</title>
      3 <meta name="timeout" content="long"/>
      4 <link rel="author" title="Frédéric Wang" href="mailto:fwang@igalia.com">
      5 <link rel="help" href="https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior">
      6 <link rel="help" href="https://drafts.csswg.org/cssom-view/#scrolling-box">
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 <script src="/dom/events/scrolling/scroll_support.js"></script>
     10 <script src="support/scroll-behavior.js"></script>
     11 <style>
     12  .scrollable {
     13    overflow: auto;
     14    width: 400px;
     15    height: 200px;
     16    scroll-behavior: smooth;
     17  }
     18 </style>
     19 <div id="log">
     20 </div>
     21 <div id="overflowNode" class="scrollable">
     22  <div style="width: 2000px; height: 1000px; background: linear-gradient(135deg, red, green);">
     23    <span style="display: inline-block; width: 500px; height: 250px;"></span><span id="elementToReveal" style="display: inline-block; vertical-align: -15px; width: 10px; height: 15px; background: black;"></span>
     24  </div>
     25 </div>
     26 <script>
     27  promise_test(async () => {
     28    await waitForCompositorReady();
     29  }, "Make sure the page is ready for animation.");
     30 
     31  // For smooth behavior, evolution of scroll positions over time is not specified by CSSOM View.
     32  // This test relies on the minimal assumption that scroll position functions are monotonic.
     33  ["scroll", "scrollTo", "scrollBy", "scrollIntoView"].forEach(function(scrollFunction) {
     34    [{left:0, top:0}, {left:1000, top:0}, {left:0, top:500}, {left:1000, top:500}].forEach((initial) => {
     35      var finalLeft = 500;
     36      var finalTop = 250;
     37      promise_test(() => {
     38        return new Promise(function(resolve, reject) {
     39          scrollNode(overflowNode, "scroll", "instant", initial.left, initial.top);
     40          var oldLeft = overflowNode.scrollLeft;
     41          var oldTop = overflowNode.scrollTop;
     42          assert_equals(oldLeft, initial.left, "ScrollLeft should be at initial position");
     43          assert_equals(oldTop, initial.top, "ScrollTop should be at initial position");
     44          if (scrollFunction === "scrollBy")
     45            scrollNode(overflowNode, scrollFunction, "smooth", finalLeft - initial.left, finalTop - initial.top);
     46          else
     47            scrollNode(overflowNode, scrollFunction, "smooth", finalLeft, finalTop);
     48          observeScrolling(overflowNode, function(done) {
     49            try {
     50              var newLeft = overflowNode.scrollLeft;
     51              var newTop = overflowNode.scrollTop;
     52              assert_less_than_equal(Math.hypot(finalLeft - newLeft, finalTop - newTop), Math.hypot(finalLeft - oldLeft, finalTop - oldTop), "Scroll position should move towards the final position");
     53              if (done) {
     54                assert_equals(newLeft, finalLeft, "ScrollLeft should reach final position");
     55                assert_equals(newTop, finalTop, "ScrollTop should reach final position");
     56              }
     57              oldLeft = newLeft;
     58              oldTop = newTop;
     59            } catch(e) {
     60              reject(e);
     61            }
     62            if (done)
     63              resolve();
     64          });
     65        });
     66      }, `Scroll positions when performing smooth scrolling from (${initial.left}, ${initial.top}) to (${finalLeft}, ${finalTop}) using ${scrollFunction}() `);
     67    });
     68  });
     69 
     70  [{scrollAttribute: "scrollLeft", scrollValue: 500}, {scrollAttribute: "scrollTop", scrollValue: 250}].forEach(function(scrollTest) {
     71    var initialPosition = Number(scrollTest.scrollValue) * 2;
     72    [0, initialPosition].forEach((initial) => {
     73      promise_test(() => {
     74        return new Promise(function(resolve, reject) {
     75          scrollNode(overflowNode, "scroll", "instant", initial, initial);
     76          var oldValue = overflowNode[scrollTest.scrollAttribute];
     77          assert_equals(oldValue, initial, `${scrollTest.scrollAttribute} should be at initial position`);
     78          var expectedValue = Number(scrollTest.scrollValue);
     79          overflowNode[scrollTest.scrollAttribute] = expectedValue;
     80          observeScrolling(overflowNode, function(done) {
     81            try {
     82              var newValue = overflowNode[scrollTest.scrollAttribute];
     83              assert_less_than_equal(Math.abs(expectedValue - newValue), Math.abs(expectedValue - oldValue), "Scroll position should move towards the final position");
     84              if (done)
     85                assert_equals(newValue, expectedValue, `${scrollTest.scrollAttribute} should reach final position`);
     86              oldValue = newValue;
     87            } catch(e) {
     88              reject(e);
     89            }
     90            if (done)
     91              resolve();
     92          });
     93        });
     94      }, `Scroll positions when performing smooth scrolling from ${initial} to ${scrollTest.scrollValue} by setting ${scrollTest.scrollAttribute} `);
     95    });
     96  });
     97 
     98  promise_test(() => {
     99    return new Promise(function(resolve, reject) {
    100      resetScroll(overflowNode);
    101      var initialScrollAborted = false;
    102      var scrollDirectionChanged = false;
    103      var oldLeft = overflowNode.scrollLeft;
    104      var oldTop = overflowNode.scrollTop;
    105      assert_equals(oldLeft, 0);
    106      assert_equals(oldTop, 0);
    107      scrollNode(overflowNode, "scroll", "smooth", 1500, 750);
    108      observeScrolling(overflowNode, function(done) {
    109        try {
    110          var newLeft = overflowNode.scrollLeft;
    111          var newTop = overflowNode.scrollTop;
    112          if (initialScrollAborted) {
    113            if (scrollDirectionChanged) {
    114              assert_greater_than_equal(oldLeft, newLeft, "ScrollLeft keeps decreasing");
    115              assert_greater_than_equal(oldTop, newTop, "ScrollTop keeps decreasing");
    116            } else
    117              scrollDirectionChanged = newLeft <= oldLeft && newTop <= oldTop;
    118          } else {
    119              assert_less_than_equal(oldLeft, newLeft, "ScrollLeft keeps increasing");
    120              assert_less_than_equal(oldTop, newTop, "ScrollTop keeps increasing");
    121              if (newLeft > 1000 && newTop > 500) {
    122                // Abort the initial scroll.
    123                initialScrollAborted = true;
    124                scrollNode(overflowNode, "scroll", "smooth", 500, 250);
    125                newLeft = overflowNode.scrollLeft;
    126                newTop = overflowNode.scrollTop;
    127              }
    128          }
    129          if (done) {
    130            assert_equals(newLeft, 500, "ScrollLeft should reach final position");
    131            assert_equals(newTop, 250, "ScrollTop should reach final position");
    132          }
    133          oldLeft = newLeft;
    134          oldTop = newTop;
    135        } catch(e) {
    136          reject(e);
    137        }
    138        if (done)
    139          resolve();
    140      });
    141    });
    142  }, "Scroll positions when aborting a smooth scrolling with another smooth scrolling");
    143 
    144  promise_test(() => {
    145    return new Promise(function(resolve, reject) {
    146      resetScroll(overflowNode);
    147      var initialScrollAborted = false;
    148      var oldLeft = overflowNode.scrollLeft;
    149      var oldTop = overflowNode.scrollTop;
    150      assert_equals(oldLeft, 0);
    151      assert_equals(oldTop, 0);
    152      scrollNode(overflowNode, "scroll", "smooth", 1500, 750);
    153      observeScrolling(overflowNode, function(done) {
    154        try {
    155          var newLeft = overflowNode.scrollLeft;
    156          var newTop = overflowNode.scrollTop;
    157          if (!initialScrollAborted) {
    158              assert_less_than_equal(oldLeft, newLeft, "ScrollLeft keeps increasing");
    159              assert_less_than_equal(oldTop, newTop, "ScrollTop keeps increasing");
    160              if (newLeft > 1000 && newTop > 500) {
    161                // Abort the initial scroll.
    162                initialScrollAborted = true;
    163                scrollNode(overflowNode, "scroll", "instant", 500, 250);
    164                newLeft = overflowNode.scrollLeft;
    165                newTop = overflowNode.scrollTop;
    166                assert_equals(newLeft, 500, "ScrollLeft should reach final position");
    167                assert_equals(newTop, 250, "ScrollTop should reach final position");
    168              }
    169          }
    170          if (done) {
    171            assert_equals(newLeft, 500, "ScrollLeft should stay at final position");
    172            assert_equals(newTop, 250, "ScrollTop should stay at final position");
    173          }
    174          oldLeft = newLeft;
    175          oldTop = newTop;
    176        } catch(e) {
    177          reject(e);
    178        }
    179        if (done)
    180          resolve();
    181      });
    182    });
    183  }, "Scroll positions when aborting a smooth scrolling with an instant scrolling");
    184 </script>