tor-browser

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

helper_relative_scroll_smoothness.html (5749B)


      1 <!DOCTYPE html>
      2 <html>
      3 <meta charset="utf-8">
      4 <script src="/tests/SimpleTest/EventUtils.js"></script>
      5 <script src="/tests/SimpleTest/NativeKeyCodes.js"></script>
      6 <script src="/tests/SimpleTest/paint_listener.js"></script>
      7 <script src="apz_test_utils.js"></script>
      8 <script src="apz_test_native_event_utils.js"></script>
      9 <title>What happens if main thread scrolls?</title>
     10 <style>
     11 html, body { margin: 0; }
     12 
     13 html {
     14  background:
     15    repeating-linear-gradient(45deg, transparent 0, transparent 100px, rgba(0,0,0,0.1) 0, rgba(0,0,0,0.1) 200px),
     16    repeating-linear-gradient(-45deg, transparent 0, transparent 100px, rgba(0,0,0,0.1) 0, rgba(0,0,0,0.1) 200px),
     17    repeating-linear-gradient(to bottom, transparent 0, transparent 500px, rgba(0,0,0,0.4) 0, rgba(0,0,0,0.4) 1000px),
     18    repeating-linear-gradient(to bottom, hsl(0, 60%, 80%), hsl(0, 60%, 80%) 200px, hsl(70, 60%, 80%) 0, hsl(70, 60%, 80%) 400px, hsl(140, 60%, 80%) 0, hsl(140, 60%, 80%) 600px, hsl(210, 60%, 80%) 0, hsl(210, 60%, 80%) 800px),
     19    white;
     20  background-size:
     21    283px 283px,
     22    283px 283px,
     23    100px 1000px,
     24    100px 800px;
     25 }
     26 
     27 body {
     28  height: 10000px;
     29 }
     30 </style>
     31 
     32 <script>
     33 const searchParams = new URLSearchParams(location.search);
     34 let strict = searchParams.get("strict") == "true";
     35 
     36 var intervalId;
     37 // Start periodic content expansions after we get a scroll event triggered by
     38 // a key press in test() function below, otherwise we may have same scroll
     39 // offsets caused by this script before we start scrolling.
     40 window.addEventListener("scroll",  () => {
     41  var offset = 0;
     42  var initialBodyHeight = 10000;
     43  intervalId = setInterval(() => {
     44    // "Add content" at the top. We do this by making the body longer and adjusting the background position.
     45    offset += 10;
     46    document.documentElement.style.backgroundPosition = `0px ${offset}px`;
     47    document.body.style.height = `${initialBodyHeight + offset}px`;
     48 
     49    switch (searchParams.get("scroll-method")) {
     50      case "scrollBy":
     51        window.scrollBy(0, 10);
     52        break;
     53      case "scrollTop":
     54        document.scrollingElement.scrollTop += 10;
     55        break;
     56      case "scrollTo":
     57        window.scrollTo(0, window.scrollY + 10);
     58        break;
     59      default:
     60        ok(false, "Unsupported scroll method: " + searchParams.get("scroll-method"));
     61        break;
     62    }
     63 
     64    // Simulate some jank.
     65    var freezeDurationInMilliseconds = 100;
     66    var startTime = Date.now();
     67    while (Date.now() - startTime < freezeDurationInMilliseconds) {} // eslint-disable-line no-empty
     68  }, 300);
     69 }, { once: true });
     70 
     71 
     72 async function test() {
     73  // Once this content starts scrolling, it triggers a 100ms jank every 300ms so
     74  // sending arrow down keys for 1500ms will cause some jank.
     75  const TEST_DURATION_MS = 1500;
     76  const timeAtStart = performance.now();
     77  while (performance.now() - timeAtStart < TEST_DURATION_MS) {
     78    switch (searchParams.get("input-type")) {
     79      case "key":
     80        synthesizeKey("KEY_ArrowDown");
     81        break;
     82      case "native-key": {
     83        const DownArrowKeyCode = nativeArrowDownKey();
     84        ok(synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US,
     85                               DownArrowKeyCode, {}  /* no modifier */,
     86                               "", ""),
     87          "Dispatched an down arrow key event");
     88        break;
     89      }
     90      case "wheel":
     91        await synthesizeNativeWheel(window, 50, 50, 0, -50);
     92        break;
     93      default:
     94        ok(false, "Unsupported input type: " + searchParams.get("input-type"));
     95        break;
     96    }
     97    await promiseFrame(window);
     98  }
     99 
    100  // Stop the periodic expansions.
    101  clearInterval(intervalId);
    102 
    103  const records = collectSampledScrollOffsets(document.scrollingElement);
    104 
    105  let previousRecord = { scrollOffsetY: 0, sampledTimeStamp: 0 };
    106  let scrollStartTime = null;
    107  for (const record of records) {
    108    // Ignore offsets before scrolling.
    109    if (record.scrollOffsetY == 0) {
    110      continue;
    111    }
    112    // Ignore offsets after TEST_DURATION_MS has elapsed since the
    113    // start of scrolling. Note that the sampled timestamps are
    114    // in microseconds.
    115    if (!scrollStartTime) {
    116      scrollStartTime = record.sampledTimeStamp;
    117    } else if (((record.sampledTimeStamp - scrollStartTime) / 1000) > TEST_DURATION_MS) {
    118      break;
    119    }
    120    ok(
    121      strict
    122        ? (record.scrollOffsetY > previousRecord.scrollOffsetY)
    123        : (record.scrollOffsetY >= previousRecord.scrollOffsetY),
    124      "scroll offset should be " +
    125      (strict ? "strictly monotonically increasing " : "nondecreasing ") +
    126      "previous offset: " + previousRecord.scrollOffsetY +
    127      ", offset: " + record.scrollOffsetY
    128    );
    129    ok(
    130      record.sampledTimeStamp > previousRecord.sampledTimeStamp,
    131      "sampled time stamp should be strictly monotonically increasing " +
    132      "previous timestamp: " + previousRecord.sampledTimeStamp +
    133      ", timestamp: " + record.sampledTimeStamp
    134    );
    135    previousRecord = record;
    136  }
    137 }
    138 
    139 function isOnChaosMode() {
    140  return SpecialPowers.Services.env.get("MOZ_CHAOSMODE");
    141 }
    142 
    143 function startTest() {
    144  if (searchParams.get("input-type") == "native-key") {
    145    if (getPlatform() != "mac" && getPlatform() != "windows") {
    146      ok(true, "Skipping test because native key events are not supported on " +
    147        getPlatform());
    148      subtestDone();
    149      return;
    150    } else if (getPlatform() == "mac" && isOnChaosMode()) {
    151      ok(true, "Skipping native-key tests on verify runs on Mac");
    152      subtestDone();
    153      return;
    154    } else if (getPlatform() == "windows") {
    155      // Bug 1909721
    156      ok(true, "Skipping native-key tests on Windows due to intermittent failures");
    157      subtestDone();
    158      return;
    159    }
    160  }
    161 
    162  waitUntilApzStable()
    163  .then(test)
    164  .then(subtestDone, subtestFailed);
    165 }
    166 startTest();
    167 </script>