233 lines
7 KiB
HTML
233 lines
7 KiB
HTML
<!doctype html>
|
|
<meta charset=utf-8>
|
|
<title>Test handling of attributes that map to dimension properties</title>
|
|
<meta name="timeout" content="long">
|
|
<link rel="help"
|
|
href="https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-dimension-property">
|
|
<link rel="help"
|
|
href="https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-dimension-property-(ignoring-zero)">
|
|
<script src=/resources/testharness.js></script>
|
|
<script src=/resources/testharnessreport.js></script>
|
|
<body>
|
|
<!-- We need a place to put our elements so they're bound to a document and
|
|
have computed style, but we don't want percentages resolved to lengths,
|
|
so need to make sure they have no CSS boxes -->
|
|
<div id="container" style="display: none"></div>
|
|
<script>
|
|
/*
|
|
* This test tests
|
|
*
|
|
* https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-dimension-property
|
|
* and
|
|
* https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-dimension-property-(ignoring-zero)
|
|
* for various elements and various values.
|
|
*/
|
|
|
|
/*
|
|
* Array of input/output pairs. The input is the string to use as the
|
|
* attribute value. The output is the string expected as the computed style
|
|
* for the relevant CSS property.
|
|
*/
|
|
const valid_values = [
|
|
// Valid values
|
|
[ "200", "200px" ],
|
|
[ "1007", "1007px" ],
|
|
[ " 00523 ", "523px" ],
|
|
[ "200.25", "200.25px" ],
|
|
[ "200.7", "200.7px" ],
|
|
[ "200.", "200px" ],
|
|
[ "200in", "200px" ],
|
|
[ "200.25in", "200.25px" ],
|
|
[ "200 %", "200px" ],
|
|
[ "200 abc", "200px" ],
|
|
[ "200%", "200%" ],
|
|
[ "200%abc", "200%" ],
|
|
[ "200.25%", "200.25%" ],
|
|
[ "200.%", "200%" ],
|
|
[ "20.25e2", "20.25px" ],
|
|
[ "20.25E2", "20.25px" ],
|
|
];
|
|
|
|
/*
|
|
* Values that are only valid for the not-ignoring-zero case.
|
|
*/
|
|
const zero_values = [
|
|
[ "0", "0px" ],
|
|
[ "0%", "0%" ],
|
|
[ "0px", "0px" ],
|
|
];
|
|
|
|
/*
|
|
* Array of invalid values. These should lead to the default value of the
|
|
* relevant CSS property.
|
|
*/
|
|
const invalid_values = [
|
|
"-0",
|
|
"-0%",
|
|
"-200",
|
|
"-200px",
|
|
" -200",
|
|
"+-200",
|
|
"-+200",
|
|
"-200%",
|
|
"+200",
|
|
" +200in ",
|
|
" +200.25in ",
|
|
"+200%",
|
|
" +200.25% ",
|
|
" +200.25%abc",
|
|
"+0",
|
|
"+0%",
|
|
".",
|
|
".%",
|
|
".x",
|
|
".5",
|
|
".5%"
|
|
];
|
|
|
|
const valid_values_with_0 =
|
|
valid_values.concat(zero_values);
|
|
const invalid_values_with_0 =
|
|
invalid_values.concat(zero_values.map((v) => v[0]));
|
|
|
|
function newElem(name) {
|
|
return () => document.createElement(name);
|
|
}
|
|
|
|
function newImageInput() {
|
|
return () => {
|
|
var elem = newElem("input")();
|
|
elem.type = "image";
|
|
return elem;
|
|
}
|
|
}
|
|
|
|
function newImgSource() {
|
|
return () => {
|
|
var elem = newElem("source")();
|
|
elem.setAttribute("srcset", "/images/green-100x50.png");
|
|
return elem;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Array of tests. Each test consists of the following information:
|
|
*
|
|
* 1) An element creation function.
|
|
* 2) The name of the attribute to set
|
|
* 3) The name of the CSS property to get.
|
|
* 4) A boolean indicating whether 0 is a valid value for the dimension
|
|
* attribute.
|
|
*/
|
|
const tests = [
|
|
[ newElem("hr"), "width", "width", true ],
|
|
[ newElem("iframe"), "width", "width", true ],
|
|
[ newElem("iframe"), "height", "height", true ],
|
|
[ newImageInput(), "width", "width", true ],
|
|
[ newImageInput(), "height", "height", true ],
|
|
[ newElem("marquee"), "width", "width", true ],
|
|
[ newElem("marquee"), "height", "height", true ],
|
|
[ newElem("video"), "width", "width", true ],
|
|
[ newElem("video"), "height", "height", true ],
|
|
[ newElem("object"), "width", "width", true ],
|
|
[ newElem("object"), "height", "height", true ],
|
|
[ newElem("embed"), "width", "width", true ],
|
|
[ newElem("embed"), "height", "height", true ],
|
|
[ newElem("img"), "width", "width", true ],
|
|
[ newElem("img"), "height", "height", true ],
|
|
[ newElem("td"), "width", "width", false ],
|
|
[ newElem("td"), "height", "height", false ],
|
|
[ newElem("table"), "width", "width", false ],
|
|
[ newElem("table"), "height", "height", true ],
|
|
[ newElem("tr"), "height", "height", true ],
|
|
[ newElem("col"), "width", "width", true ],
|
|
[ newElem("embed"), "hspace", "marginLeft", true ],
|
|
[ newElem("embed"), "hspace", "marginRight", true ],
|
|
[ newElem("embed"), "vspace", "marginTop", true ],
|
|
[ newElem("embed"), "vspace", "marginBottom", true ],
|
|
[ newElem("img"), "hspace", "marginLeft", true ],
|
|
[ newElem("img"), "hspace", "marginRight", true ],
|
|
[ newElem("img"), "vspace", "marginTop", true ],
|
|
[ newElem("img"), "vspace", "marginBottom", true ],
|
|
[ newElem("object"), "hspace", "marginLeft", true ],
|
|
[ newElem("object"), "hspace", "marginRight", true ],
|
|
[ newElem("object"), "vspace", "marginTop", true ],
|
|
[ newElem("object"), "vspace", "marginBottom", true ],
|
|
[ newImageInput(), "hspace", "marginLeft", true ],
|
|
[ newImageInput(), "hspace", "marginRight", true ],
|
|
[ newImageInput(), "vspace", "marginTop", true ],
|
|
[ newImageInput(), "vspace", "marginBottom", true ],
|
|
[ newElem("marquee"), "hspace", "marginLeft", true ],
|
|
[ newElem("marquee"), "hspace", "marginRight", true ],
|
|
[ newElem("marquee"), "vspace", "marginTop", true ],
|
|
[ newElem("marquee"), "vspace", "marginBottom", true ],
|
|
// <source width> is mapped to <img> width if both are in <picture>.
|
|
[ newImgSource(), "width", "width", true, newElem("img"), newElem("picture") ],
|
|
// <source height> is mapped to <img> height if both are in <picture>.
|
|
[ newImgSource(), "height", "height", true, newElem("img"), newElem("picture") ],
|
|
];
|
|
|
|
function style(element) {
|
|
return element.ownerDocument.defaultView.getComputedStyle(element);
|
|
}
|
|
|
|
const container = document.getElementById("container");
|
|
|
|
for (let [ctor, attr, prop, zero_allowed, mappedElemCtor, containerCtor] of tests) {
|
|
let valid, invalid;
|
|
if (zero_allowed) {
|
|
valid = valid_values_with_0;
|
|
invalid = invalid_values;
|
|
} else {
|
|
valid = valid_values;
|
|
invalid = invalid_values_with_0;
|
|
}
|
|
|
|
let elemContainer = null;
|
|
if (!!containerCtor) {
|
|
elemContainer = containerCtor();
|
|
container.appendChild(elemContainer);
|
|
} else {
|
|
elemContainer = container;
|
|
}
|
|
|
|
let runTest = (value, expected) => {
|
|
let elem = ctor();
|
|
let mappedElem = !!mappedElemCtor ? mappedElemCtor() : elem;
|
|
test(function() {
|
|
this.add_cleanup(() => {
|
|
elem.remove();
|
|
if (!!mappedElemCtor) {
|
|
mappedElem.remove();
|
|
}
|
|
});
|
|
elem.setAttribute(attr, value);
|
|
assert_equals(elem.getAttribute(attr), value);
|
|
elemContainer.appendChild(elem);
|
|
if (!!mappedElemCtor) {
|
|
elemContainer.appendChild(mappedElem);
|
|
}
|
|
assert_equals(style(mappedElem)[prop], expected);
|
|
}, `<${elem.localName} ${attr}="${value}"> mapping to ` +
|
|
`<${mappedElem.localName}> ${prop} property`);
|
|
}
|
|
|
|
for (let [value, result] of valid) {
|
|
runTest(value, result);
|
|
}
|
|
|
|
let default_elem = !!mappedElemCtor ? mappedElemCtor() : ctor();
|
|
elemContainer.appendChild(default_elem);
|
|
let defaultVal = style(default_elem)[prop];
|
|
default_elem.remove();
|
|
for (let value of invalid) {
|
|
runTest(value, defaultVal);
|
|
}
|
|
|
|
if (!!containerCtor) {
|
|
elemContainer.remove();
|
|
}
|
|
}
|
|
|
|
</script>
|
|
</body>
|