| <!doctype html> |
| <meta charset=utf-8> |
| <title>Test handling of attributes that map to dimension properties</title> |
| <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; |
| } |
| } |
| |
| /* |
| * 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 ], |
| // https://github.com/whatwg/html/issues/4715 tracks the fact that for |
| // <table width> and <table height> the "0 is valid" boolean should probably |
| // be true. |
| [ newElem("table"), "width", "width", false ], |
| [ newElem("table"), "height", "height", false ], |
| // https://github.com/whatwg/html/issues/4716 tracks the fact that for the |
| // <tr height> case that "0 is valid" boolean should probably be true. |
| [ newElem("tr"), "height", "height", false ], |
| // https://github.com/whatwg/html/issues/4717 tracks the fact that for the |
| // <col width> case that "0 is valid" boolean should probably be true. |
| [ newElem("col"), "width", "width", false ], |
| [ 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 ], |
| ]; |
| |
| |
| function style(element) { |
| return element.ownerDocument.defaultView.getComputedStyle(element); |
| } |
| |
| const container = document.getElementById("container"); |
| |
| for (let [ctor, attr, prop, zero_allowed] 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; |
| } |
| for (let [value, result] of valid) { |
| let elem = ctor(); |
| test(function() { |
| this.add_cleanup(() => elem.remove()); |
| elem.setAttribute(attr, value); |
| assert_equals(elem.getAttribute(attr), value); |
| container.appendChild(elem); |
| assert_equals(style(elem)[prop], result); |
| }, `<${elem.localName} ${attr}="${value}"> mapping to ${prop}`); |
| } |
| |
| let default_elem = ctor(); |
| container.appendChild(default_elem); |
| let defaultVal = style(default_elem)[prop]; |
| default_elem.remove(); |
| for (let value of invalid) { |
| let elem = ctor(); |
| test(function() { |
| this.add_cleanup(() => elem.remove()); |
| elem.setAttribute(attr, value); |
| assert_equals(elem.getAttribute(attr), value); |
| container.appendChild(elem); |
| assert_equals(style(elem)[prop], defaultVal); |
| }, `<${elem.localName} ${attr}="${value}"> mapping to ${prop}`); |
| } |
| } |
| </script> |
| </body> |