<!DOCTYPE html>
<title>Tests that ScrollTimeline works properly with writing mode and directionality</title>
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<script src="common.js"></script>


<script>
// Creates a DOM structure like:
//   - container
//     - box {100x100}
//     - scroller {100x100, writing-mode, direction}
//       - contents
function createTestDOM(x_scroll_axis, writing_mode, direction) {
  const elements = {};

  elements.container = document.createElement('div');

  elements.box = document.createElement('div');
  elements.box.style.height = '100px';
  elements.box.style.width = '100px';

  elements.scroller = document.createElement('div');
  elements.scroller.style.height = '100px';
  elements.scroller.style.width = '100px';
  if (x_scroll_axis)
    elements.scroller.style.overflowX = 'scroll';
  else
    elements.scroller.style.overflowY = 'scroll';
  elements.scroller.style.direction = direction;
  elements.scroller.style.writingMode = writing_mode;

  // Callers don't need access to this.
  const contents = document.createElement('div');
  contents.style.height = x_scroll_axis ? '100%' : '1000px';
  contents.style.width = x_scroll_axis ? '1000px' : '100%';

  elements.scroller.appendChild(contents);
  elements.container.appendChild(elements.box);
  elements.container.appendChild(elements.scroller);
  document.body.appendChild(elements.container);

  return elements;
}

function createAndPlayTestAnimation(elements, timeline_orientation) {
  const effect = new KeyframeEffect(
      elements.box,
      [{transform: 'translateY(0)'}, {transform: 'translateY(200px)'}], {
        duration: 1000,
      });

  const timeline = new ScrollTimeline({
    scrollSource: elements.scroller,
    orientation: timeline_orientation
  });
  const animation = new WorkletAnimation('passthrough', effect, timeline);
  animation.play();
  return animation;
}

setup(setupAndRegisterTests, {explicit_done: true});

function setupAndRegisterTests() {
  registerPassthroughAnimator().then(() => {
    // Note that block horizontal-tb is tested implicitly in the basic
    // ScrollTimeline tests (as it is the default).
    async_test(
        block_vertical_lr,
        'A block ScrollTimeline should produce the correct current time for vertical-lr');
    async_test(
        block_vertical_rl,
        'A block ScrollTimeline should produce the correct current time for vertical-rl');
    // Again, inline for horizontal-tb and direction: ltr is the default
    // inline mode and so is tested elsewhere.
    async_test(
        inline_horizontal_tb_rtl,
        'An inline ScrollTimeline should produce the correct current time for horizontal-tb and direction: rtl');
    async_test(
        inline_vertical_writing_mode_ltr,
        'An inline ScrollTimeline should produce the correct current time for vertical writing mode');
    async_test(
        inline_vertical_writing_mode_rtl,
        'An inline ScrollTimeline should produce the correct current time for vertical writing mode and direction: rtl');
    done();
  });
}

function block_vertical_lr(t) {
  const elements = createTestDOM(true, 'vertical-lr', 'ltr');
  const animation = createAndPlayTestAnimation(elements, 'block');

  // Move the scroller to the 25% point.
  const maxScroll =
      elements.scroller.scrollWidth - elements.scroller.clientWidth;
  elements.scroller.scrollLeft = 0.25 * maxScroll;

  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
    assert_equals(
        getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
  }));
}

function block_vertical_rl(t) {
  const elements = createTestDOM(true, 'vertical-rl', 'ltr');
  const animation = createAndPlayTestAnimation(elements, 'block');

  // Move the scroller to the left 25% point, since it is vertical-rl,
  // i.e leftwards overflow direction, scrollLeft is -25% point.
  const maxScroll =
      elements.scroller.scrollWidth - elements.scroller.clientWidth;
  elements.scroller.scrollLeft = -0.25 * maxScroll;

  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
    assert_equals(
        getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
  }));
}

function inline_horizontal_tb_rtl(t) {
  const elements = createTestDOM(true, 'horizontal-tb', 'rtl');
  const animation = createAndPlayTestAnimation(elements, 'inline');

  // Move the scroller to the left 25% point, since it is direction: rtl,
  // i.e leftwards overflow direction, scrollLeft is -25% point.
  const maxScroll =
      elements.scroller.scrollWidth - elements.scroller.clientWidth;
  elements.scroller.scrollLeft = -0.25 * maxScroll;

  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
    assert_equals(
        getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
  }));
}

function inline_vertical_writing_mode_ltr(t) {
  const elements = createTestDOM(false, 'vertical-lr', 'ltr');
  const animation = createAndPlayTestAnimation(elements, 'inline');

  // Move the scroller to the 25% point.
  const maxScroll =
      elements.scroller.scrollHeight - elements.scroller.clientHeight;
  elements.scroller.scrollTop = 0.25 * maxScroll;

  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
    assert_equals(
        getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
  }));
}

function inline_vertical_writing_mode_rtl(t) {
  const elements = createTestDOM(false, 'vertical-lr', 'rtl');
  const animation = createAndPlayTestAnimation(elements, 'inline');

  // Move the scroller to the top 25% point, since it is a vertical-lr writing mode
  // and direction: rtl, i.e upwards overflow direction, scrollTop is -25% point.
  const maxScroll =
      elements.scroller.scrollHeight - elements.scroller.clientHeight;
  elements.scroller.scrollTop = -0.25 * maxScroll;

  waitForNotNullLocalTime(animation).then(t.step_func_done(() => {
    assert_equals(
        getComputedStyle(elements.box).transform, 'matrix(1, 0, 0, 1, 0, 50)');
  }));
}
</script>
