mirror of
https://github.com/servo/servo.git
synced 2025-06-25 17:44:33 +01:00
124 lines
4.2 KiB
JavaScript
124 lines
4.2 KiB
JavaScript
'use strict';
|
|
|
|
// Builds a generic structure that looks like:
|
|
//
|
|
// <div class="scroller"> // 100x100 viewport
|
|
// <div class="contents"></div> // 500x500
|
|
// </div>
|
|
//
|
|
// The |scrollerOverrides| and |contentOverrides| parameters are maps which
|
|
// are applied to the scroller and contents style after basic setup.
|
|
//
|
|
// Appends the outer 'scroller' element to the document body, and returns it.
|
|
function setupScrollTimelineTest(
|
|
scrollerOverrides = new Map(), contentOverrides = new Map()) {
|
|
let scroller = document.createElement('div');
|
|
scroller.style.width = '100px';
|
|
scroller.style.height = '100px';
|
|
// Hide the scrollbars, but maintain the ability to scroll. This setting
|
|
// ensures that variability in scrollbar sizing does not contribute to test
|
|
// failures or flakes.
|
|
scroller.style.overflow = 'hidden';
|
|
for (const [key, value] of scrollerOverrides) {
|
|
scroller.style[key] = value;
|
|
}
|
|
|
|
let contents = document.createElement('div');
|
|
contents.style.width = '500px';
|
|
contents.style.height = '500px';
|
|
for (const [key, value] of contentOverrides) {
|
|
contents.style[key] = value;
|
|
}
|
|
|
|
scroller.appendChild(contents);
|
|
document.body.appendChild(scroller);
|
|
return scroller;
|
|
}
|
|
|
|
// Helper method to calculate the current time, implementing only step 5 of
|
|
// https://wicg.github.io/scroll-animations/#current-time-algorithm
|
|
function calculateCurrentTime(
|
|
currentScrollOffset, startScrollOffset, endScrollOffset) {
|
|
return ((currentScrollOffset - startScrollOffset) /
|
|
(endScrollOffset - startScrollOffset)) *
|
|
100;
|
|
}
|
|
|
|
function createScroller(test) {
|
|
var scroller = createDiv(test);
|
|
scroller.innerHTML = "<div class='contents'></div>";
|
|
scroller.classList.add('scroller');
|
|
// Trigger layout run.
|
|
scroller.scrollTop;
|
|
return scroller;
|
|
}
|
|
|
|
function createScrollerWithStartAndEnd(test, orientationClass = 'vertical') {
|
|
var scroller = createDiv(test);
|
|
scroller.innerHTML =
|
|
`<div class='contents'>
|
|
<div id='start'></div>
|
|
<div id='end'></div>
|
|
</div>`;
|
|
scroller.classList.add('scroller');
|
|
scroller.classList.add(orientationClass);
|
|
|
|
return scroller;
|
|
}
|
|
|
|
function createScrollTimeline(test, options) {
|
|
options = options || {
|
|
source: createScroller(test)
|
|
}
|
|
return new ScrollTimeline(options);
|
|
}
|
|
|
|
function createScrollLinkedAnimation(test, timeline) {
|
|
return createScrollLinkedAnimationWithTiming(test, /* duration in ms*/ 1000, timeline);
|
|
}
|
|
|
|
function createScrollLinkedAnimationWithTiming(test, timing, timeline) {
|
|
if (timeline === undefined)
|
|
timeline = createScrollTimeline(test);
|
|
const KEYFRAMES = { opacity: [0, 1] };
|
|
return new Animation(
|
|
new KeyframeEffect(createDiv(test), KEYFRAMES, timing), timeline);
|
|
}
|
|
|
|
function assert_approx_equals_or_null(actual, expected, tolerance, name) {
|
|
if (actual === null || expected === null){
|
|
assert_equals(actual, expected, name);
|
|
}
|
|
else {
|
|
assert_approx_equals(actual, expected, tolerance, name);
|
|
}
|
|
}
|
|
|
|
function assert_percents_approx_equal(actual, expected, maxScroll,
|
|
description) {
|
|
// Base the tolerance on being out by up to half a pixel.
|
|
const tolerance = 0.5 / maxScroll * 100;
|
|
assert_equals(actual.unit, "percent", `'actual' unit type must be ` +
|
|
`'percent' for "${description}"`);
|
|
assert_true(actual instanceof CSSUnitValue, `'actual' must be of type ` +
|
|
`CSSNumberish for "${description}"`);
|
|
if (expected instanceof CSSUnitValue){
|
|
// Verify that when the expected in a CSSUnitValue, it is the correct unit
|
|
// type
|
|
assert_equals(expected.unit, "percent", `'expected' unit type must be ` +
|
|
`'percent' for "${description}"`);
|
|
assert_approx_equals(actual.value, expected.value, tolerance,
|
|
`values do not match for "${description}"`);
|
|
} else if (typeof expected, "number"){
|
|
assert_approx_equals(actual.value, expected, tolerance,
|
|
`values do not match for "${description}"`);
|
|
}
|
|
}
|
|
|
|
function assert_percents_equal(actual, expected, description) {
|
|
// Rough estimate of the default size of the scrollable area based on
|
|
// sizes in setupScrollTimelineTest.
|
|
const defaultScrollRange = 400;
|
|
return assert_percents_approx_equal(actual, expected, defaultScrollRange,
|
|
description);
|
|
}
|