Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/third_party/rust/tokio-util/tests/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 13 kB image not shown  

Quelle  file_animations_omta_scroll.html   Sprache: unbekannt

 
Untersuchungsergebnis.html Download desUnknown {[0] [0] [0]}zum Wurzelverzeichnis wechseln

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Test for css-animations running on the compositor thread with scroll-timeline</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script src="/tests/SimpleTest/paint_listener.js"></script>
  <script src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
  <script type="application/javascript" src="animation_utils.js"></script>
  <style type="text/css">
    @keyframes transform_anim {
      from { transform: translate(50px); }
      to { transform: translate(150px); }
    }

    @keyframes always_fifty {
      from, to { transform: translate(50px); }
    }

    @keyframes geometry {
      from { width: 50px; }
      to { width: 100px; }
    }

    .target {
      /* The animation target needs geometry in order to qualify for OMTA */
      width: 100px;
      height: 100px;
      background-color: green;
    }

    .scroller {
      width: 100px;
      height: 100px;
      overflow: scroll;
      scroll-timeline-name: --scroll_timeline;
    }

    .content {
      block-size: 100%;
      padding-block-end: 100px;
    }
  </style>
</head>
<body>
  <div id="display"></div>
  <pre id="test"></pre>
</body>
<script type="application/javascript">
"use strict";

// Global state
var gScroller = null;
var gDiv = null;

// Shortcut omta_is and friends by filling in the initial 'elem' argument
// with gDiv.
[ 'omta_is', 'omta_todo_is', 'omta_is_approx' ].forEach(function(fn) {
  var origFn = window[fn];
  window[fn] = function() {
    var args = Array.from(arguments);
    if (!(args[0] instanceof Element)) {
      args.unshift(gDiv);
    }
    return origFn.apply(window, args);
  };
});

// Shortcut new_div and done_div to update gDiv
var originalNewDiv = window.new_div;
window.new_div = function(style) {
  [ gDiv ] = originalNewDiv(style);
};
var originalDoneDiv = window.done_div;
window.done_div = function() {
  originalDoneDiv();
  gDiv = null;
};

// Bind the ok and todo to the opener, and close this window when we finish.
var ok = opener.ok.bind(opener);
var todo = opener.todo.bind(opener);
function finish() {
  var o = opener;
  self.close();
  o.SimpleTest.finish();
}

function new_scroller() {
  gScroller = document.createElement('div');
  gScroller.className = `scroller`;

  let content = document.createElement('div');
  content.className = 'content';

  gScroller.appendChild(content);
  document.getElementById("display").appendChild(gScroller);
  return gScroller;
}

function done_scroller() {
  gScroller.firstChild.remove();
  gScroller.remove();
  gScroller = null;
}

waitUntilApzStable().then(() => {
  runOMTATest(function() {
    var onAbort = function() {
      if (gDiv) {
        done_div();
      }
      if (gScroller) {
        done_scroller();
      }
    };
    runAllAsyncAnimTests(onAbort).then(finish);
  }, finish);
});

//----------------------------------------------------------------------
//
// Test cases
//
//----------------------------------------------------------------------

// The non-omta property with scroll-timeline together with an omta property
// with document-timeline.
addAsyncAnimTest(async function() {
  new_scroller();
  new_div("animation: geometry 10s, always_fifty 1s infinite; " +
          "animation-timeline: --scroll_timeline, auto");
  await waitForPaintsFlushed();

  // Note: width is not a OMTA property, so it must be running on the main
  // thread.
  omta_is("transform", { tx: 50 }, RunningOn.Compositor,
          "transform animations should runs on compositor thread");

  done_div();
  done_scroller();
});

// transform property with scroll-driven animations.
addAsyncAnimTest(async function() {
  let scroller = new_scroller();
  new_div("animation: transform_anim 1s linear; " +
          "animation-timeline: --scroll_timeline;");
  await waitForPaintsFlushed();

  scroller.scrollTop = 50;
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 100 }, 0.1, RunningOn.Compositor,
                 "scroll transform animations should runs on compositor " +
                 "thread");

  done_div();
  done_scroller();
});


// The scroll-driven animation with an underlying value and make it go from the
// active phase to the before phase.
addAsyncAnimTest(async function() {
  let scroller = new_scroller();
  new_div("animation: always_fifty 5s linear 5s; " +
          "animation-timeline: --scroll_timeline; " +
          "transform: translate(25px);");
  await waitForPaintsFlushed();

  // NOTE: getOMTAStyle() can't detect the animation is running on the
  // compositor during the delay phase.
  omta_is_approx("transform", { tx: 25 }, 0.1, RunningOn.Either,
                 "The scroll animation is in delay");

  scroller.scrollTop = 75;
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 50 }, 0.1, RunningOn.Compositor,
                 "scroll transform animations should runs on compositor " +
                 "thread");

  // Use setAsyncScrollOffset() to update apz (compositor thread only) to make
  // sure Bug 1776077 is reproducible.
  let utils = SpecialPowers.wrap(window).windowUtils;
  utils.setAsyncScrollOffset(scroller, 0, -50);
  utils.advanceTimeAndRefresh(16);
  utils.restoreNormalRefresh();
  await waitForPaints();

  // NOTE: setAsyncScrollOffset() doesn't update main thread, so we check the
  // OMTA style directly.
  let compositorStr =
    SpecialPowers.DOMWindowUtils.getOMTAStyle(gDiv, "transform");
  ok(compositorStr === "matrix(1, 0, 0, 1, 25, 0)",
     "scroll animations is in delay phase before calling main thread style " +
     "udpate");

  scroller.scrollTop = 25;
  await waitForPaintsFlushed();

  compositorStr = SpecialPowers.DOMWindowUtils.getOMTAStyle(gDiv, "transform");
  ok(compositorStr === "",
     "scroll animation in delay phase clears its OMTA style");
  omta_is_approx("transform", { tx: 25 }, 0.1, RunningOn.Either,
                 "The scroll animation is in delay");

  done_div();
  done_scroller();
});

// The scroll-driven animation without an underlying value and make it go from
// the active phase to the before phase.
addAsyncAnimTest(async function() {
  let scroller = new_scroller();
  new_div("animation: always_fifty 5s linear 5s; " +
          "animation-timeline: --scroll_timeline;");
  await waitForPaintsFlushed();

  // NOTE: getOMTAStyle() can't detect the animation is running on the
  // compositor during the delay phase.
  omta_is_approx("transform", { tx: 0 }, 0.1, RunningOn.Either,
                 "The scroll animation is in delay");

  scroller.scrollTop = 75;
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 50 }, 0.1, RunningOn.Compositor,
                 "scroll transform animations should runs on compositor " +
                 "thread");

  // Use setAsyncScrollOffset() to update apz (compositor thread only) to make
  // sure Bug 1776077 is reproducible.
  let utils = SpecialPowers.wrap(window).windowUtils;
  utils.setAsyncScrollOffset(scroller, 0, -50);
  utils.advanceTimeAndRefresh(16);
  utils.restoreNormalRefresh();
  await waitForPaints();

  // NOTE: setAsyncScrollOffset() doesn't update main thread, so we check the
  // OMTA style directly.
  let compositorStr =
    SpecialPowers.DOMWindowUtils.getOMTAStyle(gDiv, "transform");
  ok(compositorStr === "matrix(1, 0, 0, 1, 0, 0)",
     "scroll animations is in delay phase before calling main thread style " +
     "udpate");

  done_div();
  done_scroller();
});

// The scroll-driven animation is in delay, together with other runing
// animations.
addAsyncAnimTest(async function() {
  let scroller = new_scroller();
  new_div("animation: transform_anim 10s linear -5s paused, " +
          "           always_fifty 5s linear 5s; " +
          "animation-timeline: auto, --scroll_timeline;");
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 100 }, 0.1, RunningOn.Compositor,
                 "The scroll animation is in delay");

  scroller.scrollTop = 75;
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 50 }, 0.1, RunningOn.Compositor,
                 "scroll transform animations should runs on compositor " +
                 "thread");

  let utils = SpecialPowers.wrap(window).windowUtils;
  utils.setAsyncScrollOffset(scroller, 0, -50);
  utils.advanceTimeAndRefresh(16);
  utils.restoreNormalRefresh();
  await waitForPaints();

  // NOTE: setAsyncScrollOffset() doesn't update main thread, so we check the
  // OMTA style directly.
  let compositorStr =
    SpecialPowers.DOMWindowUtils.getOMTAStyle(gDiv, "transform");
  ok(compositorStr === "matrix(1, 0, 0, 1, 100, 0)",
     "scroll animations is in delay phase before calling main thread style " +
     "udpate");

  done_div();
  done_scroller();
});

addAsyncAnimTest(async function() {
  let iframe = document.createElement("iframe");
  iframe.setAttribute("style", "width: 200px; height: 200px");
  iframe.setAttribute("scrolling", "no");
  iframe.srcdoc =
    "<!DOCTYPE HTML>" +
    "<html style='min-height: 100%; padding-bottom: 100px;'>" +
    "<style>" +
    "@keyframes anim { from, to { transform: translate(50px) } }" +
    "</style>" +
    "<div id='target_in_iframe' " +
    "     style='width:50px; height:50px; background:green; " +
    "            animation: anim 10s linear; " +
    "            animation-timeline: scroll(root);'>" +
    "</div>" +
    "</html>";

  await new Promise(resolve => {
    iframe.onload = resolve;
    document.body.appendChild(iframe);
  });

  gDiv = iframe.contentDocument.getElementById("target_in_iframe");

  const root = iframe.contentDocument.scrollingElement;
  const maxScroll = root.scrollHeight - root.clientHeight;
  root.scrollTop = 0.5 * maxScroll;
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 50 }, 0, RunningOn.MainThread,
                 "scroll transform animations inside an iframe with " +
                 "scrolling:no should run on the main thread");

  gDiv = null;
  iframe.remove();
});

// FIXME: Bug 1818346. Support OMTA for view-timeline.
addAsyncAnimTest(async function() {
  let scroller = document.createElement("div");
  scroller.style.width = "100px";
  scroller.style.height = "100px";
  // Use hidden so we don't have scrollbar, to make sure the scrollport size
  // is 100px x 100px, so view progress visibility range is 100px on block axis.
  scroller.style.overflow = "hidden";

  let content1 = document.createElement("div");
  content1.style.height = "150px";
  scroller.appendChild(content1);

  let subject = document.createElement("div");
  subject.style.width = "50px";
  subject.style.height = "50px";
  subject.style.viewTimelineName = "--view_timeline";
  scroller.appendChild(subject);

  // Let |target| be the child of |subject|, so view-timeline-name property of
  // |subject| is referenceable.
  let target = document.createElement("div");
  target.style.width = "10px";
  target.style.height = "10px";
  subject.appendChild(target);
  gDiv = target;

  let content2 = document.createElement("div");
  content2.style.height = "150px";
  scroller.appendChild(content2);

  // So the DOM tree looks like this:
  // <div class=scroller>  <!-- "scroller", height: 100px; -->
  //   <div></div>         <!-- "",         height: 150px -->
  //   <div></div>         <!-- "subject",  height: 50px; -->
  //   <div></div>         <!-- "",         height: 150px; -->
  // </div>
  // The subject is in view when scroller.scrollTop is [50px, 200px].
  document.getElementById("display").appendChild(scroller);
  await waitForPaintsFlushed();

  scroller.scrollTop = 0;
  target.style.animation = "transform_anim 10s linear";
  target.style.animationTimeline = "--view_timeline";
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 0 }, 0.1, RunningOn.OnMainThread,
                 "The scroll animation is out of view");

  scroller.scrollTop = 50;
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 50 }, 0.1, RunningOn.OnMainThread,
                 "The scroll animation is 0%");

  scroller.scrollTop = 125;
  await waitForPaintsFlushed();

  omta_is_approx("transform", { tx: 100 }, 0.1, RunningOn.OnMainThread,
                 "The scroll animation is 50%");

  target.remove();
  content2.remove();
  subject.remove();
  content1.remove();
  scroller.remove();
  gDiv = null;
});

</script>
</html>

[ zur Elbe Produktseite wechseln0.45Quellennavigators  ]