<!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>