Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

2
test/fixtures/wpt/resources/.htaccess vendored Normal file
View File

@ -0,0 +1,2 @@
# make tests that use utf-16 not inherit the encoding for testharness.js et. al.
AddCharset utf-8 .css .js

2
test/fixtures/wpt/resources/META.yml vendored Normal file
View File

@ -0,0 +1,2 @@
suggested_reviewers:
- jgraham

View File

@ -0,0 +1,102 @@
// NOTE(edvardt):
// This file is a slimmed down wrapper for the old SVGAnimationTestCase.js,
// it has some convenience functions and should not be used for new tests.
// New tests should not build on this API as it's just meant to keep things
// working.
// Helper functions
const xlinkNS = "http://www.w3.org/1999/xlink"
function expectFillColor(element, red, green, blue, message) {
let color = window.getComputedStyle(element, null).fill;
var re = new RegExp("rgba?\\(([^, ]*), ([^, ]*), ([^, ]*)(?:, )?([^, ]*)\\)");
rgb = re.exec(color);
assert_approx_equals(Number(rgb[1]), red, 2.0, message);
assert_approx_equals(Number(rgb[2]), green, 2.0, message);
assert_approx_equals(Number(rgb[3]), blue, 2.0, message);
}
function expectColor(element, red, green, blue, property) {
if (typeof property != "string")
color = getComputedStyle(element).getPropertyValue("color");
else
color = getComputedStyle(element).getPropertyValue(property);
var re = new RegExp("rgba?\\(([^, ]*), ([^, ]*), ([^, ]*)(?:, )?([^, ]*)\\)");
rgb = re.exec(color);
assert_approx_equals(Number(rgb[1]), red, 2.0);
assert_approx_equals(Number(rgb[2]), green, 2.0);
assert_approx_equals(Number(rgb[3]), blue, 2.0);
}
function createSVGElement(type) {
return document.createElementNS("http://www.w3.org/2000/svg", type);
}
// Inspired by Layoutests/animations/animation-test-helpers.js
function moveAnimationTimelineAndSample(index) {
var animationId = expectedResults[index][0];
var time = expectedResults[index][1];
var sampleCallback = expectedResults[index][2];
var animation = rootSVGElement.ownerDocument.getElementById(animationId);
// If we want to sample the animation end, add a small delta, to reliable point past the end of the animation.
newTime = time;
// The sample time is relative to the start time of the animation, take that into account.
rootSVGElement.setCurrentTime(newTime);
// NOTE(edvardt):
// This is a dumb hack, some of the old tests sampled before the animation start, this
// isn't technically part of the animation tests and is "impossible" to translate since
// tests start automatically. Thus I solved it by skipping it.
if (time != 0.0)
sampleCallback();
}
var currentTest = 0;
var expectedResults;
function sampleAnimation(t) {
if (currentTest == expectedResults.length) {
t.done();
return;
}
moveAnimationTimelineAndSample(currentTest);
++currentTest;
step_timeout(t.step_func(function () { sampleAnimation(t); }), 0);
}
function runAnimationTest(t, expected) {
if (!expected)
throw("Expected results are missing!");
if (currentTest > 0)
throw("Not allowed to call runAnimationTest() twice");
expectedResults = expected;
testCount = expectedResults.length;
currentTest = 0;
step_timeout(t.step_func(function () { sampleAnimation(this); }), 50);
}
function smil_async_test(func) {
async_test(t => {
window.onload = t.step_func(function () {
// Pause animations, we'll drive them manually.
// This also ensures that the timeline is paused before
// it starts. This should make the instance time of the below
// 'click' (for instance) 0, and hence minimize rounding
// errors for the addition in moveAnimationTimelineAndSample.
rootSVGElement.pauseAnimations();
// If eg. an animation is running with begin="0s", and
// we want to sample the first time, before the animation
// starts, then we can't delay the testing by using an
// onclick event, as the animation would be past start time.
func(t);
});
});
}

View File

@ -0,0 +1,34 @@
/*
* Function that sends an accesskey using the proper key combination depending on the browser and OS.
*
* This needs that the test imports the following scripts:
* <script src="/resources/testdriver.js"></script>
* <script src="/resources/testdriver-actions.js"></script>
* <script src="/resources/testdriver-vendor.js"></script>
*/
function pressAccessKey(accessKey){
let controlKey = '\uE009'; // left Control key
let altKey = '\uE00A'; // left Alt key
let optionKey = altKey; // left Option key
let shiftKey = '\uE008'; // left Shift key
// There are differences in using accesskey across browsers and OS's.
// See: // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey
let isMacOSX = navigator.userAgent.indexOf("Mac") != -1;
let osAccessKey = isMacOSX ? [controlKey, optionKey] : [shiftKey, altKey];
let actions = new test_driver.Actions();
// Press keys.
for (let key of osAccessKey) {
actions = actions.keyDown(key);
}
actions = actions
.keyDown(accessKey)
.addTick()
.keyUp(accessKey);
osAccessKey.reverse();
for (let key of osAccessKey) {
actions = actions.keyUp(key);
}
return actions.send();
}

16
test/fixtures/wpt/resources/blank.html vendored Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Blank Page</title>
<script>
window.onload = function(event) {
// This is needed to ensure the onload event fires when this page is
// opened as a popup.
// See https://github.com/web-platform-tests/wpt/pull/18157
};
</script>
</head>
<body>
</body>
</html>

1097
test/fixtures/wpt/resources/channel.sub.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,252 @@
(function() {
// Test is initiated from body.onload, so explicit done() call is required.
setup({ explicit_done: true });
function checkSubtreeExpectedValues(t, parent, prefix)
{
var checkedLayout = checkExpectedValues(t, parent, prefix);
Array.prototype.forEach.call(parent.childNodes, function(node) {
checkedLayout |= checkSubtreeExpectedValues(t, node, prefix);
});
return checkedLayout;
}
function checkAttribute(output, node, attribute)
{
var result = node.getAttribute && node.getAttribute(attribute);
output.checked |= !!result;
return result;
}
function assert_tolerance(actual, expected, message)
{
if (isNaN(expected) || isNaN(actual) || Math.abs(actual - expected) >= 1) {
assert_equals(actual, Number(expected), message);
}
}
function checkDataKeys(node) {
// The purpose of this list of data-* attributes is simply to ensure typos
// in tests are caught. It is therefore "ok" to add to this list for
// specific tests.
var validData = new Set([
"data-anchor-polyfill",
"data-expected-width",
"data-expected-height",
"data-offset-x",
"data-offset-y",
"data-expected-client-width",
"data-expected-client-height",
"data-expected-scroll-width",
"data-expected-scroll-height",
"data-expected-bounding-client-rect-width",
"data-expected-bounding-client-rect-height",
"data-total-x",
"data-total-y",
"data-expected-display",
"data-expected-padding-top",
"data-expected-padding-bottom",
"data-expected-padding-left",
"data-expected-padding-right",
"data-expected-margin-top",
"data-expected-margin-bottom",
"data-expected-margin-left",
"data-expected-margin-right"
]);
if (!node || !node.getAttributeNames)
return;
// Use "data-test" prefix if you need custom-named data elements.
for (let name of node.getAttributeNames()) {
if (name.startsWith("data-") && !name.startsWith("data-test"))
assert_true(validData.has(name), name + " is a valid data attribute");
}
}
function checkExpectedValues(t, node, prefix)
{
checkDataKeys(node);
var output = { checked: false };
var expectedWidth = checkAttribute(output, node, "data-expected-width");
if (expectedWidth) {
assert_tolerance(node.offsetWidth, expectedWidth, prefix + "width");
}
var expectedHeight = checkAttribute(output, node, "data-expected-height");
if (expectedHeight) {
assert_tolerance(node.offsetHeight, expectedHeight, prefix + "height");
}
var expectedOffset = checkAttribute(output, node, "data-offset-x");
if (expectedOffset) {
assert_tolerance(node.offsetLeft, expectedOffset, prefix + "offsetLeft");
}
var expectedOffset = checkAttribute(output, node, "data-offset-y");
if (expectedOffset) {
assert_tolerance(node.offsetTop, expectedOffset, prefix + "offsetTop");
}
var expectedWidth = checkAttribute(output, node, "data-expected-client-width");
if (expectedWidth) {
assert_tolerance(node.clientWidth, expectedWidth, prefix + "clientWidth");
}
var expectedHeight = checkAttribute(output, node, "data-expected-client-height");
if (expectedHeight) {
assert_tolerance(node.clientHeight, expectedHeight, prefix + "clientHeight");
}
var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width");
if (expectedWidth) {
assert_tolerance(node.scrollWidth, expectedWidth, prefix + "scrollWidth");
}
var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height");
if (expectedHeight) {
assert_tolerance(node.scrollHeight, expectedHeight, prefix + "scrollHeight");
}
var expectedWidth = checkAttribute(output, node, "data-expected-bounding-client-rect-width");
if (expectedWidth) {
assert_tolerance(node.getBoundingClientRect().width, expectedWidth, prefix + "getBoundingClientRect().width");
}
var expectedHeight = checkAttribute(output, node, "data-expected-bounding-client-rect-height");
if (expectedHeight) {
assert_tolerance(node.getBoundingClientRect().height, expectedHeight, prefix + "getBoundingClientRect().height");
}
var expectedOffset = checkAttribute(output, node, "data-total-x");
if (expectedOffset) {
var totalLeft = node.clientLeft + node.offsetLeft;
assert_tolerance(totalLeft, expectedOffset, prefix +
"clientLeft+offsetLeft (" + node.clientLeft + " + " + node.offsetLeft + ")");
}
var expectedOffset = checkAttribute(output, node, "data-total-y");
if (expectedOffset) {
var totalTop = node.clientTop + node.offsetTop;
assert_tolerance(totalTop, expectedOffset, prefix +
"clientTop+offsetTop (" + node.clientTop + " + " + node.offsetTop + ")");
}
var expectedDisplay = checkAttribute(output, node, "data-expected-display");
if (expectedDisplay) {
var actualDisplay = getComputedStyle(node).display;
assert_equals(actualDisplay, expectedDisplay, prefix + "display");
}
var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top");
if (expectedPaddingTop) {
var actualPaddingTop = getComputedStyle(node).paddingTop;
// Trim the unit "px" from the output.
actualPaddingTop = actualPaddingTop.slice(0, -2);
assert_equals(actualPaddingTop, expectedPaddingTop, prefix + "padding-top");
}
var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom");
if (expectedPaddingBottom) {
var actualPaddingBottom = getComputedStyle(node).paddingBottom;
// Trim the unit "px" from the output.
actualPaddingBottom = actualPaddingBottom.slice(0, -2);
assert_equals(actualPaddingBottom, expectedPaddingBottom, prefix + "padding-bottom");
}
var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left");
if (expectedPaddingLeft) {
var actualPaddingLeft = getComputedStyle(node).paddingLeft;
// Trim the unit "px" from the output.
actualPaddingLeft = actualPaddingLeft.slice(0, -2);
assert_equals(actualPaddingLeft, expectedPaddingLeft, prefix + "padding-left");
}
var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right");
if (expectedPaddingRight) {
var actualPaddingRight = getComputedStyle(node).paddingRight;
// Trim the unit "px" from the output.
actualPaddingRight = actualPaddingRight.slice(0, -2);
assert_equals(actualPaddingRight, expectedPaddingRight, prefix + "padding-right");
}
var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top");
if (expectedMarginTop) {
var actualMarginTop = getComputedStyle(node).marginTop;
// Trim the unit "px" from the output.
actualMarginTop = actualMarginTop.slice(0, -2);
assert_equals(actualMarginTop, expectedMarginTop, prefix + "margin-top");
}
var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom");
if (expectedMarginBottom) {
var actualMarginBottom = getComputedStyle(node).marginBottom;
// Trim the unit "px" from the output.
actualMarginBottom = actualMarginBottom.slice(0, -2);
assert_equals(actualMarginBottom, expectedMarginBottom, prefix + "margin-bottom");
}
var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left");
if (expectedMarginLeft) {
var actualMarginLeft = getComputedStyle(node).marginLeft;
// Trim the unit "px" from the output.
actualMarginLeft = actualMarginLeft.slice(0, -2);
assert_equals(actualMarginLeft, expectedMarginLeft, prefix + "margin-left");
}
var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right");
if (expectedMarginRight) {
var actualMarginRight = getComputedStyle(node).marginRight;
// Trim the unit "px" from the output.
actualMarginRight = actualMarginRight.slice(0, -2);
assert_equals(actualMarginRight, expectedMarginRight, prefix + "margin-right");
}
return output.checked;
}
var testNumber = 0;
var highlightError = false; // displays outline around failed test element.
var printDomOnError = true; // prints dom when test fails.
window.checkLayout = function(selectorList, callDone = true)
{
if (!selectorList) {
console.error("You must provide a CSS selector of nodes to check.");
return;
}
var nodes = document.querySelectorAll(selectorList);
nodes = Array.prototype.slice.call(nodes);
var checkedLayout = false;
Array.prototype.forEach.call(nodes, function(node) {
test(function(t) {
var container = node.parentNode.className == 'container' ? node.parentNode : node;
var prefix =
printDomOnError ? '\n' + container.outerHTML + '\n' : '';
var passed = false;
try {
checkedLayout |= checkExpectedValues(t, node.parentNode, prefix);
checkedLayout |= checkSubtreeExpectedValues(t, node, prefix);
passed = true;
} finally {
if (!passed && highlightError) {
if (!document.getElementById('testharness_error_css')) {
var style = document.createElement('style');
style.id = 'testharness_error_css';
style.textContent = '.testharness_error { outline: red dotted 2px !important; }';
document.body.appendChild(style);
}
if (node)
node.classList.add('testharness_error');
}
checkedLayout |= !passed;
}
}, selectorList + ' ' + String(++testNumber));
});
if (!checkedLayout) {
console.error("No valid data-* attributes found in selector list : " + selectorList);
}
if (callDone)
done();
};
})();

View File

@ -0,0 +1,245 @@
(function() {
function insertAfter(nodeToAdd, referenceNode)
{
if (referenceNode == document.body) {
document.body.appendChild(nodeToAdd);
return;
}
if (referenceNode.nextSibling)
referenceNode.parentNode.insertBefore(nodeToAdd, referenceNode.nextSibling);
else
referenceNode.parentNode.appendChild(nodeToAdd);
}
function positionedAncestor(node)
{
var ancestor = node.parentNode;
while (getComputedStyle(ancestor).position == 'static')
ancestor = ancestor.parentNode;
return ancestor;
}
function checkSubtreeExpectedValues(parent, failures)
{
var checkedLayout = checkExpectedValues(parent, failures);
Array.prototype.forEach.call(parent.childNodes, function(node) {
checkedLayout |= checkSubtreeExpectedValues(node, failures);
});
return checkedLayout;
}
function checkAttribute(output, node, attribute)
{
var result = node.getAttribute && node.getAttribute(attribute);
output.checked |= !!result;
return result;
}
function checkExpectedValues(node, failures)
{
var output = { checked: false };
var expectedWidth = checkAttribute(output, node, "data-expected-width");
if (expectedWidth) {
if (isNaN(expectedWidth) || Math.abs(node.offsetWidth - expectedWidth) >= 1)
failures.push("Expected " + expectedWidth + " for width, but got " + node.offsetWidth + ". ");
}
var expectedHeight = checkAttribute(output, node, "data-expected-height");
if (expectedHeight) {
if (isNaN(expectedHeight) || Math.abs(node.offsetHeight - expectedHeight) >= 1)
failures.push("Expected " + expectedHeight + " for height, but got " + node.offsetHeight + ". ");
}
var expectedOffset = checkAttribute(output, node, "data-offset-x");
if (expectedOffset) {
if (isNaN(expectedOffset) || Math.abs(node.offsetLeft - expectedOffset) >= 1)
failures.push("Expected " + expectedOffset + " for offsetLeft, but got " + node.offsetLeft + ". ");
}
var expectedOffset = checkAttribute(output, node, "data-offset-y");
if (expectedOffset) {
if (isNaN(expectedOffset) || Math.abs(node.offsetTop - expectedOffset) >= 1)
failures.push("Expected " + expectedOffset + " for offsetTop, but got " + node.offsetTop + ". ");
}
var expectedOffset = checkAttribute(output, node, "data-positioned-offset-x");
if (expectedOffset) {
var actualOffset = node.getBoundingClientRect().left - positionedAncestor(node).getBoundingClientRect().left;
if (isNaN(expectedOffset) || Math.abs(actualOffset - expectedOffset) >= 1)
failures.push("Expected " + expectedOffset + " for getBoundingClientRect().left offset, but got " + actualOffset + ". ");
}
var expectedOffset = checkAttribute(output, node, "data-positioned-offset-y");
if (expectedOffset) {
var actualOffset = node.getBoundingClientRect().top - positionedAncestor(node).getBoundingClientRect().top;
if (isNaN(expectedOffset) || Math.abs(actualOffset - expectedOffset) >= 1)
failures.push("Expected " + expectedOffset + " for getBoundingClientRect().top offset, but got " + actualOffset + ". ");
}
var expectedWidth = checkAttribute(output, node, "data-expected-client-width");
if (expectedWidth) {
if (isNaN(expectedWidth) || Math.abs(node.clientWidth - expectedWidth) >= 1)
failures.push("Expected " + expectedWidth + " for clientWidth, but got " + node.clientWidth + ". ");
}
var expectedHeight = checkAttribute(output, node, "data-expected-client-height");
if (expectedHeight) {
if (isNaN(expectedHeight) || Math.abs(node.clientHeight - expectedHeight) >= 1)
failures.push("Expected " + expectedHeight + " for clientHeight, but got " + node.clientHeight + ". ");
}
var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width");
if (expectedWidth) {
if (isNaN(expectedWidth) || Math.abs(node.scrollWidth - expectedWidth) >= 1)
failures.push("Expected " + expectedWidth + " for scrollWidth, but got " + node.scrollWidth + ". ");
}
var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height");
if (expectedHeight) {
if (isNaN(expectedHeight) || Math.abs(node.scrollHeight - expectedHeight) >= 1)
failures.push("Expected " + expectedHeight + " for scrollHeight, but got " + node.scrollHeight + ". ");
}
var expectedOffset = checkAttribute(output, node, "data-total-x");
if (expectedOffset) {
var totalLeft = node.clientLeft + node.offsetLeft;
if (isNaN(expectedOffset) || Math.abs(totalLeft - expectedOffset) >= 1)
failures.push("Expected " + expectedOffset + " for clientLeft+offsetLeft, but got " + totalLeft + ", clientLeft: " + node.clientLeft + ", offsetLeft: " + node.offsetLeft + ". ");
}
var expectedOffset = checkAttribute(output, node, "data-total-y");
if (expectedOffset) {
var totalTop = node.clientTop + node.offsetTop;
if (isNaN(expectedOffset) || Math.abs(totalTop - expectedOffset) >= 1)
failures.push("Expected " + expectedOffset + " for clientTop+offsetTop, but got " + totalTop + ", clientTop: " + node.clientTop + ", + offsetTop: " + node.offsetTop + ". ");
}
var expectedDisplay = checkAttribute(output, node, "data-expected-display");
if (expectedDisplay) {
var actualDisplay = getComputedStyle(node).display;
if (actualDisplay != expectedDisplay)
failures.push("Expected " + expectedDisplay + " for display, but got " + actualDisplay + ". ");
}
var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top");
if (expectedPaddingTop) {
var actualPaddingTop = getComputedStyle(node).paddingTop;
// Trim the unit "px" from the output.
actualPaddingTop = actualPaddingTop.substring(0, actualPaddingTop.length - 2);
if (actualPaddingTop != expectedPaddingTop)
failures.push("Expected " + expectedPaddingTop + " for padding-top, but got " + actualPaddingTop + ". ");
}
var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom");
if (expectedPaddingBottom) {
var actualPaddingBottom = getComputedStyle(node).paddingBottom;
// Trim the unit "px" from the output.
actualPaddingBottom = actualPaddingBottom.substring(0, actualPaddingBottom.length - 2);
if (actualPaddingBottom != expectedPaddingBottom)
failures.push("Expected " + expectedPaddingBottom + " for padding-bottom, but got " + actualPaddingBottom + ". ");
}
var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left");
if (expectedPaddingLeft) {
var actualPaddingLeft = getComputedStyle(node).paddingLeft;
// Trim the unit "px" from the output.
actualPaddingLeft = actualPaddingLeft.substring(0, actualPaddingLeft.length - 2);
if (actualPaddingLeft != expectedPaddingLeft)
failures.push("Expected " + expectedPaddingLeft + " for padding-left, but got " + actualPaddingLeft + ". ");
}
var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right");
if (expectedPaddingRight) {
var actualPaddingRight = getComputedStyle(node).paddingRight;
// Trim the unit "px" from the output.
actualPaddingRight = actualPaddingRight.substring(0, actualPaddingRight.length - 2);
if (actualPaddingRight != expectedPaddingRight)
failures.push("Expected " + expectedPaddingRight + " for padding-right, but got " + actualPaddingRight + ". ");
}
var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top");
if (expectedMarginTop) {
var actualMarginTop = getComputedStyle(node).marginTop;
// Trim the unit "px" from the output.
actualMarginTop = actualMarginTop.substring(0, actualMarginTop.length - 2);
if (actualMarginTop != expectedMarginTop)
failures.push("Expected " + expectedMarginTop + " for margin-top, but got " + actualMarginTop + ". ");
}
var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom");
if (expectedMarginBottom) {
var actualMarginBottom = getComputedStyle(node).marginBottom;
// Trim the unit "px" from the output.
actualMarginBottom = actualMarginBottom.substring(0, actualMarginBottom.length - 2);
if (actualMarginBottom != expectedMarginBottom)
failures.push("Expected " + expectedMarginBottom + " for margin-bottom, but got " + actualMarginBottom + ". ");
}
var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left");
if (expectedMarginLeft) {
var actualMarginLeft = getComputedStyle(node).marginLeft;
// Trim the unit "px" from the output.
actualMarginLeft = actualMarginLeft.substring(0, actualMarginLeft.length - 2);
if (actualMarginLeft != expectedMarginLeft)
failures.push("Expected " + expectedMarginLeft + " for margin-left, but got " + actualMarginLeft + ". ");
}
var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right");
if (expectedMarginRight) {
var actualMarginRight = getComputedStyle(node).marginRight;
// Trim the unit "px" from the output.
actualMarginRight = actualMarginRight.substring(0, actualMarginRight.length - 2);
if (actualMarginRight != expectedMarginRight)
failures.push("Expected " + expectedMarginRight + " for margin-right, but got " + actualMarginRight + ". ");
}
return output.checked;
}
window.checkLayout = function(selectorList, outputContainer)
{
var result = true;
if (!selectorList) {
document.body.appendChild(document.createTextNode("You must provide a CSS selector of nodes to check."));
return;
}
var nodes = document.querySelectorAll(selectorList);
nodes = Array.prototype.slice.call(nodes);
nodes.reverse();
var checkedLayout = false;
Array.prototype.forEach.call(nodes, function(node) {
var failures = [];
checkedLayout |= checkExpectedValues(node.parentNode, failures);
checkedLayout |= checkSubtreeExpectedValues(node, failures);
var container = node.parentNode.className == 'container' ? node.parentNode : node;
var pre = document.createElement('pre');
if (failures.length) {
pre.className = 'FAIL';
result = false;
}
pre.appendChild(document.createTextNode(failures.length ? "FAIL:\n" + failures.join('\n') + '\n\n' + container.outerHTML : "PASS"));
var referenceNode = container;
if (outputContainer) {
if (!outputContainer.lastChild) {
// Inserting a text node so we have something to insertAfter.
outputContainer.textContent = " ";
}
referenceNode = outputContainer.lastChild;
}
insertAfter(pre, referenceNode);
});
if (!checkedLayout) {
document.body.appendChild(document.createTextNode("FAIL: No valid data-* attributes found in selector list : " + selectorList));
return false;
}
return result;
}
})();

View File

@ -0,0 +1,25 @@
/*
* Polyfill for attaching shadow trees for declarative Shadow DOM for
* implementations that do not support declarative Shadow DOM.
*
* Note: this polyfill will feature-detect the native feature, and do nothing
* if supported.
*
* See: https://github.com/whatwg/html/pull/5465
*
* root: The root of the subtree in which to upgrade shadow roots
*
*/
function polyfill_declarative_shadow_dom(root) {
if (HTMLTemplateElement.prototype.hasOwnProperty('shadowRootMode'))
return;
root.querySelectorAll("template[shadowrootmode]").forEach(template => {
const mode = template.getAttribute("shadowrootmode");
const delegatesFocus = template.hasAttribute("shadowrootdelegatesfocus");
const shadowRoot = template.parentNode.attachShadow({ mode, delegatesFocus });
shadowRoot.appendChild(template.content);
template.remove();
polyfill_declarative_shadow_dom(shadowRoot);
});
}

View File

@ -0,0 +1,61 @@
// TODO: it would be nice to support `idl_array.add_objects`
function fetch_text(url) {
return fetch(url).then(function (r) {
if (!r.ok) {
throw new Error("Error fetching " + url + ".");
}
return r.text();
});
}
/**
* idl_test_shadowrealm is a promise_test wrapper that handles the fetching of the IDL, and
* running the code in a `ShadowRealm`, avoiding repetitive boilerplate.
*
* @see https://github.com/tc39/proposal-shadowrealm
* @param {String[]} srcs Spec name(s) for source idl files (fetched from
* /interfaces/{name}.idl).
* @param {String[]} deps Spec name(s) for dependency idl files (fetched
* from /interfaces/{name}.idl). Order is important - dependencies from
* each source will only be included if they're already know to be a
* dependency (i.e. have already been seen).
*/
function idl_test_shadowrealm(srcs, deps) {
promise_setup(async t => {
const realm = new ShadowRealm();
// https://github.com/web-platform-tests/wpt/issues/31996
realm.evaluate("globalThis.self = globalThis; undefined;");
realm.evaluate(`
globalThis.self.GLOBAL = {
isWindow: function() { return false; },
isWorker: function() { return false; },
isShadowRealm: function() { return true; },
}; undefined;
`);
const specs = await Promise.all(srcs.concat(deps).map(spec => {
return fetch_text("/interfaces/" + spec + ".idl");
}));
const idls = JSON.stringify(specs);
await new Promise(
realm.evaluate(`(resolve,reject) => {
(async () => {
await import("/resources/testharness.js");
await import("/resources/WebIDLParser.js");
await import("/resources/idlharness.js");
const idls = ${idls};
const idl_array = new IdlArray();
for (let i = 0; i < ${srcs.length}; i++) {
idl_array.add_idls(idls[i]);
}
for (let i = ${srcs.length}; i < ${srcs.length + deps.length}; i++) {
idl_array.add_dependency_idls(idls[i]);
}
idl_array.test();
})().then(resolve, (e) => reject(e.toString()));
}`)
);
await fetch_tests_from_shadow_realm(realm);
});
}
// vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker:

3554
test/fixtures/wpt/resources/idlharness.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600

14
test/fixtures/wpt/resources/readme.md vendored Normal file
View File

@ -0,0 +1,14 @@
# Resources
This directory contains utilities intended for use by tests and maintained as project infrastructure.
It does not contain tests.
## `testharness.js`
`testharness.js` is a framework for writing low-level tests of
browser functionality in javascript. It provides a convenient API for
making assertions and is intended to work for both simple synchronous
tests, and tests of asynchronous behaviour.
Complete documentation is available in the `docs/` directory of this repository
and on the web at https://web-platform-tests.org/writing-tests/.

View File

@ -0,0 +1,226 @@
// `integrityValue` indicates the 'integrity' attribute value at the time of
// #prepare-a-script.
//
// `integrityValueAfterPrepare` indicates how the 'integrity' attribute value
// is modified after #prepare-a-script:
// - `undefined` => not modified.
// - `null` => 'integrity' attribute is removed.
// - others => 'integrity' attribute value is set to that value.
//
// TODO: Make the arguments a dictionary for readability in the test files.
var SRIScriptTest = function(pass, name, src, integrityValue, crossoriginValue, nonce, integrityValueAfterPrepare) {
this.pass = pass;
this.name = "Script: " + name;
this.src = src;
this.integrityValue = integrityValue;
this.crossoriginValue = crossoriginValue;
this.nonce = nonce;
this.integrityValueAfterPrepare = integrityValueAfterPrepare;
}
SRIScriptTest.prototype.execute = function() {
var test = async_test(this.name);
var e = document.createElement("script");
e.src = this.src;
if (this.integrityValue) {
e.setAttribute("integrity", this.integrityValue);
}
if(this.crossoriginValue) {
e.setAttribute("crossorigin", this.crossoriginValue);
}
if(this.nonce) {
e.setAttribute("nonce", this.nonce);
}
if(this.pass) {
e.addEventListener("load", function() {test.done()});
e.addEventListener("error", function() {
test.step(function(){ assert_unreached("Good load fired error handler.") })
});
} else {
e.addEventListener("load", function() {
test.step(function() { assert_unreached("Bad load succeeded.") })
});
e.addEventListener("error", function() {test.done()});
}
document.body.appendChild(e);
if (this.integrityValueAfterPrepare === null) {
e.removeAttribute("integrity");
} else if (this.integrityValueAfterPrepare !== undefined) {
e.setAttribute("integrity", this.integrityValueAfterPrepare);
}
};
function set_extra_attributes(element, attrs) {
// Apply the rest of the attributes, if any.
for (const [attr_name, attr_val] of Object.entries(attrs)) {
element[attr_name] = attr_val;
}
}
function buildElementFromDestination(resource_url, destination, attrs) {
// Assert: |destination| is a valid destination.
let element;
// The below switch is responsible for:
// 1. Creating the correct subresource element
// 2. Setting said element's href, src, or fetch-instigating property
// appropriately.
switch (destination) {
case "script":
element = document.createElement(destination);
set_extra_attributes(element, attrs);
element.src = resource_url;
break;
case "style":
element = document.createElement('link');
set_extra_attributes(element, attrs);
element.rel = 'stylesheet';
element.href = resource_url;
break;
case "image":
element = document.createElement('img');
set_extra_attributes(element, attrs);
element.src = resource_url;
break;
default:
assert_unreached("INVALID DESTINATION");
}
return element;
}
// When using SRIPreloadTest, also include /preload/resources/preload_helper.js
// |number_of_requests| is used to ensure that preload requests are actually
// reused as expected.
const SRIPreloadTest = (preload_sri_success, subresource_sri_success, name,
number_of_requests, destination, resource_url,
link_attrs, subresource_attrs) => {
const test = async_test(name);
const link = document.createElement('link');
// Early-fail in UAs that do not support `preload` links.
test.step_func(() => {
assert_true(link.relList.supports('preload'),
"This test is automatically failing because the browser does not" +
"support `preload` links.");
})();
// Build up the link.
link.rel = 'preload';
link.as = destination;
link.href = resource_url;
for (const [attr_name, attr_val] of Object.entries(link_attrs)) {
link[attr_name] = attr_val; // This may override `rel` to modulepreload.
}
// Preload + subresource success and failure loading functions.
const valid_preload_failed = test.step_func(() =>
{ assert_unreached("Valid preload fired error handler.") });
const invalid_preload_succeeded = test.step_func(() =>
{ assert_unreached("Invalid preload load succeeded.") });
const valid_subresource_failed = test.step_func(() =>
{ assert_unreached("Valid subresource fired error handler.") });
const invalid_subresource_succeeded = test.step_func(() =>
{ assert_unreached("Invalid subresource load succeeded.") });
const subresource_pass = test.step_func(() => {
verifyNumberOfResourceTimingEntries(resource_url, number_of_requests);
test.done();
});
const preload_pass = test.step_func(() => {
const subresource_element = buildElementFromDestination(
resource_url,
destination,
subresource_attrs
);
if (subresource_sri_success) {
subresource_element.onload = subresource_pass;
subresource_element.onerror = valid_subresource_failed;
} else {
subresource_element.onload = invalid_subresource_succeeded;
subresource_element.onerror = subresource_pass;
}
document.body.append(subresource_element);
});
if (preload_sri_success) {
link.onload = preload_pass;
link.onerror = valid_preload_failed;
} else {
link.onload = invalid_preload_succeeded;
link.onerror = preload_pass;
}
document.head.append(link);
}
// <link> tests
// Style tests must be done synchronously because they rely on the presence
// and absence of global style, which can affect later tests. Thus, instead
// of executing them one at a time, the style tests are implemented as a
// queue that builds up a list of tests, and then executes them one at a
// time.
var SRIStyleTest = function(queue, pass, name, attrs, customCallback, altPassValue) {
this.pass = pass;
this.name = "Style: " + name;
this.customCallback = customCallback || function () {};
this.attrs = attrs || {};
this.passValue = altPassValue || "rgb(255, 255, 0)";
this.test = async_test(this.name);
this.queue = queue;
this.queue.push(this);
}
SRIStyleTest.prototype.execute = function() {
var that = this;
var container = document.getElementById("container");
while (container.hasChildNodes()) {
container.removeChild(container.firstChild);
}
var test = this.test;
var div = document.createElement("div");
div.className = "testdiv";
var e = document.createElement("link");
// The link relation is guaranteed to not be "preload" or "modulepreload".
this.attrs.rel = this.attrs.rel || "stylesheet";
for (var key in this.attrs) {
if (this.attrs.hasOwnProperty(key)) {
e.setAttribute(key, this.attrs[key]);
}
}
if(this.pass) {
e.addEventListener("load", function() {
test.step(function() {
var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
assert_equals(background, that.passValue);
test.done();
});
});
e.addEventListener("error", function() {
test.step(function(){ assert_unreached("Good load fired error handler.") })
});
} else {
e.addEventListener("load", function() {
test.step(function() { assert_unreached("Bad load succeeded.") })
});
e.addEventListener("error", function() {
test.step(function() {
var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
assert_not_equals(background, that.passValue);
test.done();
});
});
}
container.appendChild(div);
container.appendChild(e);
this.customCallback(e, container);
};

View File

@ -0,0 +1,31 @@
'use strict';
/* Whether the browser is Chromium-based with MojoJS enabled */
const isChromiumBased = 'MojoInterfaceInterceptor' in self;
/* Whether the browser is WebKit-based with internal test-only API enabled */
const isWebKitBased = !isChromiumBased && 'internals' in self;
/**
* Loads a script in a window or worker.
*
* @param {string} path - A script path
* @returns {Promise}
*/
function loadScript(path) {
if (typeof document === 'undefined') {
// Workers (importScripts is synchronous and may throw.)
importScripts(path);
return Promise.resolve();
} else {
// Window
const script = document.createElement('script');
script.src = path;
script.async = false;
const p = new Promise((resolve, reject) => {
script.onload = () => { resolve(); };
script.onerror = e => { reject(`Error loading ${path}`); };
})
document.head.appendChild(script);
return p;
}
}

View File

@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600

View File

@ -0,0 +1,5 @@
/* Whether the browser is Chromium-based with MojoJS enabled */
export const isChromiumBased = 'MojoInterfaceInterceptor' in self;
/* Whether the browser is WebKit-based with internal test-only API enabled */
export const isWebKitBased = !isChromiumBased && 'internals' in self;

View File

@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600

View File

@ -0,0 +1,599 @@
(function() {
let sourceNameIdx = 0;
/**
* @class
* Builder for creating a sequence of actions
*
*
* The actions are dispatched once
* :js:func:`test_driver.Actions.send` is called. This returns a
* promise which resolves once the actions are complete.
*
* The other methods on :js:class:`test_driver.Actions` object are
* used to build the sequence of actions that will be sent. These
* return the `Actions` object itself, so the actions sequence can
* be constructed by chaining method calls.
*
* Internally :js:func:`test_driver.Actions.send` invokes
* :js:func:`test_driver.action_sequence`.
*
* @example
* let text_box = document.getElementById("text");
*
* let actions = new test_driver.Actions()
* .pointerMove(0, 0, {origin: text_box})
* .pointerDown()
* .pointerUp()
* .addTick()
* .keyDown("p")
* .keyUp("p");
*
* await actions.send();
*
* @param {number} [defaultTickDuration] - The default duration of a
* tick. Be default this is set to 16ms, which is one frame time
* based on 60Hz display.
*/
function Actions(defaultTickDuration=16) {
this.sourceTypes = new Map([["key", KeySource],
["pointer", PointerSource],
["wheel", WheelSource],
["none", GeneralSource]]);
this.sources = new Map();
this.sourceOrder = [];
for (let sourceType of this.sourceTypes.keys()) {
this.sources.set(sourceType, new Map());
}
this.currentSources = new Map();
for (let sourceType of this.sourceTypes.keys()) {
this.currentSources.set(sourceType, null);
}
this.createSource("none");
this.tickIdx = 0;
this.defaultTickDuration = defaultTickDuration;
this.context = null;
}
Actions.prototype = {
ButtonType: {
LEFT: 0,
MIDDLE: 1,
RIGHT: 2,
BACK: 3,
FORWARD: 4,
},
/**
* Generate the action sequence suitable for passing to
* test_driver.action_sequence
*
* @returns {Array} Array of WebDriver-compatible actions sequences
*/
serialize: function() {
let actions = [];
for (let [sourceType, sourceName] of this.sourceOrder) {
let source = this.sources.get(sourceType).get(sourceName);
let serialized = source.serialize(this.tickIdx + 1, this.defaultTickDuration);
if (serialized) {
serialized.id = sourceName;
actions.push(serialized);
}
}
return actions;
},
/**
* Generate and send the action sequence
*
* @returns {Promise} fulfilled after the sequence is executed,
* rejected if any actions fail.
*/
send: function() {
let actions;
try {
actions = this.serialize();
} catch(e) {
return Promise.reject(e);
}
return test_driver.action_sequence(actions, this.context);
},
/**
* Set the context for the actions
*
* @param {WindowProxy} context - Context in which to run the action sequence
*/
setContext: function(context) {
this.context = context;
return this;
},
/**
* Get the action source with a particular source type and name.
* If no name is passed, a new source with the given type is
* created.
*
* @param {String} type - Source type ('none', 'key', 'pointer', or 'wheel')
* @param {String?} name - Name of the source
* @returns {Source} Source object for that source.
*/
getSource: function(type, name) {
if (!this.sources.has(type)) {
throw new Error(`${type} is not a valid action type`);
}
if (name === null || name === undefined) {
name = this.currentSources.get(type);
}
if (name === null || name === undefined) {
return this.createSource(type, null);
}
return this.sources.get(type).get(name);
},
setSource: function(type, name) {
if (!this.sources.has(type)) {
throw new Error(`${type} is not a valid action type`);
}
if (!this.sources.get(type).has(name)) {
throw new Error(`${name} is not a valid source for ${type}`);
}
this.currentSources.set(type, name);
return this;
},
/**
* Add a new key input source with the given name
*
* @param {String} name - Name of the key source
* @param {Bool} set - Set source as the default key source
* @returns {Actions}
*/
addKeyboard: function(name, set=true) {
this.createSource("key", name);
if (set) {
this.setKeyboard(name);
}
return this;
},
/**
* Set the current default key source
*
* @param {String} name - Name of the key source
* @returns {Actions}
*/
setKeyboard: function(name) {
this.setSource("key", name);
return this;
},
/**
* Add a new pointer input source with the given name
*
* @param {String} type - Name of the pointer source
* @param {String} pointerType - Type of pointing device
* @param {Bool} set - Set source as the default pointer source
* @returns {Actions}
*/
addPointer: function(name, pointerType="mouse", set=true) {
this.createSource("pointer", name, {pointerType: pointerType});
if (set) {
this.setPointer(name);
}
return this;
},
/**
* Set the current default pointer source
*
* @param {String} name - Name of the pointer source
* @returns {Actions}
*/
setPointer: function(name) {
this.setSource("pointer", name);
return this;
},
/**
* Add a new wheel input source with the given name
*
* @param {String} type - Name of the wheel source
* @param {Bool} set - Set source as the default wheel source
* @returns {Actions}
*/
addWheel: function(name, set=true) {
this.createSource("wheel", name);
if (set) {
this.setWheel(name);
}
return this;
},
/**
* Set the current default wheel source
*
* @param {String} name - Name of the wheel source
* @returns {Actions}
*/
setWheel: function(name) {
this.setSource("wheel", name);
return this;
},
createSource: function(type, name, parameters={}) {
if (!this.sources.has(type)) {
throw new Error(`${type} is not a valid action type`);
}
let sourceNames = new Set();
for (let [_, name] of this.sourceOrder) {
sourceNames.add(name);
}
if (!name) {
do {
name = "" + sourceNameIdx++;
} while (sourceNames.has(name))
} else {
if (sourceNames.has(name)) {
throw new Error(`Alreay have a source of type ${type} named ${name}.`);
}
}
this.sources.get(type).set(name, new (this.sourceTypes.get(type))(parameters));
this.currentSources.set(type, name);
this.sourceOrder.push([type, name]);
return this.sources.get(type).get(name);
},
/**
* Insert a new actions tick
*
* @param {Number?} duration - Minimum length of the tick in ms.
* @returns {Actions}
*/
addTick: function(duration) {
this.tickIdx += 1;
if (duration) {
this.pause(duration);
}
return this;
},
/**
* Add a pause to the current tick
*
* @param {Number?} duration - Minimum length of the tick in ms.
* @param {String} sourceType - source type
* @param {String?} sourceName - Named key, pointer or wheel source to use
* or null for the default key, pointer or
* wheel source
* @returns {Actions}
*/
pause: function(duration=0, sourceType="none", {sourceName=null}={}) {
if (sourceType=="none")
this.getSource("none").addPause(this, duration);
else
this.getSource(sourceType, sourceName).addPause(this, duration);
return this;
},
/**
* Create a keyDown event for the current default key source
*
* @param {String} key - Key to press
* @param {String?} sourceName - Named key source to use or null for the default key source
* @returns {Actions}
*/
keyDown: function(key, {sourceName=null}={}) {
let source = this.getSource("key", sourceName);
source.keyDown(this, key);
return this;
},
/**
* Create a keyDown event for the current default key source
*
* @param {String} key - Key to release
* @param {String?} sourceName - Named key source to use or null for the default key source
* @returns {Actions}
*/
keyUp: function(key, {sourceName=null}={}) {
let source = this.getSource("key", sourceName);
source.keyUp(this, key);
return this;
},
/**
* Create a pointerDown event for the current default pointer source
*
* @param {String} button - Button to press
* @param {String?} sourceName - Named pointer source to use or null for the default
* pointer source
* @returns {Actions}
*/
pointerDown: function({button=this.ButtonType.LEFT, sourceName=null,
width, height, pressure, tangentialPressure,
tiltX, tiltY, twist, altitudeAngle, azimuthAngle}={}) {
let source = this.getSource("pointer", sourceName);
source.pointerDown(this, button, width, height, pressure, tangentialPressure,
tiltX, tiltY, twist, altitudeAngle, azimuthAngle);
return this;
},
/**
* Create a pointerUp event for the current default pointer source
*
* @param {String} button - Button to release
* @param {String?} sourceName - Named pointer source to use or null for the default pointer
* source
* @returns {Actions}
*/
pointerUp: function({button=this.ButtonType.LEFT, sourceName=null}={}) {
let source = this.getSource("pointer", sourceName);
source.pointerUp(this, button);
return this;
},
/**
* Create a move event for the current default pointer source
*
* @param {Number} x - Destination x coordinate
* @param {Number} y - Destination y coordinate
* @param {String|Element} origin - Origin of the coordinate system.
* Either "pointer", "viewport" or an Element
* @param {Number?} duration - Time in ms for the move
* @param {String?} sourceName - Named pointer source to use or null for the default pointer
* source
* @returns {Actions}
*/
pointerMove: function(x, y,
{origin="viewport", duration, sourceName=null,
width, height, pressure, tangentialPressure,
tiltX, tiltY, twist, altitudeAngle, azimuthAngle}={}) {
let source = this.getSource("pointer", sourceName);
source.pointerMove(this, x, y, duration, origin, width, height, pressure,
tangentialPressure, tiltX, tiltY, twist, altitudeAngle,
azimuthAngle);
return this;
},
/**
* Create a scroll event for the current default wheel source
*
* @param {Number} x - mouse cursor x coordinate
* @param {Number} y - mouse cursor y coordinate
* @param {Number} deltaX - scroll delta value along the x-axis in pixels
* @param {Number} deltaY - scroll delta value along the y-axis in pixels
* @param {String|Element} origin - Origin of the coordinate system.
* Either "viewport" or an Element
* @param {Number?} duration - Time in ms for the scroll
* @param {String?} sourceName - Named wheel source to use or null for the
* default wheel source
* @returns {Actions}
*/
scroll: function(x, y, deltaX, deltaY,
{origin="viewport", duration, sourceName=null}={}) {
let source = this.getSource("wheel", sourceName);
source.scroll(this, x, y, deltaX, deltaY, duration, origin);
return this;
},
};
function GeneralSource() {
this.actions = new Map();
}
GeneralSource.prototype = {
serialize: function(tickCount, defaultTickDuration) {
let actions = [];
let data = {"type": "none", "actions": actions};
for (let i=0; i<tickCount; i++) {
if (this.actions.has(i)) {
actions.push(this.actions.get(i));
} else {
actions.push({"type": "pause", duration: defaultTickDuration});
}
}
return data;
},
addPause: function(actions, duration) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
throw new Error(`Already have a pause action for the current tick`);
}
this.actions.set(tick, {type: "pause", duration: duration});
},
};
function KeySource() {
this.actions = new Map();
}
KeySource.prototype = {
serialize: function(tickCount) {
if (!this.actions.size) {
return undefined;
}
let actions = [];
let data = {"type": "key", "actions": actions};
for (let i=0; i<tickCount; i++) {
if (this.actions.has(i)) {
actions.push(this.actions.get(i));
} else {
actions.push({"type": "pause"});
}
}
return data;
},
keyDown: function(actions, key) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "keyDown", value: key});
},
keyUp: function(actions, key) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "keyUp", value: key});
},
addPause: function(actions, duration) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "pause", duration: duration});
},
};
function PointerSource(parameters={pointerType: "mouse"}) {
let pointerType = parameters.pointerType || "mouse";
if (!["mouse", "pen", "touch"].includes(pointerType)) {
throw new Error(`Invalid pointerType ${pointerType}`);
}
this.type = pointerType;
this.actions = new Map();
}
function setPointerProperties(action, width, height, pressure, tangentialPressure,
tiltX, tiltY, twist, altitudeAngle, azimuthAngle) {
if (width) {
action.width = width;
}
if (height) {
action.height = height;
}
if (pressure) {
action.pressure = pressure;
}
if (tangentialPressure) {
action.tangentialPressure = tangentialPressure;
}
if (tiltX) {
action.tiltX = tiltX;
}
if (tiltY) {
action.tiltY = tiltY;
}
if (twist) {
action.twist = twist;
}
if (altitudeAngle) {
action.altitudeAngle = altitudeAngle;
}
if (azimuthAngle) {
action.azimuthAngle = azimuthAngle;
}
return action;
}
PointerSource.prototype = {
serialize: function(tickCount) {
if (!this.actions.size) {
return undefined;
}
let actions = [];
let data = {"type": "pointer", "actions": actions, "parameters": {"pointerType": this.type}};
for (let i=0; i<tickCount; i++) {
if (this.actions.has(i)) {
actions.push(this.actions.get(i));
} else {
actions.push({"type": "pause"});
}
}
return data;
},
pointerDown: function(actions, button, width, height, pressure, tangentialPressure,
tiltX, tiltY, twist, altitudeAngle, azimuthAngle) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
let actionProperties = setPointerProperties({type: "pointerDown", button}, width, height,
pressure, tangentialPressure, tiltX, tiltY,
twist, altitudeAngle, azimuthAngle);
this.actions.set(tick, actionProperties);
},
pointerUp: function(actions, button) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "pointerUp", button});
},
pointerMove: function(actions, x, y, duration, origin, width, height, pressure,
tangentialPressure, tiltX, tiltY, twist, altitudeAngle, azimuthAngle) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
let moveAction = {type: "pointerMove", x, y, origin};
if (duration) {
moveAction.duration = duration;
}
let actionProperties = setPointerProperties(moveAction, width, height, pressure,
tangentialPressure, tiltX, tiltY, twist,
altitudeAngle, azimuthAngle);
this.actions.set(tick, actionProperties);
},
addPause: function(actions, duration) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "pause", duration: duration});
},
};
function WheelSource() {
this.actions = new Map();
}
WheelSource.prototype = {
serialize: function(tickCount) {
if (!this.actions.size) {
return undefined;
}
let actions = [];
let data = {"type": "wheel", "actions": actions};
for (let i=0; i<tickCount; i++) {
if (this.actions.has(i)) {
actions.push(this.actions.get(i));
} else {
actions.push({"type": "pause"});
}
}
return data;
},
scroll: function(actions, x, y, deltaX, deltaY, duration, origin) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "scroll", x, y, deltaX, deltaY, origin});
if (duration) {
this.actions.get(tick).duration = duration;
}
},
addPause: function(actions, duration) {
let tick = actions.tickIdx;
if (this.actions.has(tick)) {
tick = actions.addTick().tickIdx;
}
this.actions.set(tick, {type: "pause", duration: duration});
},
};
test_driver.Actions = Actions;
})();

View File

View File

@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600

1145
test/fixtures/wpt/resources/testdriver.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600

4941
test/fixtures/wpt/resources/testharness.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600

View File

@ -0,0 +1,57 @@
/* global add_completion_callback */
/* global setup */
/*
* This file is intended for vendors to implement code needed to integrate
* testharness.js tests with their own test systems.
*
* Typically test system integration will attach callbacks when each test has
* run, using add_result_callback(callback(test)), or when the whole test file
* has completed, using
* add_completion_callback(callback(tests, harness_status)).
*
* For more documentation about the callback functions and the
* parameters they are called with see testharness.js
*/
function dump_test_results(tests, status) {
var results_element = document.createElement("script");
results_element.type = "text/json";
results_element.id = "__testharness__results__";
var test_results = tests.map(function(x) {
return {name:x.name, status:x.status, message:x.message, stack:x.stack}
});
var data = {test:window.location.href,
tests:test_results,
status: status.status,
message: status.message,
stack: status.stack};
results_element.textContent = JSON.stringify(data);
// To avoid a HierarchyRequestError with XML documents, ensure that 'results_element'
// is inserted at a location that results in a valid document.
var parent = document.body
? document.body // <body> is required in XHTML documents
: document.documentElement; // fallback for optional <body> in HTML5, SVG, etc.
parent.appendChild(results_element);
}
add_completion_callback(dump_test_results);
/* If the parent window has a testharness_properties object,
* we use this to provide the test settings. This is used by the
* default in-browser runner to configure the timeout and the
* rendering of results
*/
try {
if (window.opener && "testharness_properties" in window.opener) {
/* If we pass the testharness_properties object as-is here without
* JSON stringifying and reparsing it, IE fails & emits the message
* "Could not complete the operation due to error 80700019".
*/
setup(JSON.parse(JSON.stringify(window.opener.testharness_properties)));
}
} catch (e) {
}
// vim: set expandtab shiftwidth=4 tabstop=4:

View File

@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600

View File

@ -0,0 +1,12 @@
set -ex
if [ ! -d "webidl2.js" ]; then
git clone https://github.com/w3c/webidl2.js.git
fi
cd webidl2.js
npm install
npm run build-debug
HASH=$(git rev-parse HEAD)
cd ..
cp webidl2.js/dist/webidl2.js lib/
echo "Currently using webidl2.js@${HASH}." > lib/VERSION.md

View File

@ -0,0 +1,4 @@
This directory contains a built version of the [webidl2.js library](https://github.com/w3c/webidl2.js).
It is built by running `npm run build-debug` at the root of that repository.
The `webidl2.js.headers` file is a local addition to ensure the script is interpreted as UTF-8.

View File

@ -0,0 +1 @@
Currently using webidl2.js@6889aee6fc7d65915ab1267825248157dbc50486.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
Content-Type: text/javascript; charset=utf-8