diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /testing/web-platform/tests/mathml | |
parent | Initial commit. (diff) | |
download | firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/mathml')
580 files changed, 36168 insertions, 0 deletions
diff --git a/testing/web-platform/tests/mathml/META.yml b/testing/web-platform/tests/mathml/META.yml new file mode 100644 index 0000000000..ee5c81bfb6 --- /dev/null +++ b/testing/web-platform/tests/mathml/META.yml @@ -0,0 +1,3 @@ +spec: https://w3c.github.io/mathml-core/ +suggested_reviewers: + - fred-wang diff --git a/testing/web-platform/tests/mathml/README.md b/testing/web-platform/tests/mathml/README.md new file mode 100644 index 0000000000..4511b3e7df --- /dev/null +++ b/testing/web-platform/tests/mathml/README.md @@ -0,0 +1,12 @@ +# Tests for the MathML Core specification + +This directory contains tests for the +[MathML Core specification](https://w3c.github.io/mathml-core/). +Many of the tests verify OpenType features and require specific Web fonts for +that purpose. WOFF fonts are generated by scripts in the `tools/` folder using +the Python API of +[fontforge](https://github.com/fontforge/fontforge/). A recent enough version +of FontForge is necessary so that it includes fixes for +[WOFF checkSumAdjustment](https://github.com/fontforge/fontforge/issues/926), +[USE_TYPO_METRICS flag](https://github.com/fontforge/fontforge/pull/2274) and +for other various bugs. diff --git a/testing/web-platform/tests/mathml/crashtests/children-with-negative-block-sizes.html b/testing/web-platform/tests/mathml/crashtests/children-with-negative-block-sizes.html new file mode 100644 index 0000000000..c50f9be153 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/children-with-negative-block-sizes.html @@ -0,0 +1,142 @@ +<!DOCTYPE html> +<style> + /* These are children with negative block sizes. Absolute values are chosen + large enough compared to math layout constants. */ + span { display: inline-block; } + mspace, span { + margin-block-start: -10em; + margin-block-end: -10em; + } + /* Override display: none; from UA style sheet for the following children. */ + maction > :not(:first-child), + semantics > annotation, + semantics > annotation-xml { + display: math; + } +</style> +<math> + <mi><span></span></mi> + <mn><span></span></mn> + <mo><span></span></mo> + <ms><span></span></ms> + <mtext><span></span></mtext> +</math> +<math> + <semantics> + <mspace/> + <annotation><span></span></annotation> + <annotation-xml><span></span></annotation-xml> + </semantics> +</math> +<math> + <mtable> + <mtr> + <mtd><mspace/></mtd> + <mtd><mspace/></mtd> + <mtd><mspace/></mtd> + </mtr> + <mtr> + <mtd><mspace/></mtd> + <mtd><mspace/></mtd> + <mtd><mspace/></mtd> + </mtr> + </mtable> +</math> +<math> + <mspace/> + <mspace/> + <mspace/> + <mspace/> +</math> +<math> + <maction> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </maction> + <merror> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </merror> + <mpadded> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </mpadded> + <mphantom> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </mphantom> + <mstyle> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </mstyle> +</math> +<math> + <mfrac> + <mspace/> + <mspace/> + </mfrac> + <mfrac linethickness="0"> + <mspace/> + <mspace/> + </mfrac> +</math> +<math> + <msqrt> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </msqrt> + <mroot> + <mspace/> + <mspace/> + </mroot> +</math> +<math> + <msup> + <mspace/> + <mspace/> + </msup> + <msub> + <mspace/> + <mspace/> + </msub> + <msubsup> + <mspace/> + <mspace/> + <mspace/> + </msubsup> + <mmultiscripts> + <mspace/> + <mspace/> + <mspace/> + <mprescripts/> + <mspace/> + <mspace/> + </mmultiscripts> +</math> +<math> + <mover> + <mspace/> + <mspace/> + </mover> + <munder> + <mspace/> + <mspace/> + </munder> + <munderover> + <mspace/> + <mspace/> + <mspace/> + </munderover> +</math> diff --git a/testing/web-platform/tests/mathml/crashtests/children-with-negative-inline-sizes.html b/testing/web-platform/tests/mathml/crashtests/children-with-negative-inline-sizes.html new file mode 100644 index 0000000000..5c41fc8969 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/children-with-negative-inline-sizes.html @@ -0,0 +1,142 @@ +<!DOCTYPE html> +<style> + /* These are children with negative block sizes. Absolute values are chosen + large enough compared to math layout constants. */ + span { display: inline-block; } + mspace, span { + margin-inline-start: -10em; + margin-inline-end: -10em; + } + /* Override display: none; from UA style sheet for the following children. */ + maction > :not(:first-child), + semantics > annotation, + semantics > annotation-xml { + display: math; + } +</style> +<math> + <mi><span></span></mi> + <mn><span></span></mn> + <mo><span></span></mo> + <ms><span></span></ms> + <mtext><span></span></mtext> +</math> +<math> + <semantics> + <mspace/> + <annotation><span></span></annotation> + <annotation-xml><span></span></annotation-xml> + </semantics> +</math> +<math> + <mtable> + <mtr> + <mtd><mspace/></mtd> + <mtd><mspace/></mtd> + <mtd><mspace/></mtd> + </mtr> + <mtr> + <mtd><mspace/></mtd> + <mtd><mspace/></mtd> + <mtd><mspace/></mtd> + </mtr> + </mtable> +</math> +<math> + <mspace/> + <mspace/> + <mspace/> + <mspace/> +</math> +<math> + <maction> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </maction> + <merror> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </merror> + <mpadded> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </mpadded> + <mphantom> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </mphantom> + <mstyle> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </mstyle> +</math> +<math> + <mfrac> + <mspace/> + <mspace/> + </mfrac> + <mfrac linethickness="0"> + <mspace/> + <mspace/> + </mfrac> +</math> +<math> + <msqrt> + <mspace/> + <mspace/> + <mspace/> + <mspace/> + </msqrt> + <mroot> + <mspace/> + <mspace/> + </mroot> +</math> +<math> + <msup> + <mspace/> + <mspace/> + </msup> + <msub> + <mspace/> + <mspace/> + </msub> + <msubsup> + <mspace/> + <mspace/> + <mspace/> + </msubsup> + <mmultiscripts> + <mspace/> + <mspace/> + <mspace/> + <mprescripts/> + <mspace/> + <mspace/> + </mmultiscripts> +</math> +<math> + <mover> + <mspace/> + <mspace/> + </mover> + <munder> + <mspace/> + <mspace/> + </munder> + <munderover> + <mspace/> + <mspace/> + <mspace/> + </munderover> +</math> diff --git a/testing/web-platform/tests/mathml/crashtests/chrome-bug-1287843.html b/testing/web-platform/tests/mathml/crashtests/chrome-bug-1287843.html new file mode 100644 index 0000000000..6fc95fc12e --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/chrome-bug-1287843.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1287843"> +<div style="columns:2;"> + <math> + <mtd> + <mtable> + <mtr></mtr> + </mtable> + </mtd> + </math> +</div> diff --git a/testing/web-platform/tests/mathml/crashtests/display-and-column-properties.html b/testing/web-platform/tests/mathml/crashtests/display-and-column-properties.html new file mode 100644 index 0000000000..c40a2a0549 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/display-and-column-properties.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html class="test-wait"> + <head> + <title>MathML elements with display and column properties</title> + <meta charset="utf-8"/> + <style> + math { + column-width: 100px; + } + </style> + </head> + <body> + <math></math> + <math style="display: list-item"></math> + <script> + window.addEventListener("load", function() { + // Force initial layout. + document.documentElement.getBoundingClientRect(); + + // Change display and reforce layout. + let maths = document.getElementsByTagName("math"); + maths[0].setAttribute("style", "display: list-item"); + maths[1].removeAttribute("style"); + document.documentElement.getBoundingClientRect(); + + document.documentElement.classList.remove("test-wait"); + }); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/dynamic-height-within-table-cell.html b/testing/web-platform/tests/mathml/crashtests/dynamic-height-within-table-cell.html new file mode 100644 index 0000000000..cf42101bc8 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/dynamic-height-within-table-cell.html @@ -0,0 +1,33 @@ +<!DOCTYPE> +<html class="test-wait"> + <head> + <title>Dynamic height within table cell</title> + <meta charset="utf-8"/> + <link rel="author" title="Frédéric Wang" href="mailto:fwang@igalia.com"> + <link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1254572"> + <style> + #cell { + position: relative; + } + #elementToResize { + position: absolute; + height: 50px; + } + </style> + </head> + <body> + <math> + <mtd id="cell"> + <mrow id="elementToResize"></mrow> + </mtd> + </math> + <script> + window.addEventListener("load", () => { + window.requestAnimationFrame(() => { + elementToResize.style.height = "0px"; + document.documentElement.classList.remove('test-wait'); + }); + }); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/fixed-pos-children.html b/testing/web-platform/tests/mathml/crashtests/fixed-pos-children.html new file mode 100644 index 0000000000..773439d6f3 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/fixed-pos-children.html @@ -0,0 +1,25 @@ +<style> + * { + border-bottom: hsla(115.49088416259553deg 12% 15% / 18%) groove thin; + -webkit-text-stroke: InactiveCaptionText thin; + scale: -121 + } + + * * { + padding-inline: 69%; + } +</style> +<script> + document.addEventListener('DOMContentLoaded', () => { + const style = document.createElement('style') + document.head.appendChild(style) + style.sheet.insertRule('* {-webkit-mask-image:url(', 0) + }) +</script> +<math> + <mmultiscripts> + <mglyph> + <maligngroup style='position:fixed'></maligngroup> + </mglyph> + </mmultiscripts> +</math>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/math-depth-overflow.html b/testing/web-platform/tests/mathml/crashtests/math-depth-overflow.html new file mode 100644 index 0000000000..e096dbb558 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/math-depth-overflow.html @@ -0,0 +1,10 @@ +<script> +document.addEventListener('DOMContentLoaded', () => { + let a = document.createElementNS('http://www.w3.org/1998/Math/MathML', 'math') + a.setAttribute('scriptlevel', '127') + let b = document.createElementNS('http://www.w3.org/1998/Math/MathML', 'mstyle') + b.setAttribute('scriptlevel', '+2147483645') + a.appendChild(b) + document.documentElement.appendChild(a) +}) +</script> diff --git a/testing/web-platform/tests/mathml/crashtests/mathml-in-svg-001.html b/testing/web-platform/tests/mathml/crashtests/mathml-in-svg-001.html new file mode 100644 index 0000000000..94a905f3b0 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mathml-in-svg-001.html @@ -0,0 +1,3 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1262555"> +<svg><foreignObject><math><mn>42</mn></math></foreignObject></svg> diff --git a/testing/web-platform/tests/mathml/crashtests/mmultiscripts-with-two-prescripts.html b/testing/web-platform/tests/mathml/crashtests/mmultiscripts-with-two-prescripts.html new file mode 100644 index 0000000000..54f9384606 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mmultiscripts-with-two-prescripts.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<math> + <mmultiscripts> + <mrow></mrow> + <mprescripts></mprescripts> + <mprescripts></mprescripts> + </mmultiscripts> +</math> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/1028521-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/1028521-1.xhtml new file mode 100644 index 0000000000..b8d0947741 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/1028521-1.xhtml @@ -0,0 +1,5 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<body> +<mstyle xmlns="http://www.w3.org/1998/Math/MathML"><li xmlns="http://www.w3.org/1999/xhtml" dir="rtl"></li></mstyle> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/1061027.html b/testing/web-platform/tests/mathml/crashtests/mozilla/1061027.html new file mode 100644 index 0000000000..3187f500a3 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/1061027.html @@ -0,0 +1,12 @@ +<style> +.c1 { transform-style: preserve-3d; display: table-row-group;</style><script> +var docElement = document.documentElement; +function init() { +test1 = document.createElementNS("http://www.w3.org/1999/xhtml", "defs"); +test1.setAttribute("class", "c1"); +docElement.appendChild(test1); +test2 = document.createElementNS("http://www.w3.org/1998/Math/MathML", "msub"); +test1.appendChild(test2); +} +document.addEventListener("DOMContentLoaded", init); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/1221888-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/1221888-1.html new file mode 100644 index 0000000000..741daa7503 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/1221888-1.html @@ -0,0 +1,15 @@ +<!DOCTYPE htm> +<html> +<head> +<meta charset="UTF-8"> +</head> +<body> + + <div> + <math> + <mspace height="50px" width="100px" style="outline-style: dotted;"></mspace> + </math> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/1373767-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/1373767-1.html new file mode 100644 index 0000000000..a159cec7be --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/1373767-1.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<style> +math { + position: fixed; +} +div { + transform: translateZ(0px); +} +body { + display: -moz-box; +} +</style> +</head> +<body> +<div> +<math></math> +</div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/1376158.html b/testing/web-platform/tests/mathml/crashtests/mozilla/1376158.html new file mode 100644 index 0000000000..42b6dd73c8 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/1376158.html @@ -0,0 +1,6 @@ +<math> +<munderover> +></ms> +<munder accentunder="true"> +<mo>)</mo> +<mscarry> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/151054-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/151054-1.xml new file mode 100644 index 0000000000..f634d089f3 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/151054-1.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html" /> + <title>Math with position: absolute</title> + <style> + math { position: absolute; } + </style> +</head> +<body> + <math xmlns="http://www.w3.org/1998/Math/MathML"> + <infinity/> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/1600635.html b/testing/web-platform/tests/mathml/crashtests/mozilla/1600635.html new file mode 100644 index 0000000000..d6ad315885 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/1600635.html @@ -0,0 +1,16 @@ +<style> + * { + overflow-inline: scroll; + } +</style> +<script> + window.addEventListener('load', () => { + const mbsubsup = document.createElementNS('http://www.w3.org/1998/Math/MathML', 'msubsup') + const m = document.createElementNS('http://www.w3.org/1998/Math/MathML', 'm') + const ms = document.createElementNS('http://www.w3.org/1998/Math/MathML', 'ms') + mbsubsup.appendChild(m) + ms.innerHTML = '<figure>' + mbsubsup.appendChild(ms) + document.documentElement.appendChild(mbsubsup) + }) +</script> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/289180-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/289180-1.xml new file mode 100644 index 0000000000..8d1f2e843c --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/289180-1.xml @@ -0,0 +1,16 @@ + + + <math xmlns="http://www.w3.org/1998/Math/MathML" mode="inline"> + <mfrac> + <mi>x</mi> + <mi>y</mi> + </mfrac> + </math> + <math xmlns="http://www.w3.org/1998/Math/MathML" mode="display"> + <mfrac> + + <mi>x</mi> + <mi>y</mi> + </mfrac> + </math> + diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/307826-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/307826-1.xhtml new file mode 100644 index 0000000000..02d436e825 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/307826-1.xhtml @@ -0,0 +1,30 @@ +<html xmlns="http://www.w3.org/1999/xhtml" class="test-wait"> + +<head> + +<title>Testcase for MathML crash</title> + +<script><![CDATA[ + +function boom() { + var div = document.getElementById("div"); + var mi = document.getElementById("mi"); + mi.appendChild(div); + mi.removeChild(div); + + document.documentElement.removeAttribute("class"); +} + +]]></script> + +</head> + + +<body onload="setTimeout(boom, 30);"> + +<div style="float: right;" id="div">Floated div</div> + +<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mi id="mi">mi</mi></math> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/307839-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/307839-1.xhtml new file mode 100644 index 0000000000..a26e58ac07 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/307839-1.xhtml @@ -0,0 +1,15 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>Testcase</title> + </head> + <body onload="document.getElementById('B').appendChild(document.getElementById('A'));"> + <div style="position: relative;"> + <math xmlns="http://www.w3.org/1998/Math/MathML"> + <mover> + <mrow id="A"/> + <mn id="B"/> + </mover> + </math> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/307839-2.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/307839-2.xhtml new file mode 100644 index 0000000000..05dc08a78f --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/307839-2.xhtml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/TR/MathML2/dtd/xhtml-math11-f.dtd" [ + <!ENTITY mathml "http://www.w3.org/1998/Math/MathML"> +]> +<html xmlns="http://www.w3.org/1999/xhtml"> + +<head> +<title>Testcase bug - Evil mrow:hover testcase crashes Mozilla</title> +<style type="text/css"> +#h:hover{display:block;} +</style> +</head> +<body onload="document.getElementById('mrow').setAttribute('id', 'h');"> +<math mode="display" xmlns="http://www.w3.org/1998/Math/MathML"> +<mover> + <mrow id="mrow">hovering over this should not crash Mozilla</mrow> + <mover> + <mo>10</mo> + <mrow>times</mrow> + </mover> +</mover> +</math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/323733-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/323733-1.xml new file mode 100644 index 0000000000..5551d8588c --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/323733-1.xml @@ -0,0 +1,7 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + <div> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"> + <ms /> + </math> + </div> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/323737-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/323737-1.xml new file mode 100644 index 0000000000..ad673f9460 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/323737-1.xml @@ -0,0 +1,9 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + <div> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"> + <mtable> + <mroot /> + </mtable> + </math> + </div> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/323738-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/323738-1.xml new file mode 100644 index 0000000000..318aa93b4e --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/323738-1.xml @@ -0,0 +1,11 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + <div> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"> + <msub> + <mo> + <factorial /> + </mo> + </msub> + </math> + </div> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/323741-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/323741-1.xml new file mode 100644 index 0000000000..8527c1a783 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/323741-1.xml @@ -0,0 +1,13 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + <div> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"> + <notin> + <mspace> + <mfenced /> + </mspace> + + f + </notin> + </math> + </div> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/323742-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/323742-1.xml new file mode 100644 index 0000000000..2cd225990d --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/323742-1.xml @@ -0,0 +1,16 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + <div> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"> + + <eulergamma> + <arcsech> + <mrow> + <mtable> + <maction/> + </mtable> + </mrow> + </arcsech> + </eulergamma> + </math> + </div> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/336074-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/336074-1.xhtml new file mode 100644 index 0000000000..3d1f5b4223 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/336074-1.xhtml @@ -0,0 +1,25 @@ +<html xmlns="http://www.w3.org/1999/xhtml" class="test-wait"> + +<head> + +<script> +<![CDATA[ + +function init() +{ + var k = document.getElementById("k"); + k.remove(); + document.documentElement.removeAttribute("class"); +} + +]]> +</script> + +</head> + +<body onload="setTimeout(init, 30);"> + +<mo xmlns='http://www.w3.org/1998/Math/MathML'><mi id="k">z</mi></mo> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1-inner.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1-inner.xhtml new file mode 100644 index 0000000000..22689c3c12 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1-inner.xhtml @@ -0,0 +1,28 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> + +function foo() +{ + var mrow = document.getElementById("mrow") + + mrow.parentNode.removeChild(mrow); +} + +</script> +</head> + +<body onload="setTimeout(foo, 100)"> + +<div> +<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <mrow id="mrow"> + <mtd><img xmlns="http://www.w3.org/1999/xhtml" src="347355-1.gif" /></mtd> + <mtable>
<mtr>
<mtd><mi>t</mi></mtd>
</mtr>
</mtable> + </mrow> +</math> +</div> + +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1.gif b/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1.gif Binary files differnew file mode 100644 index 0000000000..475ea8c164 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1.gif diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1.html new file mode 100644 index 0000000000..0d61fb9d4a --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/347355-1.html @@ -0,0 +1,9 @@ +<html class="test-wait"> +<head> +<script> +setTimeout('document.documentElement.className = ""', 1000); +</script> +<body> +<iframe src="347355-1-inner.xhtml"></iframe> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/347495-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/347495-1.xhtml new file mode 100644 index 0000000000..4a65b8f34d --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/347495-1.xhtml @@ -0,0 +1,10 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<body> + +<div><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <munderover>
<mo>∏</mo>
<mn>1</mn>
</munderover> +</math></div> + +</body> + +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/347507-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/347507-1.xhtml new file mode 100644 index 0000000000..274ae48ff2 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/347507-1.xhtml @@ -0,0 +1,29 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> + +function foo() +{ + var div = document.getElementById("div"); + div.appendChild(div.firstChild); + + var td = document.getElementById("td"); + td.setAttribute('rowspan', -2); +} + +</script> + +</head> + +<body onload="foo()"> + + +<div id="div"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + + <mtable>
<mtr>
<mtd id="td"><mi>y</mi></mtd>
</mtr>
</mtable> + +</math></div> + +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/348492-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/348492-1.xhtml new file mode 100644 index 0000000000..f59c9353a4 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/348492-1.xhtml @@ -0,0 +1,31 @@ +<html xmlns="http://www.w3.org/1999/xhtml" class="test-wait"> +<head> + +<script> +var MATHML_NS = "http://www.w3.org/1998/Math/MathML"; + +function foo() +{ + var mmultiscripts = document.createElementNS(MATHML_NS, 'mmultiscripts'); + var mtd = document.createElementNS(MATHML_NS, 'mtd'); + + + document.body.appendChild(mmultiscripts); + aC(mmultiscripts, mtd); + aC(mmultiscripts, document.createTextNode('foo')); + + document.documentElement.removeAttribute("class"); +} + +function aC(q1, q2) { q1.appendChild(q2); } + +</script> +</head> + +<body onload="setTimeout(foo, 30)"> + + + +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/348709-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/348709-1.xhtml new file mode 100644 index 0000000000..907ede6abb --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/348709-1.xhtml @@ -0,0 +1,20 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + +<script> +function foo() +{ + document.getElementById("mtr").appendChild(document.createTextNode("a")); +} +</script> +</head> + +<body onload="foo()"> + +<div><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> +<mrow>
<mfenced open="[" close="]">
<mtable>
<mtr id="mtr">
<mtd><mi>x</mi></mtd>
<mtd><mi>y</mi></mtd>
</mtr>
</mtable>
</mfenced>
</mrow> +</math></div> + +</body> + +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/348811-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/348811-1.xhtml new file mode 100644 index 0000000000..f6557e5a67 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/348811-1.xhtml @@ -0,0 +1,26 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> +function foo() +{ + var newTable = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mtable") + + document.getElementById("mtr").appendChild(newTable); +} +</script> +</head> + +<body onload="foo()"> + + +<div> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <mtable>
<mtr id="mtr">
<mtd> + <mi>x</mi> + </mtd>
</mtr>
</mtable>
</math> +</div> + + +</body> + +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/348811-2.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/348811-2.xhtml new file mode 100644 index 0000000000..d6a741765a --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/348811-2.xhtml @@ -0,0 +1,31 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> +function foo() +{ + var m = "http://www.w3.org/1998/Math/MathML"; + var newTable = document.createElementNS(m, "mtable") + document.getElementById("mtable").appendChild(newTable); +} +</script> +</head> + +<body onload="foo()"> + + +<div> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <mtable id="mtable"> + <mtr id="mtr"> + <mtd> + <mi>x</mi> + </mtd> + </mtr> + </mtable> + </math> +</div> + + +</body> + +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/353612-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/353612-1.xhtml new file mode 100644 index 0000000000..386e66f933 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/353612-1.xhtml @@ -0,0 +1,17 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> +function foo() +{ + document.getElementById("ms").setAttribute("lquote", "'"); +} +</script> +</head> + +<body onload="foo()"> + +<mtr xmlns="http://www.w3.org/1998/Math/MathML" /> +<mstyle xmlns="http://www.w3.org/1998/Math/MathML" id="ms" /> +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/355986-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/355986-1.xhtml new file mode 100644 index 0000000000..787e1f6772 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/355986-1.xhtml @@ -0,0 +1,34 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + + +<head> +<style> + +body * { + display: table-footer-group; + overflow: hidden scroll; +} + +</style> +</head> + + + +<body onload="document.getElementById('eee').style.display = 'inline';"> + + + + +<div id="eee"> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <mtable> + <mtr> + <mtd><mi>x</mi></mtd> + </mtr> + </mtable> + </math> +</div> + + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/364685-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/364685-1.xhtml new file mode 100644 index 0000000000..ab2b56a2f8 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/364685-1.xhtml @@ -0,0 +1,19 @@ +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:math="http://www.w3.org/1998/Math/MathML"> + +<body onload="boom();"> + +<script> +function boom() +{ + document.getElementById("merror").appendChild(document.getElementById("s")); +} +</script> + +<math:merror id="merror"></math:merror> + +<span id="s" /> + +</body> +</html> + diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/366012-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/366012-1.xhtml new file mode 100644 index 0000000000..55f29f3ac3 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/366012-1.xhtml @@ -0,0 +1,23 @@ +<html xmlns="http://www.w3.org/1999/xhtml" class="test-wait"> + +<head> +<script> + +function boom() +{ + var doom = document.getElementById("doom"); + doom.parentNode.removeChild(doom); + document.documentElement.removeAttribute("class"); +} + +</script> +</head> + +<body onload="setTimeout(boom, 30);"> + <div> + <p id="doom">This paragraph disappears.</p> + <math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><msub><mi>y</mi><mn>0</mn><frameset xmlns="http://www.w3.org/1999/xhtml" /></msub></math> + </div> +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/366564-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/366564-1.xhtml new file mode 100644 index 0000000000..8bb112a30d --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/366564-1.xhtml @@ -0,0 +1,44 @@ +<?xml version='1.0' encoding='utf-8'?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd" > +<html xmlns="http://www.w3.org/1999/xhtml" class="test-wait"> +<head> +<script> +function boom1() +{ + document.getElementById("mfenced3").appendChild(document.getElementById("div4")); + setTimeout(boom2, 30); +} + +function boom2() +{ + document.getElementById("sup1").appendChild(document.getElementById("mo2")); + document.documentElement.removeAttribute("class"); +} + +</script> +</head> + +<body onload="setTimeout(boom1, 30);"> + +<div><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <msup id="sup1"> + <mi>b</mi> + <mn>2</mn> + </msup> +</math></div> + +<div><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <mi>j</mi> + <mo id="mo2">=</mo> + <mfenced id="mfenced3" open="[" close="]"> + <mn>55</mn> + </mfenced> +</math></div> + +<div id="div4"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <mo> ∫ </mo> +</math></div> + +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/367107-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/367107-1.html new file mode 100644 index 0000000000..775ace87e0 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/367107-1.html @@ -0,0 +1,22 @@ +<html> +<head> +<script> + +function boom() +{ + var MATHML_NS = "http://www.w3.org/1998/Math/MathML"; + + var mtr = document.createElementNS(MATHML_NS, 'mtr'); + var mtable = document.createElementNS(MATHML_NS, 'mtable'); + + document.body.appendChild(mtr); + mtr.appendChild(mtable); +} + +</script> +</head> + +<body onload="boom()"> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/368430-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/368430-1.xhtml new file mode 100644 index 0000000000..79e10c46ac --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/368430-1.xhtml @@ -0,0 +1,5 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<body> +<maction xmlns="http://www.w3.org/1998/Math/MathML">Foo Bar</maction> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/370791-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/370791-1.xhtml new file mode 100644 index 0000000000..d72eb5f709 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/370791-1.xhtml @@ -0,0 +1,33 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:math="http://www.w3.org/1998/Math/MathML" class="test-wait"> +<head> +<script> + +function boom() +{ + var mi = document.getElementById("mi"); + var textA = mi.firstChild; + var textB = document.createTextNode("b"); + var textSpace = document.createTextNode(" "); + + var floater = document.getElementById("floater"); + + mi.appendChild(textB); + mi.appendChild(textSpace); + mi.removeChild(textA); + mi.removeChild(textSpace); + + floater.parentNode.removeChild(floater); + + document.documentElement.removeAttribute("class"); +} + +</script> +</head> + +<body onload="setTimeout(boom, 30);"> + +<math:mi id="mi">a<p><span style="float: right;" id="floater" /></p></math:mi> + +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/370862-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/370862-1.xhtml new file mode 100644 index 0000000000..fa2f1a4d67 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/370862-1.xhtml @@ -0,0 +1,27 @@ +<html xmlns="http://www.w3.org/1999/xhtml" class="test-wait"> + +<head> +<script> +function boom() +{ + var math = document.getElementById("math"); + var div = document.getElementById("div") + + math.setAttribute("color", "g"); + document.body.appendChild(div); + + document.documentElement.removeAttribute("class"); +} +</script> +</head> + +<body onload="setTimeout(boom, 30);"> + +<div id="div"> + +<mo xmlns='http://www.w3.org/1998/Math/MathML'>+<math id="math"><mn>1</mn></math></mo> + +</div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/372483-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/372483-1.xhtml new file mode 100644 index 0000000000..41edd7d9b7 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/372483-1.xhtml @@ -0,0 +1,7 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<body> + +<div><munder xmlns="http://www.w3.org/1998/Math/MathML"/></div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/373472-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/373472-1.xhtml new file mode 100644 index 0000000000..6c6a304a73 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/373472-1.xhtml @@ -0,0 +1,20 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> +function boom() +{ + document.getElementById("mo").appendChild(document.getElementById("mo2")); + document.body.offsetWidth; + document.getElementById("span").appendChild(document.createTextNode("baz")); +} +</script> +</head> + +<body onload="boom();"> + +<p>Foo <math xmlns="http://www.w3.org/1998/Math/MathML"><mo id="mo2">-</mo></math></p> + +<p><math xmlns="http://www.w3.org/1998/Math/MathML"><msub id="msub"><mo id="mo">+</mo></msub></math> <span id="span">bar</span></p> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/373472-2.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/373472-2.xhtml new file mode 100644 index 0000000000..1c7e1c7ade --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/373472-2.xhtml @@ -0,0 +1,9 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +</head> +<body> + +<p><math xmlns="http://www.w3.org/1998/Math/MathML"><mroot><mo>k</mo></mroot></math></p> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/375562-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/375562-1.xhtml new file mode 100644 index 0000000000..7b00d1f91a --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/375562-1.xhtml @@ -0,0 +1,38 @@ +<html xmlns="http://www.w3.org/1999/xhtml" class="test-wait"> +<head> +<script> + +var HTML_NS = "http://www.w3.org/1999/xhtml"; + +function boom() +{ + var a = document.getElementById("a"); + var plus = document.getElementById("plus"); + var frameset = document.createElementNS(HTML_NS, "frameset"); + + document.body.style.width = "300px"; + + a.parentNode.removeChild(a); + + plus.appendChild(frameset); + + document.documentElement.removeAttribute("class"); +} + +</script> +</head> + +<body onload="setTimeout(boom, 30);"> + +<div><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> + <msup> + <mi id="a">a</mi> + <mo id="plus">+</mo> + <mi>b</mi> + <mi>c</mi> + </msup> +</math></div> + +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/377824-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/377824-1.xhtml new file mode 100644 index 0000000000..ddbe7da664 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/377824-1.xhtml @@ -0,0 +1,5 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:math="http://www.w3.org/1998/Math/MathML"> +<body> +<math:mtable /> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/379418-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/379418-1.xhtml new file mode 100644 index 0000000000..dc6e9e5711 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/379418-1.xhtml @@ -0,0 +1,7 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<body> +<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> +ע</math> +</body> +</html> + diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/385226-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/385226-1.xhtml new file mode 100644 index 0000000000..b1d261eb38 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/385226-1.xhtml @@ -0,0 +1,29 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml"> + +<head> +<style> +[class="capleft"] { caption-side: left; } +[class="collapse"] { visibility: collapse; } +</style> +</head> + +<body> + +<div> + <math xmlns="http://www.w3.org/1998/Math/MathML" display="block" class="collapse"> + <mtable> + <mtr> + <mtd><mi>x</mi></mtd> + <mtd><mi>y</mi></mtd> + </mtr> + <html:caption class="capleft"> + <mtd><mi>z</mi></mtd> + <mtd><mi>w</mi></mtd> + </html:caption> + </mtable> + </math> +</div> + +</body> + +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/393760-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/393760-1.xhtml new file mode 100644 index 0000000000..cb5c2d7a12 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/393760-1.xhtml @@ -0,0 +1,16 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:math="http://www.w3.org/1998/Math/MathML"> +<head> +<script> +function boom() +{ + document.getElementById("mfenced").setAttribute("mathbackground", "yellow"); +} +</script> +</head> + +<body onload="boom();"> + +<math:mfenced id="mfenced" /> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/397518-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/397518-1.xhtml new file mode 100644 index 0000000000..bc460ead11 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/397518-1.xhtml @@ -0,0 +1,15 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:math="http://www.w3.org/1998/Math/MathML"> +<head> +<script> +function boom() +{ + var span = document.getElementById("s"); + var newSpan = document.createElementNS("http://www.w3.org/1999/xhtml", "span"); + span.appendChild(newSpan); +} +</script> +</head> +<body onload="boom();"> +<math:math><span id="s"><div/></span></math:math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/398038-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/398038-1.html new file mode 100644 index 0000000000..b383141c45 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/398038-1.html @@ -0,0 +1,8 @@ +<html> +<head><title>Crashtest for bug 398038</title></head> +<body> + <math><mpadded height="20 10"/></math> + <math><mpadded height="10 0000000000em"/></math> + <math><mpadded height="10 1.2em"/></math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/400475-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/400475-1.xhtml new file mode 100644 index 0000000000..13ff2fcb63 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/400475-1.xhtml @@ -0,0 +1,16 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> +function foo() +{ + document.getElementById("ms").setAttribute("foo", "x"); +} +</script> +</head> + +<body onload="foo()"> + +<mstyle xmlns="http://www.w3.org/1998/Math/MathML" id="ms" /> +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/402400-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/402400-1.xhtml new file mode 100644 index 0000000000..5212d67f16 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/402400-1.xhtml @@ -0,0 +1,41 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script type="text/javascript"> + +function boom() +{ + var textB = document.createTextNode("b"); + var textC = document.createTextNode("c"); + var textN = document.createTextNode("n"); + var textP = document.createTextNode("p"); + + var blv = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); + var odj = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); + var tr = document.createElementNS("http://www.w3.org/1999/xhtml", "tr"); + var td = document.createElementNS("http://www.w3.org/1999/xhtml", "td"); + var mathMO = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mo"); + + td.appendChild(textB); + document.body.appendChild(blv); + blv.appendChild(tr); + blv.appendChild(mathMO); + mathMO.appendChild(textP); + odj.appendChild(td); + odj.appendChild(textN); + + blv.removeChild(tr); + mathMO.appendChild(odj); + td.removeChild(textB); + blv.appendChild(textC); + document.body.appendChild(odj); + odj.insertBefore(mathMO, textN); + document.body.appendChild(mathMO); + mathMO.appendChild(odj); +} + +</script> +</head> + +<body onload="boom();"></body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/403156-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/403156-1.xhtml new file mode 100644 index 0000000000..b49bff7d04 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/403156-1.xhtml @@ -0,0 +1,12 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML"> + +<head> +<style> +maction { height: 12em; } +</style> +</head> + +<body> +<m:maction>䦚<span>c<div>t䦚</div></span>䦚x䦚䦚2</m:maction> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/404485-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/404485-1.xhtml new file mode 100644 index 0000000000..fea18cbd59 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/404485-1.xhtml @@ -0,0 +1,9 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:math="http://www.w3.org/1998/Math/MathML"> + +<body onload="document.getElementById('s').firstChild.splitText(1);"> + +<math:msqrt><span xmlns="http://www.w3.org/1999/xhtml" id="s">x <math:mo/></span></math:msqrt> + +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/405187-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/405187-1.xhtml new file mode 100644 index 0000000000..537512e629 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/405187-1.xhtml @@ -0,0 +1,10 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML"> +<head> +<style id="s"> +[class="fx"] { position: fixed; } +</style> +</head> +<body onload="document.getElementById('s').textContent = '* { color: magenta; }'"> +<m:mrow><m:mrow class="fx" /><span class="fx" /></m:mrow> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/405271-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/405271-1.xml new file mode 100644 index 0000000000..c94525c638 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/405271-1.xml @@ -0,0 +1,36 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML"> +<head> + +<style type="text/css"> +#q { width: 16px; height: 16px; } +#a, #b { counter-increment: chicken; } +</style> + +<style id="s" type="text/css"> +#a { content: 'x'; } +</style> + +<script type="text/javascript"> + +function boom() +{ + remove(document.getElementById("s")); + remove(document.getElementById("b")); +} + +function remove(n) +{ + n.parentNode.removeChild(n); +} + +</script> + +</head> + +<body onload="boom();"> + +<m:mrow id="a"/><m:mo id="q"><m:malignmark><m:msubsup/><m:munderover/><m:munder id="b"/></m:malignmark></m:mo> + +</body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/412237-1.xml b/testing/web-platform/tests/mathml/crashtests/mozilla/412237-1.xml new file mode 100644 index 0000000000..2e8f13b73e --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/412237-1.xml @@ -0,0 +1,11 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +</head> +<body> + +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <ms fontsize="-2%"><mfrac><mi>x</mi><mi>y</mi></mfrac></ms> +</math> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/413063-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/413063-1.xhtml new file mode 100644 index 0000000000..b595acd1ce --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/413063-1.xhtml @@ -0,0 +1,21 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML"> +<head> +<script type="text/javascript"> + +function boom() +{ + var mtd = document.getElementById("mtd"); + var ns = document.createElementNS("http://www.w3.org/1999/xhtml", "span"); + var nt = document.createTextNode("foo"); + ns.appendChild(nt); + mtd.appendChild(ns); + mtd.setAttribute("rowspan", "0"); +} + + +</script> +</head> + +<body onload="boom();"><m:mtd id="mtd" style="display: table-footer-group"><m:mi /></m:mtd></body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/416907-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/416907-1.xhtml new file mode 100644 index 0000000000..94a9abde21 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/416907-1.xhtml @@ -0,0 +1,5 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:mathml="http://www.w3.org/1998/Math/MathML"> +<mathml:mroot> +<frameset/> +</mathml:mroot> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/420420-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/420420-1.xhtml new file mode 100644 index 0000000000..db17b277a7 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/420420-1.xhtml @@ -0,0 +1,7 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML"> +<body> +<m:math><span><m:mfenced><m:mo>⁡</m:mo></m:mfenced></span></m:math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/431072-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/431072-1.xhtml new file mode 100644 index 0000000000..f25ce28f14 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/431072-1.xhtml @@ -0,0 +1,25 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + +<script type="text/javascript"> + +function boom() +{ + document.getElementById("math").setAttribute("class", "li"); + document.documentElement.offsetHeight; + document.documentElement.appendChild(document.createTextNode("\n")); +} + +</script> + +<style type="text/css"> + +[class="li"] { display: list-item; } + +</style> + +</head> + +<body onload="boom();"><math xmlns="http://www.w3.org/1998/Math/MathML" id="math"/></body> + +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/443089-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/443089-1.xhtml new file mode 100644 index 0000000000..2630cea131 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/443089-1.xhtml @@ -0,0 +1,7 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +</head> +<body> +<mtd xmlns="http://www.w3.org/1998/Math/MathML" id="mtd" rowspan="1073741825"/> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/462929-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/462929-1.html new file mode 100644 index 0000000000..386d8e138f --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/462929-1.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<script type="text/javascript"> + +var a = document.createElementNS("http://www.w3.org/2000/svg", "foo"); +var b = document.createElementNS("http://www.w3.org/1998/Math/MathML", "math"); + +</script> +</head> +<body></body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/463763-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/463763-1.xhtml new file mode 100644 index 0000000000..61df8ff0c3 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/463763-1.xhtml @@ -0,0 +1,10 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<body> +<math xmlns="http://www.w3.org/1998/Math/MathML" + xmlns:h="http://www.w3.org/1999/xhtml"> +<msup style="display:block"><mo><h:frameset/></mo></msup> +<msub style="display:block"><mo><h:frameset/></mo></msub> +<msubsup style="display:block"><mo><h:frameset/></mo></msubsup> +</math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/463763-2.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/463763-2.xhtml new file mode 100644 index 0000000000..8d41abade0 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/463763-2.xhtml @@ -0,0 +1,12 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<body> +<math xmlns="http://www.w3.org/1998/Math/MathML" + xmlns:h="http://www.w3.org/1999/xhtml"> +<mstyle displaystyle="false"> +<munder style="display:block"><mo movablelimits="true"><h:frameset/></mo></munder> +<mover style="display:block"><mo movablelimits="true"><h:frameset/></mo></mover> +<munderover style="display:block"><mo movablelimits="true"><h:frameset/></mo></munderover> +</mstyle> +</math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/476547-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/476547-1.xhtml new file mode 100644 index 0000000000..0cece35eaa --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/476547-1.xhtml @@ -0,0 +1,5 @@ +<html xmlns="http://www.w3.org/1999/xhtml" style="quotes: '<1>' '';"> +<body onload="document.getElementById('ms').setAttribute('lquote', '');" style="direction: rtl;"> +<span><ms id="ms" xmlns="http://www.w3.org/1998/Math/MathML"><mstyle/></ms></span> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/541620-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/541620-1.xhtml new file mode 100644 index 0000000000..ccef762e48 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/541620-1.xhtml @@ -0,0 +1,6 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://www.w3.org/1998/Math/MathML"> +<body> +<m:ms><m:mfenced/></m:ms> +</body> +</html> + diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/557474-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/557474-1.html new file mode 100644 index 0000000000..1bf8d534ca --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/557474-1.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> + <head> + <title>Test mpadded</title> + </head> + <body> + <math> + <mpadded width="-100px" height="-100px" depth="-100px"></mpadded> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/654928-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/654928-1.html new file mode 100644 index 0000000000..da52f34b45 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/654928-1.html @@ -0,0 +1,3 @@ +<html> + <math><maction selection="2">A<mo>B</mo></maction></math> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/655451-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/655451-1.xhtml new file mode 100644 index 0000000000..0d5fb687b7 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/655451-1.xhtml @@ -0,0 +1,15 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> + +function boom() +{ + document.documentElement.style.fontStyle = "oblique"; + var c = document.getElementById("c"); + c.parentNode.removeChild(c); +} + +</script> +</head> +<body onload="boom();"><math xmlns="http://www.w3.org/1998/Math/MathML"><frameset xmlns="http://www.w3.org/1999/xhtml"></frameset><msubsup id="c"/><mo><frameset xmlns="http://www.w3.org/1999/xhtml"></frameset></mo></math>x</body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/713606-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/713606-1.html new file mode 100644 index 0000000000..a0d4939a83 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/713606-1.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> + <head> + <title>Crashtest bug 713606</title> + </head> + <body onload="document.querySelector('mstyle').setAttribute('scriptminsize', '0%');"> + <math> + <msubsup> + <mtext>X</mtext> + <mtable displaystyle="true"></mstyle> + </mtext>Y</mtext> + </msubsup> + </math> + <math> + <msubsup> + <mtext>X</mtext> + <mstyle displaystyle="true"></mstyle> + </mtext>Y</mtext> + </msubsup> + </math> + <math><mfrac><mstyle displaystyle="true"></mstyle></mfrac></math> + </body> +</html> + diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/716349-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/716349-1.html new file mode 100644 index 0000000000..9b5895ad64 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/716349-1.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <head> + <title>Crashtest bug 716349</title> + </head> + <body> + <math> + <mspace width="-10px"/> + <mspace height="-10px"/> + </math> + </body> +</html> + diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/767251.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/767251.xhtml new file mode 100644 index 0000000000..aa3632a6ba --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/767251.xhtml @@ -0,0 +1 @@ +<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl"><tr><span><math xmlns="http://www.w3.org/1998/Math/MathML"/><tr>n</tr></span></tr></html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/770710-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/770710-1.html new file mode 100644 index 0000000000..2171966769 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/770710-1.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + var mo = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mo"); + var text = document.createTextNode(" "); + mo.appendChild(text); + document.body.appendChild(mo); + + window.getSelection().removeAllRanges(); + var r = document.createRange(); + r.setStart(mo.firstChild, 0); + r.setEnd(mo.firstChild, 1); + window.getSelection().addRange(r); + + window.getSelection().toString(); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/848725-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/848725-1.html new file mode 100644 index 0000000000..7ce9c434cc --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/848725-1.html @@ -0,0 +1,17 @@ +<!doctype html> +<html> + <head> + <title>Bug 848725</title> + <meta charset="utf-8"/> + </head> + <body> + <div> + <math> + <mover> + <mo>↠</mo> + <mspace width="500px"></mspace> + </mover> + </math> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/848725-2.html b/testing/web-platform/tests/mathml/crashtests/mozilla/848725-2.html new file mode 100644 index 0000000000..b6362f9bf2 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/848725-2.html @@ -0,0 +1,17 @@ +<!doctype html> +<html> + <head> + <title>Bug 848725</title> + <meta charset="utf-8"/> + </head> + <body> + <div> + <math> + <mover> + <mo>↡</mo> + <mspace height="500px"></mspace> + </mover> + </math> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/947557-1.html b/testing/web-platform/tests/mathml/crashtests/mozilla/947557-1.html new file mode 100644 index 0000000000..3ddfb7b984 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/947557-1.html @@ -0,0 +1,21 @@ +<!doctype html> +<body> + <math> + <mmultiscripts> + <mo>A</mo> + <mprescripts/> + <mmultiscripts> + <mo>A</mo> + <mprescripts/> + <mo>A</mo> + <mo>A</mo> + </mmultiscripts> + <mmultiscripts> + <mo>A</mo> + <mprescripts/> + <mo>A</mo> + <mo>A</mo> + </mmultiscripts> + </mmultiscripts> + </math> +</body> diff --git a/testing/web-platform/tests/mathml/crashtests/mozilla/973322-1.xhtml b/testing/web-platform/tests/mathml/crashtests/mozilla/973322-1.xhtml new file mode 100644 index 0000000000..dfac127fb4 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mozilla/973322-1.xhtml @@ -0,0 +1,8 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + <body onload="document.getElementById('f').setAttribute('class', 'e');"> + <math xmlns="http://www.w3.org/1998/Math/MathML"> + <mfenced id="f"/> + </math> + <p style="overflow: scroll; position: sticky;"></p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/crashtests/mspace-mpadded-negative-dimensions.html b/testing/web-platform/tests/mathml/crashtests/mspace-mpadded-negative-dimensions.html new file mode 100644 index 0000000000..97ae5b89b8 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mspace-mpadded-negative-dimensions.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1421195"> +<math><mspace width="-1px"/></math> +<math><mspace height="-1px"/></math> +<math><mspace depth="-1px"/></math> +<math><mspace height="-2px" depth="1px"/></math> +<math><mspace height="1px" depth="-2px"/></math> +<math><mpadded width="-1px"/></math> +<math><mpadded height="-1px"/></math> +<math><mpadded depth="-1px"/></math> +<math><mpadded height="-2px" depth="1px"></mpadded></math> +<math><mpadded height="1px" depth="-2px"></mpadded></math> +<math><mpadded lspace="-1px"/></math> diff --git a/testing/web-platform/tests/mathml/crashtests/mtd-as-multicol.html b/testing/web-platform/tests/mathml/crashtests/mtd-as-multicol.html new file mode 100644 index 0000000000..f00fa48815 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/mtd-as-multicol.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1354561"> +<div id="container"></div> +<script> + mtd = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mtd"); + mtd.style.columns = "2"; + container.appendChild(mtd); +</script> diff --git a/testing/web-platform/tests/mathml/crashtests/multicol-inside-ms.html b/testing/web-platform/tests/mathml/crashtests/multicol-inside-ms.html new file mode 100644 index 0000000000..b7d481e1fb --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/multicol-inside-ms.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1178979"> +<math><ms><span><span style="columns:3;"> diff --git a/testing/web-platform/tests/mathml/crashtests/multicol-on-token-elements.html b/testing/web-platform/tests/mathml/crashtests/multicol-on-token-elements.html new file mode 100644 index 0000000000..9fc00eb691 --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/multicol-on-token-elements.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<math><mi style="column-count: 10">mi</mi></math> +<math><mi style="column-width: 10px">mi</mi></math> +<math><mn style="column-count: 10">mn</mn></math> +<math><mn style="column-width: 10px">mn</mn></math> +<math><mo style="column-count: 10">mo</mo></math> +<math><mo style="column-width: 10px">mo</mo></math> +<math><ms style="column-count: 10">ms</ms></math> +<math><ms style="column-width: 10px">ms</ms></math> +<math><mtext style="column-count: 10">mtext</mtext></math> +<math><mtext style="column-width: 10px">mtext</mtext></math> diff --git a/testing/web-platform/tests/mathml/crashtests/operator-and-first-letter.html b/testing/web-platform/tests/mathml/crashtests/operator-and-first-letter.html new file mode 100644 index 0000000000..a4d56de72f --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/operator-and-first-letter.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<style> + p::first-letter { --panel-arrowcontent-color:-moz-FieldText; } +</style> +<p> + <math display="block"> + <mo>∫</mo> + </math> +</p> diff --git a/testing/web-platform/tests/mathml/crashtests/scrollbar-caching-assert.html b/testing/web-platform/tests/mathml/crashtests/scrollbar-caching-assert.html new file mode 100644 index 0000000000..3f972ef70d --- /dev/null +++ b/testing/web-platform/tests/mathml/crashtests/scrollbar-caching-assert.html @@ -0,0 +1,17 @@ +<!doctype html> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1663740"> +<style> +@namespace url(http://www.w3.org/1998/Math/MathML); +* { + all: inherit; + overflow-inline: hidden; +} +</style> +<script> +window.addEventListener('load', () => { + var x = document.getElementById('a') + x.setAttribute('mathvariant', 'double-struck') + x.innerHTML = '<select></select>' +}) +</script> +<math id='a'> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-006-ref.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-006-ref.html new file mode 100644 index 0000000000..39e6dabdfb --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-006-ref.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>RTL mtable and mtable with frame</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 25px Ahem; + } + </style> + </head> + <body> + + <p> + <math> + <mtable> + <mtr> + <mtd> + <mtext>É</mtext> + </mtd> + <mtd> + <mtext>p</mtext> + </mtd> + <mtd> + <mtext>X</mtext> + </mtd> + </mtr> + <mtr> + <mtd> + <mtext>pÉ</mtext> + </mtd> + <mtd> + <mtext>XÉ</mtext> + </mtd> + <mtd> + <mtext>Xp</mtext> + </mtd> + </mtr> + </mtable> + </math> + </p> + + <p> + <math> + <mtable frame="solid"> + <mtr> + <mtd> + <mtext>É</mtext> + </mtd> + <mtd> + <mtext>p</mtext> + </mtd> + <mtd> + <mtext>X</mtext> + </mtd> + </mtr> + <mtr> + <mtd> + <mtext>pÉ</mtext> + </mtd> + <mtd> + <mtext>XÉ</mtext> + </mtd> + <mtd> + <mtext>Xp</mtext> + </mtd> + </mtr> + </mtable> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-006.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-006.html new file mode 100644 index 0000000000..76cdc41471 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-006.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>RTL mtable and mtable with frame</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#tabular-math"> + <meta name="assert" content="Verify RTL math table renders the same as the column mirrored."> + <link rel="match" href="direction-006-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 25px Ahem; + } + </style> + </head> + <body> + + <p> + <math dir="rtl"> + <mtable> + <mtr> + <mtd> + <mtext>X</mtext> + </mtd> + <mtd> + <mtext>p</mtext> + </mtd> + <mtd> + <mtext>É</mtext> + </mtd> + </mtr> + <mtr> + <mtd> + <mtext>Xp</mtext> + </mtd> + <mtd> + <mtext>XÉ</mtext> + </mtd> + <mtd> + <mtext>pÉ</mtext> + </mtd> + </mtr> + </mtable> + </math> + </p> + + <p> + <math dir="rtl"> + <mtable frame="solid"> + <mtr> + <mtd> + <mtext>X</mtext> + </mtd> + <mtd> + <mtext>p</mtext> + </mtd> + <mtd> + <mtext>É</mtext> + </mtd> + </mtr> + <mtr> + <mtd> + <mtext>Xp</mtext> + </mtd> + <mtd> + <mtext>XÉ</mtext> + </mtd> + <mtd> + <mtext>pÉ</mtext> + </mtd> + </mtr> + </mtable> + </math> + </p> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_dir");</script> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-007-ref.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-007-ref.html new file mode 100644 index 0000000000..5c77395f20 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-007-ref.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>mo and embellished mrow/munderover (lspace=1em rspace=2em)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 25px/1 Ahem; + } + </style> + </head> + <body> + + <p> + <math> + <mtext>p</mtext><mo lspace="2em" rspace="1em">X</mo><mtext>p</mtext> + </math> + </p> + + <p> + <math> + <mtext>p</mtext> + <mrow><mo lspace="2em" rspace="1em">X</mo></mrow> + <mtext>p</mtext> + </math> + </p> + + <p> + <math> + <mtext>p</mtext> + <munderover> + <mo lspace="2em" rspace="1em">X</mo> + <mtext>É</mtext> + <mtext>É</mtext> + </munderover> + <mtext>p</mtext> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-007.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-007.html new file mode 100644 index 0000000000..3419467ae2 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-007.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>mo and embellished mrow/munderover (lspace=1em rspace=2em)</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> + <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> + <meta name="assert" content="Verify that the lspace/rspace on an mo or an embellished mrow/munderover element are switched in RTL mode"> + <link rel="match" href="direction-007-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 25px/1 Ahem; + } + </style> + </head> + <body> + + <p> + <math dir="rtl"> + <mtext>p</mtext><mo lspace="1em" rspace="2em">X</mo><mtext>p</mtext> + </math> + </p> + + <p> + <math dir="rtl"> + <mtext>p</mtext> + <mrow><mo lspace="1em" rspace="2em">X</mo></mrow> + <mtext>p</mtext> + </math> + </p> + + <p> + <math dir="rtl"> + <mtext>p</mtext> + <munderover> + <mo lspace="1em" rspace="2em">X</mo> + <mtext>É</mtext> + <mtext>É</mtext> + </munderover> + <mtext>p</mtext> + </math> + </p> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_dir");</script> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-008-ref.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-008-ref.html new file mode 100644 index 0000000000..492fa9539a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-008-ref.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>embellished mfrac (lspace=1em rspace=2em)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 25px/1 Ahem; + } + </style> + </head> + <body> + + <p> + <math> + <mtext>p</mtext> + <mfrac> + <mo lspace="2em" rspace="1em">X</mo> + <mtext>É</mtext> + </mfrac> + <mtext>p</mtext> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-008.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-008.html new file mode 100644 index 0000000000..0be8137364 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-008.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>embellished mfrac (lspace=1em rspace=2em)</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> + <meta name="assert" content="Verify that the lspace/rspace on an embellished mfrac element are switched in RTL mode"> + <link rel="match" href="direction-008-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 25px/1 Ahem; + } + </style> + </head> + <body> + + <p> + <math dir="rtl"> + <mtext>p</mtext> + <mfrac> + <mo lspace="1em" rspace="2em">X</mo> + <mtext>É</mtext> + </mfrac> + <mtext>p</mtext> + </math> + </p> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_dir");</script> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-010-ref.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-010-ref.html new file mode 100644 index 0000000000..4f595ed49f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-010-ref.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>dir="rtl" VS direction: rtl on math/mrow/mstyle</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 25px/1 Ahem; + } + </style> + </head> + <body> + + <p> + <math style="direction: rtl"> + <mtext>X</mtext> + <mtext>p</mtext> + <mtext>É</mtext> + </math> + </p> + + <p> + <math> + <mrow style="direction: rtl"> + <mtext>X</mtext> + <mtext>p</mtext> + <mtext>É</mtext> + </mrow> + </math> + </p> + + <p> + <math> + <mstyle mathcolor="blue" style="direction: rtl"> + <mtext>X</mtext> + <mtext>p</mtext> + <mtext>É</mtext> + </mstyle> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-010.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-010.html new file mode 100644 index 0000000000..6e92dfda2a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-010.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>dir="rtl" VS direction: rtl on math/mrow/mstyle</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> + <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> + <meta name="assert" content="Verify that math, mrow and mstyle with a dir=rtl attribute render the same as CSS direction right-to-left."> + <link rel="match" href="direction-010-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 25px/1 Ahem; + } + </style> + </head> + <body> + + <p> + <math dir="rtl"> + <mtext>X</mtext> + <mtext>p</mtext> + <mtext>É</mtext> + </math> + </p> + + <p> + <math> + <mrow dir="rtl"> + <mtext>X</mtext> + <mtext>p</mtext> + <mtext>É</mtext> + </mrow> + </math> + </p> + + <p> + <math> + <mstyle mathcolor="blue" dir="rtl"> + <mtext>X</mtext> + <mtext>p</mtext> + <mtext>É</mtext> + </mstyle> + </math> + </p> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_dir");</script> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-overall-ref.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-overall-ref.html new file mode 100644 index 0000000000..5ce6c5c42b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-overall-ref.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Verify dir attribute on various containers</title> + </head> + <body> + <p> + math: + <math> + <mspace width="25px" height="25px" mathbackground="blue"/> + <mspace width="25px" height="25px" mathbackground="green"/> + <mspace width="25px" height="25px" mathbackground="red"/> + </math> + </p> + + <p> + mrow: + <math> + <mrow> + <mspace width="25px" height="25px" mathbackground="blue"/> + <mspace width="25px" height="25px" mathbackground="green"/> + <mspace width="25px" height="25px" mathbackground="red"/> + </mrow> + </math> + </p> + + <p> + mstyle: + <math> + <mstyle> + <mspace width="25px" height="25px" mathbackground="blue"/> + <mspace width="25px" height="25px" mathbackground="green"/> + <mspace width="25px" height="25px" mathbackground="red"/> + </mstyle> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-overall.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-overall.html new file mode 100644 index 0000000000..6effb94c54 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-overall.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Verify dir attribute on various containers</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> + <link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> + <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> + <meta name="assert" content="Verify dir attribute on various containers."> + <link rel="match" href="direction-overall-ref.html"> + </head> + <body> + + <!-- Test dir="rtl" on <math>, <mrow> and <mstyle> elements. The rectangle + inside these elements should be displayed right-to-left. --> + + <p> + math: + <math dir="rtl"> + <mspace width="25px" height="25px" mathbackground="red"/> + <mspace width="25px" height="25px" mathbackground="green"/> + <mspace width="25px" height="25px" mathbackground="blue"/> + </math> + </p> + + <p> + mrow: + <math> + <mrow dir="rtl"> + <mspace width="25px" height="25px" mathbackground="red"/> + <mspace width="25px" height="25px" mathbackground="green"/> + <mspace width="25px" height="25px" mathbackground="blue"/> + </mrow> + </math> + </p> + + <p> + mstyle: + <math> + <mstyle dir="rtl"> + <mspace width="25px" height="25px" mathbackground="red"/> + <mspace width="25px" height="25px" mathbackground="green"/> + <mspace width="25px" height="25px" mathbackground="blue"/> + </mstyle> + </math> + </p> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-token-ref.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-token-ref.html new file mode 100644 index 0000000000..f1895b578a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-token-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html dir="rtl"> + <head> + <meta charset="utf-8"/> + <title>Verify dir attribute on token elements</title> + </head> + <body> + + <p><math><mtext style="direction: rtl;">חוק \left חסר או חוק \right מיותר</mtext></math></p> + <p><math><ms style="direction: rtl;">חוק \left חסר או חוק \right מיותר</ms></math></p> + <p><math><mo style="direction: rtl;">חוק \left חסר או חוק \right מיותר</mo></math></p> + <p><math><mi style="direction: rtl;">חוק \left חסר או חוק \right מיותר</mi></math></p> + <p><math><mn style="direction: rtl;">חוק \left חסר או חוק \right מיותר</mn></math></p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction-token.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-token.html new file mode 100644 index 0000000000..58319fbfac --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction-token.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html dir="rtl"> + <head> + <meta charset="utf-8"/> + <title>Verify dir attribute on token elements</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#token-elements"> + <meta name="assert" content="Verify dir attribute on various token elements."> + <link rel="match" href="direction-token-ref.html"> + </head> + <body> + + <!-- Test dir="rtl" on MathML token elements. The text contains RTL and + LTR characters, so the attribute is needed to specify the actual + direction. --> + + <p><math><mtext dir="rtl">חוק \left חסר או חוק \right מיותר</mtext></math></p> + <p><math><ms dir="rtl">חוק \left חסר או חוק \right מיותר</ms></math></p> + <p><math><mo dir="rtl">חוק \left חסר או חוק \right מיותר</mo></math></p> + <p><math><mi dir="rtl">חוק \left חסר או חוק \right מיותר</mi></math></p> + <p><math><mn dir="rtl">חוק \left חסר או חוק \right מיותר</mn></math></p> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_dir");</script> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/direction/direction.html b/testing/web-platform/tests/mathml/presentation-markup/direction/direction.html new file mode 100644 index 0000000000..dfb1671e4c --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/direction/direction.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html dir="rtl"> +<head> +<meta charset="utf-8"/> +<title>Verify computed direction</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<meta name="assert" content="Verify computed direction value."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() { + test(function() { + assert_equals(window.getComputedStyle(document.getElementById('x1')).direction, "ltr"); + assert_equals(window.getComputedStyle(document.getElementById('x2')).direction, "ltr"); + assert_equals(window.getComputedStyle(document.getElementById('x3')).direction, "ltr"); + assert_equals(window.getComputedStyle(document.getElementById('x4')).direction, "rtl"); + }, "Check direction"); + + done(); + } +</script> +</head> +<body> + <!-- Test the CSS direction and dir attribute on the <math> element. It + should be "ltr", except if an explicit dir="rtl" is used. --> + + <p>שורשי משוואה מודגשת זו <math id="x1"> <mrow> <msup> <mi>y</mi> <mn>3</mn> </msup> <mo>+</mo> <mi>p</mi> <mi>y</mi> <mo>+</mo> <mi>q</mi> <mo>=</mo> <mn>0</mn> </mrow> </math> מודגשים גם הם</p> + + <p>שורשי משוואה מודגשת זו <math id="x2" dir="ltr"> <mrow> <msup> <mi>y</mi> <mn>3</mn> </msup> <mo>+</mo> <mi>p</mi> <mi>y</mi> <mo>+</mo> <mi>q</mi> <mo>=</mo> <mn>0</mn> </mrow> </math> מודגשים גם הם</p> + + <p>שורשי משוואה מודגשת זו <math id="x3" dir="invalid"> <mrow> <msup> <mi>y</mi> <mn>3</mn> </msup> <mo>+</mo> <mi>p</mi> <mi>y</mi> <mo>+</mo> <mi>q</mi> <mo>=</mo> <mn>0</mn> </mrow> </math> מודגשים גם הם</p> + + <p>שורשי משוואה מודגשת זו <math id="x4" dir="rtl"> <mrow> <msup> <mi>y</mi> <mn>3</mn> </msup> <mo>+</mo> <mi>p</mi> <mi>y</mi> <mo>+</mo> <mi>q</mi> <mo>=</mo> <mn>0</mn> </mrow> </math> מודגשים גם הם</p> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-1.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-1.html new file mode 100644 index 0000000000..604e574322 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-1.html @@ -0,0 +1,191 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Fraction</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fraction-with-nonzero-line-thickness"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fraction-with-zero-line-thickness"> +<meta name="assert" content="Verify fraction metrics for different sizes of numerator and denominator."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math, mspace { + /* OS/2.sxHeight = 800 */ + /* post.underlineThickness == 20 */ + font-family: Ahem; + font-size: 10px; + } + div.shrink-wrap { + background: yellow; + display: inline-block; + margin-top: 5px; + padding-top: 5px; + } +</style> +<script> + const xHeight = 800; + const underlineThickness = 800; + const emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + + function getBox(aId) { + var box = document.getElementById(aId).getBoundingClientRect(); + box.middle = (box.bottom + box.top) / 2; + box.center = (box.left + box.right) / 2; + return box; + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 4; + var mathAxis = getBox("baseline").top - (xHeight/2) * emToPx; + for (var i = 0; i <= 4; i++) { + var frac = getBox("frac" + i); + var num = getBox("frac" + i + "num"); + var den = getBox("frac" + i + "den"); + // To estimate the fraction axis, we calculate barycenter between the + // top and bottom of the fraction, using the heights of numerator and + // denominator as weights. + var fracAxis = (frac.top * den.height + frac.bottom * num.height) / (num.height + den.height); + assert_approx_equals(fracAxis, mathAxis, e, "frac" + i + " fraction bar"); + } + }, "Fraction axis is aligned on the math axis"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + for (var i = 0; i < 10; i++) { + assert_less_than_equal(getBox("frac" + i + "num").bottom, getBox("frac" + i + "den").top, "numerator is above denominator"); + assert_less_than(getBox("frac" + i + "den").top - getBox("frac" + i + "num").bottom, 5, "The gap between numerator and denominator is not too large"); + } + }, "Vertical positions of numerator and denominator"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 3; + for (var i = 0; i < 10; i++) + assert_approx_equals(getBox("frac" + i + "num").center, getBox("frac" + i + "den").center, e, "numerator and denominator are horizontally centered"); + }, "Horizontal alignments of numerator and denominator"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 5; + for (var i = 0; i < 10; i++) { + var frac = getBox("frac" + i); + var num = getBox("frac" + i + "num"); + var den = getBox("frac" + i + "den"); + assert_approx_equals(frac.height, den.bottom - num.top, e, "height of frac " + i + " is determined by the bottom/top sides of the denominator/numerator"); + assert_approx_equals(frac.width, Math.max(num.right, den.right) - Math.min(num.left, den.left), e, "width of frac " + i + " is determined by the left/right sides of the denominator/numerator (plus some spacing)"); + } + }, "Dimension of mfrac elements"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_mfrac()); + + Array.from(document.getElementsByClassName("shrink-wrap")).forEach((container) => { + var marginPx = 2; // By default fractions have 1px margin on each side. + var epsilon = 1; + var containerWidth = container.getBoundingClientRect().width; + var children = container.getElementsByTagName("mspace"); + var numWidth = children[0].getBoundingClientRect().width; + var denWidth = children[1].getBoundingClientRect().width; + assert_approx_equals(containerWidth, marginPx + Math.max(numWidth, denWidth), epsilon, "Should be the maximum preferred width of numerator/denominator."); + }); + }, "Preferred width of mfrac elements"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="baseline" width="1em" height="0em" depth="1em" style="background: black"/> + <mfrac id="frac0"> + <mspace id="frac0num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac0den" width="15px" height="15px" style="background: green"/> + </mfrac> + <mfrac id="frac1"> + <mspace id="frac1num" width="30px" height="15px" style="background: blue"/> + <mspace id="frac1den" width="15px" height="15px" style="background: green"/> + </mfrac> + <mfrac id="frac2"> + <mspace id="frac2num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac2den" width="30px" height="15px" style="background: green"/> + </mfrac> + <mfrac id="frac3"> + <mspace id="frac3num" width="15px" height="30px" style="background: blue"/> + <mspace id="frac3den" width="15px" height="15px" style="background: green"/> + </mfrac> + <mfrac id="frac4"> + <mspace id="frac4num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac4den" width="15px" height="30px" style="background: green"/> + </mfrac> + <mfrac id="frac5" linethickness="0px"> + <mspace id="frac5num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac5den" width="15px" height="15px" style="background: green"/> + </mfrac> + <mfrac id="frac6" linethickness="0px"> + <mspace id="frac6num" width="30px" height="15px" style="background: blue"/> + <mspace id="frac6den" width="15px" height="15px" style="background: green"/> + </mfrac> + <mfrac id="frac7" linethickness="0px"> + <mspace id="frac7num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac7den" width="30px" height="15px" style="background: green"/> + </mfrac> + <mfrac id="frac8" linethickness="0px"> + <mspace id="frac8num" width="15px" height="30px" style="background: blue"/> + <mspace id="frac8den" width="15px" height="15px" style="background: green"/> + </mfrac> + <mfrac id="frac9" linethickness="0px"> + <mspace id="frac9num" width="15px" height="15px" style="background: blue"/> + <mspace id="frac9den" width="15px" height="30px" style="background: green"/> + </mfrac> + </math> + </p> + <div class="shrink-wrap"> + <math> + <mfrac> + <mspace width="30px" height="15px" style="background: blue"/> + <mspace width="15px" height="15px" style="background: green"/> + </mfrac> + </math> + </div> + <div class="shrink-wrap"> + <math> + <mfrac> + <mspace width="15px" height="15px" style="background: blue"/> + <mspace width="30px" height="15px" style="background: green"/> + </mfrac> + </math> + </div> + <div class="shrink-wrap"> + <math> + <mfrac linethickness="0px"> + <mspace width="30px" height="15px" style="background: blue"/> + <mspace width="15px" height="15px" style="background: green"/> + </mfrac> + </math> + </div> + <div class="shrink-wrap"> + <math> + <mfrac linethickness="0px"> + <mspace width="15px" height="15px" style="background: blue"/> + <mspace width="30px" height="15px" style="background: green"/> + </mfrac> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-001-ref.html new file mode 100644 index 0000000000..5b7a8dff47 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-001-ref.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions bar</title> + <style type="text/css"> + #container { + position: absolute; + left: 10px; + top: 50px; + width: 150px; + height: 150px; + background: green; + } + </style> + </head> + <body> + <p>This test passes if you see a green square.</p> + <div id="container"></div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-001.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-001.html new file mode 100644 index 0000000000..8284546e4f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-001.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <meta charset="utf-8"> + <title>fractions bar</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Verifies painting of the fraction bar"> + <link rel="match" href="frac-bar-001-ref.html"> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 1 / 1000 = 10px; */ + /* The gap / shift / axisheight parameters are set to 0. */ + font-family: "TestFont"; + font-size: 1px; + } + #container { + position: absolute; + left: 0; + top: 0; + } + </style> + <script src="/common/reftest-wait.js"></script> + <script src="/mathml/support/fonts.js"></script> + <script> + window.addEventListener("load", () => { loadAllFonts().then(adjustPositionOfFraction); }); + + function adjustPositionOfFraction() + { + requestAnimationFrame(() => { + var container = document.getElementById("container"); + var numeratorBox = document.getElementById("numerator").getBoundingClientRect(); + container.style.left = (10 - numeratorBox.left) + "px"; + container.style.top = (50 - numeratorBox.top) + "px"; + requestAnimationFrame(takeScreenshot); + }); + } + </script> + </head> + <body> + <p>This test passes if you see a green square.</p> + <div id="container"> + <math> + <mfrac style="color: green; font-size: 15em"> + <mspace id="numerator" width="150px"></mspace> + <mspace></mspace> + </mfrac> + </math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-002-ref.html new file mode 100644 index 0000000000..9d5eef896a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-002-ref.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions bar</title> + <style type="text/css"> + #green { + position: absolute; + background: green; + width: 150px; + height: 150px; + left: 50px; + top: 50px; + } + </style> + </head> + <body> + <p>This test passes if you see a green <strong>square</strong> and no red.</p> + <div> + <div id="green"></div> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-002.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-002.html new file mode 100644 index 0000000000..3eb5433e82 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-002.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <meta charset="utf-8"> + <title>fractions bar</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Verify painting of the fraction bar when margin/padding/border are involved."> + <link rel="match" href="frac-bar-002-ref.html"> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 1 / 1000 = 10px; */ + /* The gap / shift / axisheight parameters are set to 0. */ + font-family: "TestFont"; + font-size: 1px; + } + #container { + position: absolute; + left: 0; + top: 0; + } + #red { + position: absolute; + background: red; + margin: 1px; + width: 148px; + height: 148px; + } + </style> + <script src="/mathml/support/fonts.js"></script> + <script src="/common/reftest-wait.js"></script> + <script> + window.addEventListener("load", () => { loadAllFonts().then(adjustPositionOfFraction); }); + + function adjustPositionOfFraction() + { + requestAnimationFrame(() => { + var container = document.getElementById("container"); + var red = document.getElementById("red"); + var numeratorBox = document.getElementById("numerator").getBoundingClientRect(); + const shift = 50; + const numeratorMargin = 20; + + /* Move the red square at the expected position, + with a 1px gap to avoid antialiasing issues. */ + red.style.left = `${shift}px`; + red.style.top = `${shift}px`; + + /* Move the fraction bar at the expected position. */ + container.style.left = (shift - numeratorBox.left + numeratorMargin) + "px"; + container.style.top = (shift - numeratorBox.bottom - numeratorMargin) + "px"; + requestAnimationFrame(takeScreenshot); + }); + } + </script> + </head> + <body> + <p>This test passes if you see a green <strong>square</strong> and no red.</p> + <div> + <div id="red"></div> + <div id="container"> + <math> + <!-- border, padding and margin should not affect the width of the fraction bar. --> + <mfrac style="color: green; font-size: 15em; + border: 30px solid transparent; + padding: 60px; margin: 120px; + "> + <!-- the bar width is the one of the numerator margin box i.e. 80 + 2 * (5 + 10 + 20) = 150px --> + <mspace id="numerator" width="80px" + style="border: 5px solid transparent; + padding: 10px; margin: 20px;"></mspace> + <mspace></mspace> + </mfrac> + </math> + </div> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-003-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-003-ref.html new file mode 100644 index 0000000000..6bb6370d6e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-003-ref.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions bar (reference)</title> + <style type="text/css"> + #container { + position: absolute; + left: 10px; + top: 50px; + width: 150px; + height: 150px; + background: green; + } + </style> + </head> + <body> + <p>This test passes if you see a green square.</p> + <div id="container"></div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-003.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-003.html new file mode 100644 index 0000000000..69b45ea29c --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-bar-003.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions bar</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Verifies that the fraction bar takes the full width of the mfrac element"> + <link rel="match" href="frac-bar-003-ref.html"> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 1 / 1000 = 10px; */ + /* The gap / shift / axisheight parameters are set to 0. */ + font-family: "TestFont"; + font-size: 1px; + } + #container { + position: absolute; + left: 10px; + top: 50px; + width: 150px; + height: 150px; + } + + /* Revert style specified in the UA style sheet that changes box size. */ + mfrac { padding: 0; } + </style> + <script src="/mathml/support/fonts.js"></script> + </head> + <body> + <p>This test passes if you see a green square.</p> + <div id="container"> + <math> + <mfrac style="width: 150px; color: green; font-size: 15em"> + <mspace></mspace> + <mspace></mspace> + </mfrac> + </math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-001-notref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-001-notref.html new file mode 100644 index 0000000000..498d6277a3 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-001-notref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Fraction bar color</title> + </head> + <body style="font-size: 20pt;"> + <p>This test passes if you see a fraction with a blue fraction bar.</p> + <math> + <mfrac> + <mspace width="200px" height="20px" style="background: black"></mspace> + <mspace width="200px" height="20px" style="background: black"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-001.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-001.html new file mode 100644 index 0000000000..442388a6eb --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-001.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Fraction bar color</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <meta name="assert" content="The CSS color property has an effect on the fraction bar."> + <link rel="mismatch" href="frac-color-001-notref.html"> + </head> + <body style="font-size: 20pt;"> + <p>This test passes if you see a fraction with a blue fraction bar.</p> + <math> + <mfrac style="color: blue;"> + <mspace width="200px" height="20px" style="background: black"></mspace> + <mspace width="200px" height="20px" style="background: black"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-002-ref.html new file mode 100644 index 0000000000..fe2f4fa7b1 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-002-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions color</title> + </head> + <body> + <p>This test passes if you see a green square and a blue square.</p> + <div style="background: green; width: 200px; height: 200px;"> + </div> + <div style="background: blue; width: 200px; height: 200px;"> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-002.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-002.html new file mode 100644 index 0000000000..5c87212f59 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-color-002.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions color</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <meta name="assert" content="Verifies the color property affects the fraction bar"> + <link rel="match" href="frac-color-002-ref.html"> + </head> + <body> + <p>This test passes if you see a green square and a blue square.</p> + <div style="background: green; width: 200px; height: 200px;"> + <math> + <mspace width="10px"></mspace> + <mfrac style="color: green"> + <mspace width="150px" height="20px"></mspace> + <mspace width="150px" height="20px"></mspace> + </mfrac> + </math> + </div> + <div style="background: blue; width: 200px; height: 200px;"> + <math> + <mspace width="10px"></mspace> + <mfrac style="color: blue"> + <mspace width="150px" height="20px"></mspace> + <mspace width="150px" height="20px"></mspace> + </mfrac> + </math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-2-ref.html new file mode 100644 index 0000000000..d389906112 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-2-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mfrac created dynamically</title> + </head> + <body> + <p>This test passes if it renders the same as an invalid fraction with 3 children.</p> + <math> + <mfrac> + <mspace width="50px" height="50px" style="background: black"></mspace> + <mspace width="50px" height="50px" style="background: black"></mspace> + <mspace width="50px" height="50px" style="background: black"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-2.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-2.html new file mode 100644 index 0000000000..8e9fa520ea --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-2.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>mfrac created dynamically</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<meta name="assert" content="A dynamically added mfrac should render like the equivalent markup."> +<link rel="match" href="frac-created-dynamically-2-ref.html"> +<script> + window.addEventListener("load", function() { + + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + var mfrac = document.createElementNS("http://www.w3.org/1998/Math/MathML","mfrac"); + var mspace1 = document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace"); + mspace1.setAttribute("width", "50px"); + mspace1.setAttribute("height", "50px"); + mspace1.setAttribute("style", "background: black"); + var mspace2 = document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace"); + mspace2.setAttribute("width", "50px"); + mspace2.setAttribute("height", "50px"); + mspace2.setAttribute("style", "background: black"); + var mspace3 = document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace"); + mspace3.setAttribute("width", "50px"); + mspace3.setAttribute("height", "50px"); + mspace3.setAttribute("style", "background: black"); + document.getElementsByTagName("math")[0].appendChild(mfrac); + mfrac.appendChild(mspace1); + mfrac.appendChild(mspace2); + mfrac.appendChild(mspace3); + + document.documentElement.classList.remove('reftest-wait'); + }); +</script> +</head> +<body> + <p>This test passes if it renders the same as an invalid fraction with 3 children.</p> + <math></math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-3-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-3-ref.html new file mode 100644 index 0000000000..f8db144cfe --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-3-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mfrac created dynamically</title> + </head> + <body> + <p>This test passes if you see a fraction 1/3.</p> + <math> + <mfrac> + <mn>1</mn> + <mn>3</mn> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-3.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-3.html new file mode 100644 index 0000000000..1f7e23bb84 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-3.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>mfrac created dynamically</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<meta name="assert" content="A dynamically added mfrac should render like the equivalent markup."> +<link rel="match" href="frac-created-dynamically-3-ref.html"> +<script> + window.addEventListener("load", function() { + + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + var mn3 = document.createElementNS("http://www.w3.org/1998/Math/MathML","mn"); + mn3.appendChild(document.createTextNode("3")); + document.getElementsByTagName("mfrac")[0].appendChild(mn3); + document.getElementById("mn2").remove(); + + document.documentElement.classList.remove('reftest-wait'); + }); +</script> +</head> +<body> + <p>This test passes if you see a fraction 1/3.</p> + <math> + <mfrac> + <mn>1</mn> + <mn id="mn2">2</mn> + </mfrac> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-ref.html new file mode 100644 index 0000000000..e10405c572 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mfrac created dynamically</title> + </head> + <body> + <p>This test passes if you see a fraction.</p> + <math> + <mfrac> + <mspace width="50px" height="50px" style="background: black"></mspace> + <mspace width="50px" height="50px" style="background: black"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically.html new file mode 100644 index 0000000000..8f65e8d9cf --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-created-dynamically.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>mfrac created dynamically</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<meta name="assert" content="A dynamically added mfrac should render like the equivalent markup."> +<link rel="match" href="frac-created-dynamically-ref.html"> +<script> + window.addEventListener("load", function() { + + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + var mfrac = document.createElementNS("http://www.w3.org/1998/Math/MathML","mfrac"); + var mspace1 = document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace"); + mspace1.setAttribute("width", "50px"); + mspace1.setAttribute("height", "50px"); + mspace1.setAttribute("style", "background: black"); + var mspace2 = document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace"); + mspace2.setAttribute("width", "50px"); + mspace2.setAttribute("height", "50px"); + mspace2.setAttribute("style", "background: black"); + mfrac.appendChild(mspace1); + mfrac.appendChild(mspace2); + document.getElementsByTagName("math")[0].appendChild(mfrac); + + document.documentElement.classList.remove('reftest-wait'); + }); +</script> +</head> +<body> + <p>This test passes if you see a fraction.</p> + <math></math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-default-padding-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-default-padding-ref.html new file mode 100644 index 0000000000..93d3e0162b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-default-padding-ref.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fraction default padding</title> + </head> + <body> + <p>This test passes if you see three green squares of same size, separated by a gap of one pixel.</p> + <div> + <math> + <mspace width="150px" height="75px" depth="75px" style="background: green"/> + <mspace width="1px"/> + <mspace width="150px" height="75px" depth="75px" style="background: green"/> + <mspace width="1px"/> + <mspace width="150px" height="75px" depth="75px" style="background: green"/> + </math> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-default-padding.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-default-padding.html new file mode 100644 index 0000000000..30f155661a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-default-padding.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fraction default padding</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Verifies 1px padding is added around each side of the fraction."> + <link rel="match" href="frac-default-padding-ref.html"> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 1 / 1000 = 10px; */ + /* The gap / shift / axisheight parameters are set to 0. */ + font-family: "TestFont"; + font-size: 1px; + } + </style> + </head> + <body> + <p>This test passes if you see three green squares of same size, separated by a gap of one pixel.</p> + <div> + <math> + <mspace width="150px" height="75px" depth="75px" style="background: green"/> + <mfrac style="color: green; font-size: 15em"> + <mspace id="numerator" width="150px"></mspace> + <mspace></mspace> + </mfrac> + <mspace width="150px" height="75px" depth="75px" style="background: green"/> + </math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-2-ref.html new file mode 100644 index 0000000000..d57c20901b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-2-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mfrac with one child</title> +</head> +<body> + <p>This test passes if you see a single rectangle.</p> + <math> + <mrow style="padding-inline-start: 1px; padding-inline-end: 1px;"> + <mspace width="200px" height="200px" style="background: green"></mspace> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-2.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-2.html new file mode 100644 index 0000000000..729fe813d0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-2.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mfrac with one child</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#mfrac"> +<meta name="assert" content="An mfrac with one child should render using mrow."> +<link rel="match" href="frac-invalid-2-ref.html"> +</head> +<body> + <p>This test passes if you see a single rectangle.</p> + <math> + <mfrac> + <mspace width="200px" height="200px" style="background: green"></mspace> + </mfrac> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-3-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-3-ref.html new file mode 100644 index 0000000000..703e4aeca0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-3-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mfrac with three children</title> +</head> +<body> + <p>This test passes if you see a single rectangle.</p> + <math> + <mrow style="padding-inline-start: 1px; padding-inline-end: 1px;"> + <mspace width="50px" height="200px" style="background: green"></mspace> + <mspace width="50px" height="200px" style="background: green"></mspace> + <mspace width="100px" height="200px" style="background: green"></mspace> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-3.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-3.html new file mode 100644 index 0000000000..d56b55ef80 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-3.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mfrac with three children</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#mfrac"> +<meta name="assert" content="An mfrac with no children should render using an empty mrow."> +<link rel="match" href="frac-invalid-3-ref.html"> +</head> +<body> + <p>This test passes if you see a single rectangle.</p> + <math> + <mfrac> + <mspace width="50px" height="200px" style="background: green"></mspace> + <mspace width="50px" height="200px" style="background: green"></mspace> + <mspace width="100px" height="200px" style="background: green"></mspace> + </mfrac> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-ref.html new file mode 100644 index 0000000000..beb3024732 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mfrac with zero children</title> +</head> +<body> + <p>This test passes if mfrac renders nothing.</p> + <math> + <mrow style="padding-inline-start: 1px; padding-inline-end: 1px;"> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid.html new file mode 100644 index 0000000000..78e11e7e2b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-invalid.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mfrac with zero children</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#mfrac"> +<meta name="assert" content="An mfrac with no children should render using an empty mrow."> +<link rel="match" href="frac-invalid-ref.html"> +</head> +<body> + <p>This test passes if mfrac renders nothing.</p> + <math> + <mfrac> + </mfrac> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-legacy-bevelled-attribute.tentative-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-legacy-bevelled-attribute.tentative-ref.html new file mode 100644 index 0000000000..f0b355c7bd --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-legacy-bevelled-attribute.tentative-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions bevelled (reference)</title> + </head> + <body> + <p>Test passes is you see a blue rectangle <em>above</em> a green rectangle, separated by a horizontal bar.</p> + <p> + <math> + <mfrac> + <mspace width="100px" height="30px" style="background: lightblue"></mspace> + <mspace width="100px" height="30px" style="background: lightgreen"></mspace> + </mfrac> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-legacy-bevelled-attribute.tentative.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-legacy-bevelled-attribute.tentative.html new file mode 100644 index 0000000000..a98fc0f979 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-legacy-bevelled-attribute.tentative.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions bevelled</title> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mfrac"> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://github.com/mathml-refresh/mathml/issues/29"> + <meta name="assert" content="Verify that the MathML3 bevelled attribute is ignored."> + <link rel="match" href="frac-legacy-bevelled-attribute.tentative-ref.html"> + </head> + <body> + <p>Test passes is you see a blue rectangle <em>above</em> a green rectangle, separated by a horizontal bar.</p> + <p> + <math> + <mfrac bevelled="true"> + <mspace width="100px" height="30px" style="background: lightblue"></mspace> + <mspace width="100px" height="30px" style="background: lightgreen"></mspace> + </mfrac> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-001-ref.html new file mode 100644 index 0000000000..d4be8ea03b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-001-ref.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions linethickness</title> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 1 / 1000 = 10px; */ + font-family: "TestFont"; + font-size: 1px; + } + </style> + </head> + <body> + <p>This test passes if you see the same fraction four times.</p> + <math> + <mfrac> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + <mspace width="20px"/> + <mfrac> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + <mspace width="20px"/> + <mfrac> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + <mspace width="20px"/> + <mfrac> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-001.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-001.html new file mode 100644 index 0000000000..918d4aba6e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-001.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions linethickness</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Verifies deprecated 'thin', 'medium', 'thick' and unitless values have no effect on the linethickness of the mfrac element"> + <link rel="match" href="frac-linethickness-001-ref.html"> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 1 / 1000 = 10px; */ + font-family: "TestFont"; + font-size: 1px; + } + </style> + </head> + <body> + <p>This test passes if you see the same fraction four times.</p> + <math> + <mfrac linethickness="thin"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + <mspace width="20px"/> + <mfrac linethickness="medium"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + <mspace width="20px"/> + <mfrac linethickness="thick"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + <mspace width="20px"/> + <mfrac linethickness="5"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-002.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-002.html new file mode 100644 index 0000000000..bb47f18687 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-002.html @@ -0,0 +1,131 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions linethickness</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> + <meta name="assert" content="Verifies fraction with positive, negative, percent and named space linethickness values."> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/mathml/support/feature-detection.js"></script> + <script src="/mathml/support/fonts.js"></script> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 10 / 1000 = 100px; */ + font-family: "TestFont"; + font-size: 10px; + } + </style> + <script> + function LineThickness(aId) { + var mfrac = document.getElementById(aId); + var numBox = mfrac.firstElementChild.getBoundingClientRect(); + var denumBox = mfrac.lastElementChild.getBoundingClientRect(); + return denumBox.top - numBox.bottom; + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + var defaultRuleThickness = 100; + var epsilon = 2; + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(LineThickness("positive"), 5.67 * 10, epsilon); + }, "Positive"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + /* Negative values are treated as 0 */ + assert_approx_equals(LineThickness("negative"), 0, epsilon); + }, "Negative"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(LineThickness("percent"), defaultRuleThickness * 234 / 100, epsilon); + }, "Percentage"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + /* Namedspace values are invalid in MathML Core. */ + assert_approx_equals(LineThickness("namedspace"), defaultRuleThickness, epsilon); + }, "Named space"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + /* Calc() expressions are invalid in MathML Core. */ + assert_approx_equals(LineThickness("calc"), defaultRuleThickness, epsilon); + }, "Calc() expression"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + document.getElementById("dynamic-attach").setAttribute("linethickness", "400%"); + document.getElementById("dynamic-modify").setAttribute("linethickness", "200%"); + document.getElementById("dynamic-remove").removeAttribute("linethickness"); + assert_approx_equals(LineThickness("dynamic-attach"), defaultRuleThickness * 4, epsilon, "attach"); + assert_approx_equals(LineThickness("dynamic-modify"), defaultRuleThickness * 2, epsilon, "modify"); + assert_approx_equals(LineThickness("dynamic-remove"), defaultRuleThickness, epsilon, "remove"); + }, "Dynamic linethickness"); + + done(); + } + </script> + </head> + <body> + <math> + <mfrac id="positive" linethickness="5.67em"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <math> + <mfrac id="negative" linethickness="-1.23em"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <math> + <mfrac id="percent" linethickness="234%"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <math> + <mfrac id="namedspace" linethickness="veryverythickmathspace"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <math> + <mfrac id="calc" linethickness="calc(20px)"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <math> + <mfrac id="dynamic-attach"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <math> + <mfrac id="dynamic-modify" linethickness="300%"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <math> + <mfrac id="dynamic-remove" linethickness="300%"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-003-notref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-003-notref.html new file mode 100644 index 0000000000..934d666333 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-003-notref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions linethickness</title> + </head> + <body> + <p>This test passes if you see a fraction without fraction bar.</p> + <math> + <mfrac> + <mspace width="20px" height="5px" style="background: blue"></mspace> + <mspace width="20px" height="5px" style="background: cyan"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-003.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-003.html new file mode 100644 index 0000000000..d930f058c5 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-003.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions linethickness</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Verifies fraction with 0px bar."> + <link rel="mismatch" href="frac-linethickness-003-notref.html"> + </head> + <body> + <p>This test passes if you see a fraction without fraction bar.</p> + <math> + <mfrac linethickness="0px"> + <mspace width="20px" height="5px" style="background: blue"></mspace> + <mspace width="20px" height="5px" style="background: cyan"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-004-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-004-ref.html new file mode 100644 index 0000000000..8014f0a895 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-004-ref.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions linethickness</title> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 1 / 1000 = 10px; */ + font-family: "TestFont"; + font-size: 1px; + } + </style> + </head> + <body> + <p>This test passes if you see no fraction bar.</p> + <math> + <mfrac linethickness="0px"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-004.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-004.html new file mode 100644 index 0000000000..bfb708c092 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-linethickness-004.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>fractions linethickness</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Verifies that unitless value of zero causes no fraction bar to be painted"> + <link rel="match" href="frac-linethickness-004-ref.html"> + <style type="text/css"> + @font-face { + font-family: TestFont; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } + math { + /* FractionRuleThickness = 10000 * 1 / 1000 = 10px; */ + font-family: "TestFont"; + font-size: 1px; + } + </style> + </head> + <body> + <p>This test passes if you see no fraction bar.</p> + <math> + <mfrac linethickness="0"> + <mspace width="20px" height="10px" style="background: blue"></mspace> + <mspace width="20px" height="10px" style="background: cyan"></mspace> + </mfrac> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-mrow-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-mrow-001-ref.html new file mode 100644 index 0000000000..e42cb96fe8 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-mrow-001-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Fraction mrow</title> + </head> + <body style="font-size: 20pt;"> + <p>This test passes if you see a fraction with a blue square as numerator and a cyan square as denominator.</p> + <math> + <mfrac> + <mspace width="60px" height="60px" style="background: blue"></mspace> + <mspace width="60px" height="60px" style="background: cyan"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-mrow-001.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-mrow-001.html new file mode 100644 index 0000000000..82e817e4de --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-mrow-001.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Fraction mrow</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> + <meta name="assert" content="This test that <mrow> elements can be used as numerator and denominator of fractions."> + <link rel="match" href="frac-mrow-001-ref.html"> + </head> + <body style="font-size: 20pt;"> + <p>This test passes if you see a fraction with a blue square as numerator and a cyan square as denominator.</p> + <math> + <mfrac> + <mrow> + <mspace width="30px" height="60px" style="background: blue"></mspace> + <mspace width="30px" height="60px" style="background: blue "></mspace> + </mrow> + <mrow> + <mspace width="30px" height="60px" style="background: cyan"></mspace> + <mspace width="30px" height="60px" style="background: cyan "></mspace> + </mrow> + </mfrac> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-numalign-denomalign-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-numalign-denomalign-001-ref.html new file mode 100644 index 0000000000..09b83e9efb --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-numalign-denomalign-001-ref.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Fraction numalign denomalign</title> + </head> + <body> + <p>This test passes if you see 6 fractions with numerators and + denominators horizontally centered.</p> + <p> + <math> + <mfrac> + <mrow> + <mspace width="10px" height="20px"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px"></mspace> + </mrow> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + </mfrac> + </math> + <math> + <mfrac> + <mrow> + <mspace width="10px" height="20px"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px"></mspace> + </mrow> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + </mfrac> + </math> + <math> + <mfrac> + <mrow> + <mspace width="10px" height="20px"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px"></mspace> + </mrow> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + </mfrac> + </math> + </p> + <p> + <math> + <mfrac> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mrow> + <mspace width="10px" height="20px"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px"></mspace> + </mrow> + </mfrac> + </math> + <math> + <mfrac> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mrow> + <mspace width="10px" height="20px"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px"></mspace> + </mrow> + </mfrac> + </math> + <math> + <mfrac> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mrow> + <mspace width="10px" height="20px"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px"></mspace> + </mrow> + </mfrac> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-numalign-denomalign-001.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-numalign-denomalign-001.html new file mode 100644 index 0000000000..653962f33d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-numalign-denomalign-001.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Fraction numalign denomalign</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Check that legacy numalign/denomalign attributes are ignored."> + <link rel="match" href="frac-numalign-denomalign-001-ref.html"> + </head> + <body> + <p>This test passes if you see 6 fractions with numerators and + denominators horizontally centered.</p> + <p> + <math> + <mfrac numalign="left"> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + </mfrac> + </math> + <math> + <mfrac numalign="center"> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + </mfrac> + </math> + <math> + <mfrac numalign="right"> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + </mfrac> + </math> + </p> + <p> + <math> + <mfrac denomalign="left"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mfrac> + </math> + <math> + <mfrac denomalign="center"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mfrac> + </math> + <math> + <mfrac denomalign="right"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mfrac> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-1.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-1.html new file mode 100644 index 0000000000..3c5e35159e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-1.html @@ -0,0 +1,440 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Fraction parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<meta name="assert" content="Element mfrac correctly uses the fraction parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace { + font-size: 10px; + } + @font-face { + font-family: axisheight7000-rulethickness1000; + src: url("/fonts/math/fraction-axisheight7000-rulethickness1000.woff"); + } + @font-face { + font-family: denominatordisplaystylegapmin5000-rulethickness1000; + src: url("/fonts/math/fraction-denominatordisplaystylegapmin5000-rulethickness1000.woff"); + } + @font-face { + font-family: denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000; + src: url("/fonts/math/fraction-denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000.woff"); + } + @font-face { + font-family: denominatorgapmin4000-rulethickness1000; + src: url("/fonts/math/fraction-denominatorgapmin4000-rulethickness1000.woff"); + } + @font-face { + font-family: denominatorshiftdown3000-axisheight1000-rulethickness1000; + src: url("/fonts/math/fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000.woff"); + } + @font-face { + font-family: numeratordisplaystylegapmin8000-rulethickness1000; + src: url("/fonts/math/fraction-numeratordisplaystylegapmin8000-rulethickness1000.woff"); + } + @font-face { + font-family: numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000; + src: url("/fonts/math/fraction-numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000.woff"); + } + @font-face { + font-family: numeratorgapmin9000-rulethickness1000; + src: url("/fonts/math/fraction-numeratorgapmin9000-rulethickness1000.woff"); + } + @font-face { + font-family: numeratorshiftup11000-axisheight1000-rulethickness1000; + src: url("/fonts/math/fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff"); + } + @font-face { + font-family: rulethickness10000; + src: url("/fonts/math/fraction-rulethickness10000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 7000 * emToPx; + var v2 = 1000 * emToPx; + assert_approx_equals(getBox("ref0001").top - getBox("num0001").bottom, + v1 + v2 / 2, epsilon, "mfrac: axis height"); + }, "AxisHeight"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 5000 * emToPx; + assert_approx_equals(getBox("den0002").top - getBox("ref0002").bottom, + v1, epsilon, "mfrac: denominator gap"); + }, "DenominatorDisplayStyleGapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 6000 * emToPx; + assert_approx_equals(getBox("den0003").top - getBox("ref0003").bottom, + v1, epsilon, "mfrac: denominator shift"); + }, "DenominatorDisplayStyleShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 5000 * emToPx; + assert_approx_equals(getBox("den0002b").top - getBox("ref0002b").bottom, + v1, epsilon, "mfrac: denominator gap"); + }, "DenominatorDisplayStyleGapMin Displaystyle"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var v1 = 6000 * emToPx; + assert_approx_equals(getBox("den0003b").top - getBox("ref0003b").bottom, + v1, epsilon, "mfrac: denominator shift"); + }, "DenominatorDisplayStyleShiftDown Displaystyle"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var v1 = 5000 * emToPx; + assert_approx_equals(getBox("den0002c").top - getBox("ref0002c").bottom, + v1, epsilon, "mfrac: denominator gap"); + }, "DenominatorDisplayStyleGapMin Displaystyle on fraction"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var v1 = 6000 * emToPx; + assert_approx_equals(getBox("den0003c").top - getBox("ref0003c").bottom, + v1, epsilon, "mfrac: denominator shift"); + }, "DenominatorDisplayStyleShiftDown Displaystyle on fraction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var v1 = 4000 * emToPx; + assert_approx_equals(getBox("den0004").top - getBox("ref0004").bottom, + v1, epsilon, "mfrac: denominator gap"); + }, "DenominatorGapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 3000 * emToPx; + assert_approx_equals(getBox("den0005").top - getBox("ref0005").bottom, + v1, epsilon, "mfrac: denominator shift"); + }, "DenominatorShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var v1 = 4000 * emToPx; + assert_approx_equals(getBox("den0004b").top - getBox("ref0004b").bottom, + v1, epsilon, "mfrac: denominator gap"); + }, "DenominatorGapMin Displaystyle on fraction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 3000 * emToPx; + assert_approx_equals(getBox("den0005b").top - getBox("ref0005b").bottom, + v1, epsilon, "mfrac: denominator shift"); + }, "DenominatorShiftDown Displaystyle on fraction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 8000 * emToPx; + assert_approx_equals(getBox("ref0006").top - getBox("num0006").bottom, + v1, epsilon, "mfrac: numerator gap"); + }, "NumeratorDisplayStyleGapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 2000 * emToPx; + assert_approx_equals(getBox("ref0007").top - getBox("num0007").bottom, + v1, epsilon, "mfrac: numerator shift"); + }, "NumeratorDisplayStyleShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 8000 * emToPx; + assert_approx_equals(getBox("ref0006b").top - getBox("num0006b").bottom, + v1, epsilon, "mfrac: numerator gap"); + }, "NumeratorDisplayStyleGapMin Displaystyle"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 2000 * emToPx; + assert_approx_equals(getBox("ref0007b").top - getBox("num0007b").bottom, + v1, epsilon, "mfrac: numerator shift"); + }, "NumeratorDisplayStyleShiftDown Displaystyle"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 8000 * emToPx; + assert_approx_equals(getBox("ref0006c").top - getBox("num0006c").bottom, + v1, epsilon, "mfrac: numerator gap"); + }, "NumeratorDisplayStyleGapMin Displaystyle on fraction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 2000 * emToPx; + assert_approx_equals(getBox("ref0007c").top - getBox("num0007c").bottom, + v1, epsilon, "mfrac: numerator shift"); + }, "NumeratorDisplayStyleShiftDown Displaystyle on fraction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 9000 * emToPx; + assert_approx_equals(getBox("ref0008").top - getBox("num0008").bottom, + v1, epsilon, "mfrac: numerator gap"); + }, "NumeratorGapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 11000 * emToPx; + assert_approx_equals(getBox("ref0009").top - getBox("num0009").bottom, + v1, epsilon, "mfrac: numerator shift"); + }, "NumeratorShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 10000 * emToPx; + assert_approx_equals(getBox("den0010").top - getBox("num0010").bottom, + v1, epsilon, "mfrac: rule thickness"); + }, "FractionRuleThickness"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: axisheight7000-rulethickness1000;"> + <mspace id="ref0001" depth="1em" width="3em" style="background: green"/> + <mfrac> + <mspace width="3em" height="1em" id="num0001" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math display="block" style="font-family: denominatordisplaystylegapmin5000-rulethickness1000;"> + <mspace id="ref0002" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac> + <mspace width="3em"/> + <mspace width="3em" height="1em" id="den0002" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math display="block" style="font-family: denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000;"> + <mspace id="ref0003" width="3em" height="1em" style="background: green"/> + <mfrac> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0003" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: denominatordisplaystylegapmin5000-rulethickness1000;"> + <mspace id="ref0002b" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac> + <mspace width="3em"/> + <mspace width="3em" height="1em" id="den0002b" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000;"> + <mspace id="ref0003b" width="3em" height="1em" style="background: green"/> + <mfrac> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0003b" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: denominatordisplaystylegapmin5000-rulethickness1000;"> + <mspace id="ref0002c" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac displaystyle="true"> + <mspace width="3em"/> + <mspace width="3em" height="1em" id="den0002c" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: denominatordisplaystyleshiftdown6000-axisheight1000-rulethickness1000;"> + <mspace id="ref0003c" width="3em" height="1em" style="background: green"/> + <mfrac displaystyle="true"> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0003c" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: denominatorgapmin4000-rulethickness1000;"> + <mspace id="ref0004" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac> + <mspace width="3em"/> + <mspace width="3em" height="1em" id="den0004" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: denominatorshiftdown3000-axisheight1000-rulethickness1000;"> + <mspace id="ref0005" width="3em" height="1em" style="background: green"/> + <mfrac> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0005" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: denominatorgapmin4000-rulethickness1000;"> + <mspace id="ref0004b" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac displaystyle="false"> + <mspace width="3em"/> + <mspace width="3em" height="1em" id="den0004b" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: denominatorshiftdown3000-axisheight1000-rulethickness1000;"> + <mspace id="ref0005b" width="3em" height="1em" style="background: green"/> + <mfrac displaystyle="false"> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0005b" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math display="block" style="font-family: numeratordisplaystylegapmin8000-rulethickness1000;"> + <mspace id="ref0006" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac> + <mspace width="3em" depth="1em" id="num0006" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math display="block" style="font-family: numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000;"> + <mspace id="ref0007" width="3em" + depth="1em" style="background: green"/> + <mfrac> + <mspace width="3em" height="1em" id="num0007" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: numeratordisplaystylegapmin8000-rulethickness1000;"> + <mspace id="ref0006b" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac> + <mspace width="3em" depth="1em" id="num0006b" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000;"> + <mspace id="ref0007b" width="3em" + depth="1em" style="background: green"/> + <mfrac> + <mspace width="3em" height="1em" id="num0007b" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: numeratordisplaystylegapmin8000-rulethickness1000;"> + <mspace id="ref0006c" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac displaystyle="true"> + <mspace width="3em" depth="1em" id="num0006c" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: numeratordisplaystyleshiftup2000-axisheight1000-rulethickness1000;"> + <mspace id="ref0007c" width="3em" + depth="1em" style="background: green"/> + <mfrac displaystyle="true"> + <mspace width="3em" height="1em" id="num0007c" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: numeratorgapmin9000-rulethickness1000;"> + <mspace id="ref0008" width="3em" + height=".5em" depth=".5em" style="background: green"/> + <mfrac> + <mspace width="3em" depth="1em" id="num0008" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: numeratorshiftup11000-axisheight1000-rulethickness1000;"> + <mspace id="ref0009" width="3em" + depth="1em" style="background: green"/> + <mfrac> + <mspace width="3em" height="1em" id="num0009" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: rulethickness10000"> + <mfrac> + <mspace width="3em" height="1em" id="num0010" style="background: blue"/> + <mspace width="3em" depth="1em" id="den0010" style="background: green"/> + </mfrac> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-2.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-2.html new file mode 100644 index 0000000000..d09ad8272c --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-2.html @@ -0,0 +1,290 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Stack parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<meta name="assert" content="Element mfrac correctly uses the stack parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace { + font-size: 10px; + } + @font-face { + font-family: bottomdisplaystyleshiftdown5000-axisheight1000; + src: url("/fonts/math/stack-bottomdisplaystyleshiftdown5000-axisheight1000.woff"); + } + @font-face { + font-family: bottomshiftdown6000-axisheight1000; + src: url("/fonts/math/stack-bottomshiftdown6000-axisheight1000.woff"); + } + @font-face { + font-family: displaystylegapmin4000; + src: url("/fonts/math/stack-displaystylegapmin4000.woff"); + } + @font-face { + font-family: gapmin8000; + src: url("/fonts/math/stack-gapmin8000.woff"); + } + @font-face { + font-family: topdisplaystyleshiftup3000-axisheight1000; + src: url("/fonts/math/stack-topdisplaystyleshiftup3000-axisheight1000.woff"); + } + @font-face { + font-family: topshiftup9000-axisheight1000; + src: url("/fonts/math/stack-topshiftup9000-axisheight1000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("den0002").top - getBox("ref0002").bottom, + v, epsilon, "mfrac: denominator shift"); + }, "BottomDisplayStyleShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("den0002b").top - getBox("ref0002b").bottom, + v, epsilon, "mfrac: denominator shift"); + }, "BottomDisplayStyleShiftDown Displaystyle"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("den0002c").top - getBox("ref0002c").bottom, + v, epsilon, "mfrac: denominator shift"); + }, "BottomDisplayStyleShiftDown Displaystyle om fraction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 6000 * emToPx; + assert_approx_equals(getBox("den0003").top - getBox("ref0003").bottom, + v, epsilon, "mfrac: denominator shift"); + }, "BottomShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 4000 * emToPx; + assert_approx_equals(getBox("den0004").top - getBox("num0004").bottom, + v, epsilon, "mfrac: gap"); + }, "DisplayStyleGapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 4000 * emToPx; + assert_approx_equals(getBox("den0004b").top - getBox("num0004b").bottom, + v, epsilon, "mfrac: gap"); + }, "DisplayStyleGapMin Dsiplaystyle"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 4000 * emToPx; + assert_approx_equals(getBox("den0004c").top - getBox("num0004c").bottom, + v, epsilon, "mfrac: gap"); + }, "DisplayStyleGapMin Dsiplaystyle on fraction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 8000 * emToPx; + assert_approx_equals(getBox("den0005").top - getBox("num0005").bottom, + v, epsilon, "mfrac: gap"); + }, "GapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("ref0006").top - getBox("num0006").bottom, + v, epsilon, "mfrac: numerator shift"); + }, "TopDisplayStyleShiftUp"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("ref0006b").top - getBox("num0006b").bottom, + v, epsilon, "mfrac: numerator shift"); + }, "TopDisplayStyleShiftUp Displaystyle"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("ref0006c").top - getBox("num0006c").bottom, + v, epsilon, "mfrac: numerator shift"); + }, "TopDisplayStyleShiftUp Displaystyle on fraction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 9000 * emToPx; + assert_approx_equals(getBox("ref0007").top - getBox("num0007").bottom, + v, epsilon, "mfrac: numerator shift"); + }, "ToShiftUp"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 9000 * emToPx; + assert_approx_equals(getBox("ref0007b").top - getBox("num0007b").bottom, + v, epsilon, "mfrac: numerator shift"); + }, "ToShiftUp with Displaystyle on fraction"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math display="block" style="font-family: bottomdisplaystyleshiftdown5000-axisheight1000;"> + <mspace id="ref0002" width="3em" height="1em" style="background: green"/> + <mfrac linethickness="0px"> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0002" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: bottomdisplaystyleshiftdown5000-axisheight1000;"> + <mspace id="ref0002b" width="3em" height="1em" style="background: green"/> + <mfrac linethickness="0px"> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0002b" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: bottomdisplaystyleshiftdown5000-axisheight1000;"> + <mspace id="ref0002c" width="3em" height="1em" style="background: green"/> + <mfrac displaystyle="true" linethickness="0px"> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0002c" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: bottomshiftdown6000-axisheight1000;"> + <mspace id="ref0003" width="3em" height="1em" style="background: green"/> + <mfrac linethickness="0px"> + <mspace width="3em"/> + <mspace width="3em" depth="1em" id="den0003" style="background: blue"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math display="block" style="font-family: displaystylegapmin4000;"> + <mfrac linethickness="0px"> + <mspace width="3em" height="1em" id="num0004" style="background: blue"/> + <mspace width="3em" depth="1em" id="den0004" style="background: green"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: displaystylegapmin4000;"> + <mfrac linethickness="0px"> + <mspace width="3em" height="1em" id="num0004b" style="background: blue"/> + <mspace width="3em" depth="1em" id="den0004b" style="background: green"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: displaystylegapmin4000;"> + <mfrac displaystyle="true" linethickness="0px"> + <mspace width="3em" height="1em" id="num0004c" style="background: blue"/> + <mspace width="3em" depth="1em" id="den0004c" style="background: green"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: gapmin8000;"> + <mfrac linethickness="0px"> + <mspace width="3em" height="1em" id="num0005" style="background: blue"/> + <mspace width="3em" depth="1em" id="den0005" style="background: green"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math display="block" style="font-family: topdisplaystyleshiftup3000-axisheight1000;"> + <mspace id="ref0006" width="3em" depth="1em" style="background: green"/> + <mfrac linethickness="0px"> + <mspace width="3em" height="1em" id="num0006" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: topdisplaystyleshiftup3000-axisheight1000;"> + <mspace id="ref0006b" width="3em" depth="1em" style="background: green"/> + <mfrac linethickness="0px"> + <mspace width="3em" height="1em" id="num0006b" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: topdisplaystyleshiftup3000-axisheight1000;"> + <mspace id="ref0006c" width="3em" depth="1em" style="background: green"/> + <mfrac displaystyle="true" linethickness="0px"> + <mspace width="3em" height="1em" id="num0006c" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math style="font-family: topshiftup9000-axisheight1000;"> + <mspace id="ref0007" width="3em" depth="1em" style="background: green"/> + <mfrac linethickness="0px"> + <mspace width="3em" height="1em" id="num0007" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true" style="font-family: topshiftup9000-axisheight1000;"> + <mspace id="ref0007b" width="3em" depth="1em" style="background: green"/> + <mfrac displaystyle="false" linethickness="0px"> + <mspace width="3em" height="1em" id="num0007b" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-3.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-3.html new file mode 100644 index 0000000000..ddcb9d5a69 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-3.html @@ -0,0 +1,168 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Fraction/Stack parameters (fallback)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<meta name="assert" content="Element mfrac correctly uses the fraction fallback parameters."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + /* Testing fallback values is tricky as we don't have a lot of flexibility to + make sure one parameter is not shadowed by another one. We also use the + Ahem font here, so can't really play with the fallback values involved. */ + math, mspace { + font-size: 200px; /* Large value because underlineThickness is small */ + } + math { + /* OS/2.sxHeight = 800 */ + /* post.underlineThickness == 20 */ + font-family: Ahem; + } +</style> +<script> + const emToPx = 200 / 1000; // font-size: 200px, font.em = 1000 + const epsilon = 1; + const xHeight = 800; + const underlineThickness = 20; + + // NB: This test assumes the fallback shifts are all equal to zero. + const axisHeight = xHeight / 2; + const fractionRuleThickness = underlineThickness; + const fractionNumeratorGapMin = underlineThickness; + const fractionDenominatorGapMin = underlineThickness; + const fractionNumeratorDisplayStyleGapMin = 3 * underlineThickness; + const fractionDenominatorDisplayStyleGapMin = 3 * underlineThickness; + const stackGapMin = 3 * underlineThickness; + const stackDisplayStyleGapMin = 7 * underlineThickness; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(axisHeight * emToPx, + (getBox("ref0001").top - + getBox("num0001").bottom) - + (fractionRuleThickness/2 + + fractionNumeratorGapMin) * emToPx, + epsilon); + assert_approx_equals((getBox("den0002").top - + getBox("num0002").bottom), + (fractionNumeratorGapMin + + fractionRuleThickness + + fractionDenominatorGapMin) * emToPx, + epsilon); + }, "nonzero linethickness, displaystyle=false"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(axisHeight * emToPx, + (getBox("ref0003").top - + getBox("num0003").bottom) - + (fractionRuleThickness/2 + + fractionNumeratorDisplayStyleGapMin) * emToPx, + epsilon, "mfrac: thickness, axis height"); + assert_approx_equals((getBox("den0004").top - + getBox("num0004").bottom), + (fractionNumeratorDisplayStyleGapMin + + fractionRuleThickness + + fractionDenominatorDisplayStyleGapMin) * emToPx, + epsilon); + }, "nonzero linethickness, displaystyle=true"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals((getBox("ref1001").top - + getBox("num1001").bottom), + stackGapMin/2 * emToPx, + epsilon); + assert_approx_equals((getBox("den1001").top) - + getBox("ref1001").top, + stackGapMin/2 * emToPx, + epsilon); + }, "linethickness=0, displaystyle=false"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals((getBox("ref1002").top - + getBox("num1002").bottom), + stackDisplayStyleGapMin/2 * emToPx, + epsilon); + assert_approx_equals((getBox("den1002").top) - + getBox("ref1002").top, + stackDisplayStyleGapMin/2 * emToPx, + epsilon); + }, "linethickness=0, displaystyle=true"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="ref0001" height="0em" depth="1em" width="1em" style="background: green"/> + <mfrac> + <mspace width="1em" height="2em" depth="0em" id="num0001" style="background: blue"/> + <mspace width="1em" height="0em" depth="2em" id="den0001" style="background: purple"/> + </mfrac> + </math> + </p> + <p> + <math> + <mfrac> + <mspace width="1em" height="2em" depth="4em" id="num0002" style="background: blue"/> + <mspace width="1em" height="4em" depth="2em" id="den0002" style="background: purple"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true"> + <mspace id="ref0003" height="0em" depth="1em" width="1em" style="background: green"/> + <mfrac> + <mspace width="1em" height="2em" depth="0em" id="num0003" style="background: blue"/> + <mspace width="1em" height="0em" depth="2em" id="den0003" style="background: purple"/> + </mfrac> + </math> + </p> + <p> + <math displaystyle="true"> + <mfrac> + <mspace width="1em" height="2em" depth="4em" id="num0004" style="background: blue"/> + <mspace width="1em" height="4em" depth="2em" id="den0004" style="background: purple"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math> + <mspace id="ref1001" height="0em" depth="1em" width="1em" style="background: green"/> + <mfrac linethickness="0"> + <mspace width="1em" height="2em" depth="0em" id="num1001" style="background: blue"/> + <mspace width="1em" height="0em" depth="2em" id="den1001" style="background: purple"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math displaystyle="true"> + <mspace id="ref1002" height="0em" depth="1em" width="1em" style="background: green"/> + <mfrac linethickness="0"> + <mspace width="1em" height="2em" depth="0em" id="num1002" style="background: blue"/> + <mspace width="1em" height="0em" depth="2em" id="den1002" style="background: purple"/> + </mfrac> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-001-ref.html new file mode 100644 index 0000000000..06fe8d8d35 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-001-ref.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters</title> +<style> + math, mspace { + font-size: 20px; + } + @font-face { + font-family: denominatordisplaystylegapmin5000-rulethickness1000; + src: url("/fonts/math/fraction-denominatordisplaystylegapmin5000-rulethickness1000.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math display="block" style="font-family: denominatordisplaystylegapmin5000-rulethickness1000;"> + <mspace height="2em" depth="20em"/> + <mfrac> + <mspace width="3em"/> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mspace width="1em" height=".5em" depth=".5em" style="background: blue"/> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mspace width="1em" height="1em" style="background: blue"/> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mspace width="1em" depth="1em" style="background: blue"/> + </mfrac> + </math> + </p> + <div id="frame"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-001.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-001.html new file mode 100644 index 0000000000..ee31231145 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-001.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters (display gap between bar and denominator)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="match" href="frac-parameters-gap-001-ref.html"/> +<meta name="assert" content="Element mfrac correctly uses the FractionDenomDisplayStyleGapMin parameter from the MATH table when denominator contains text."> +<style> + math, mspace, mtext { + font-size: 20px; + } + mtext { + font-family: math-text; + color: blue; + } + @font-face { + font-family: denominatordisplaystylegapmin5000-rulethickness1000; + src: url("/fonts/math/fraction-denominatordisplaystylegapmin5000-rulethickness1000.woff"); + } + @font-face { + /* + math-text has the following properties: + - typo/hhea/win metrics: 2.5em ascent and 2.5em descent. + - glyph A: .5em ascent and .5em descent. + - glyph B: 1em ascent and 0em descent. + - glyph C: 0em ascent and 1em descent. + */ + font-family: math-text; + src: url("/fonts/math/math-text.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math display="block" style="font-family: denominatordisplaystylegapmin5000-rulethickness1000;"> + <!-- This is a dummy mspace element to ensure that the font ascent/descent does not affect the size of the math element. --> + <mspace height="2em" depth="20em"/> + <!-- + All the fraction bars must be aligned. + The gap between the denominators and bar must be FractionDenomDisplayStyleGapMin. + The gap should be calculated using the exact bounding box of the glyphs. + Hence glyphs A, B, C should be rendered at the same vertical position, even if they have different ascent/descent. + --> + <mfrac> + <mspace width="3em"/> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mtext>A</mtext> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mtext>B</mtext> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mtext>C</mtext> + </mfrac> + </math> + </p> + <div id="frame"></div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-002-ref.html new file mode 100644 index 0000000000..30958a6a5f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-002-ref.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters</title> +<style> + math, mspace { + font-size: 20px; + } + @font-face { + font-family: denominatorgapmin4000-rulethickness1000; + src: url("/fonts/math/fraction-denominatorgapmin4000-rulethickness1000.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math style="font-family: denominatorgapmin4000-rulethickness1000;"> + <mspace height="2em" depth="20em"/> + <mfrac> + <mspace width="3em"/> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mspace width="1em" height=".5em" depth=".5em" style="background: blue"/> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mspace width="1em" height="1em" style="background: blue"/> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mspace width="1em" depth="1em" style="background: blue"/> + </mfrac> + </math> + </p> + <div id="frame"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-002.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-002.html new file mode 100644 index 0000000000..bf77b2d910 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-002.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters (inline gap between bar and denominator)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="match" href="frac-parameters-gap-002-ref.html"/> +<meta name="assert" content="Element mfrac correctly uses the FractionDenominatorGapMin parameter from the MATH table when denominator contains text."> +<style> + math, mspace, mtext { + font-size: 20px; + } + mtext { + font-family: math-text; + color: blue; + } + @font-face { + font-family: denominatorgapmin4000-rulethickness1000; + src: url("/fonts/math/fraction-denominatorgapmin4000-rulethickness1000.woff"); + } + @font-face { + /* + math-text has the following properties: + - typo/hhea/win metrics: 2.5em ascent and 2.5em descent. + - glyph A: .5em ascent and .5em descent. + - glyph B: 1em ascent and 0em descent. + - glyph C: 0em ascent and 1em descent. + */ + font-family: math-text; + src: url("/fonts/math/math-text.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math style="font-family: denominatorgapmin4000-rulethickness1000;"> + <!-- This is a dummy mspace element to ensure that the font ascent/descent does not affect the size of the math element. --> + <mspace height="2em" depth="20em"/> + <!-- + All the fraction bars must be aligned. + The gap between the denominators and bar must be FractionDenominatorGapMin. + The gap should be calculated using the exact bounding box of the glyphs. + Hence glyphs A, B, C should be rendered at the same vertical position, even if they have different ascent/descent. + --> + <mfrac> + <mspace width="3em"/> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mtext>A</mtext> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mtext>B</mtext> + </mfrac> + <mfrac> + <mspace width="3em"/> + <mtext>C</mtext> + </mfrac> + </math> + </p> + <div id="frame"></div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-003-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-003-ref.html new file mode 100644 index 0000000000..70e2ec5a88 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-003-ref.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters</title> +<style> + math, mspace { + font-size: 20px; + } + @font-face { + font-family: numeratordisplaystylegapmin8000-rulethickness1000; + src: url("/fonts/math/fraction-numeratordisplaystylegapmin8000-rulethickness1000.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math display="block" style="font-family: numeratordisplaystylegapmin8000-rulethickness1000;"> + <mspace height="20em" depth="2em"/> + <mfrac> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mspace width="1em" depth=".5em" height=".5em" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mspace width="1em" height="1em" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mspace width="1em" depth="1em" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <div id="frame"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-003.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-003.html new file mode 100644 index 0000000000..c35c11ffdc --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-003.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters (display gap between bar and numerator)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="match" href="frac-parameters-gap-003-ref.html"/> +<meta name="assert" content="Element mfrac correctly uses the FractionNumDisplayStyleGapMin parameter from the MATH table when numerator contains text."> +<style> + math, mspace, mtext { + font-size: 20px; + } + mtext { + font-family: math-text; + color: blue; + } + @font-face { + font-family: numeratordisplaystylegapmin8000-rulethickness1000; + src: url("/fonts/math/fraction-numeratordisplaystylegapmin8000-rulethickness1000.woff"); + } + @font-face { + /* + math-text has the following properties: + - typo/hhea/win metrics: 2.5em ascent and 2.5em descent. + - glyph A: .5em ascent and .5em descent. + - glyph B: 1em ascent and 0em descent. + - glyph C: 0em ascent and 1em descent. + */ + font-family: math-text; + src: url("/fonts/math/math-text.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math display="block" style="font-family: numeratordisplaystylegapmin8000-rulethickness1000;"> + <!-- This is a dummy mspace element to ensure that the font ascent/descent does not affect the size of the math element. --> + <mspace height="20em" depth="2em"/> + <!-- + All the fraction bars must be aligned. + The gap between the numerators and bar must be FractionNumDisplayStyleGapMin. + The gap should be calculated using the exact bounding box of the glyphs. + Hence glyphs A, B, C should be rendered at the same vertical position, even if they have different ascent/descent. + --> + <mfrac> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mtext>A</mtext> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mtext>B</mtext> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mtext>C</mtext> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <div id="frame"></div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-004-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-004-ref.html new file mode 100644 index 0000000000..675d33fbcc --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-004-ref.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters</title> +<style> + math, mspace { + font-size: 20px; + } + @font-face { + font-family: numeratorgapmin9000-rulethickness1000; + src: url("/fonts/math/fraction-numeratorgapmin9000-rulethickness1000.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math style="font-family: numeratorgapmin9000-rulethickness1000;"> + <mspace height="20em" depth="2em"/> + <mfrac> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mspace width="1em" height=".5em" depth=".5em" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mspace width="1em" height="1em" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mspace width="1em" depth="1em" style="background: blue"/> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <div id="frame"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-004.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-004.html new file mode 100644 index 0000000000..6d567d02d9 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-004.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters (inline gap between bar and numerator)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="match" href="frac-parameters-gap-004-ref.html"/> +<meta name="assert" content="Element mfrac correctly uses the FractionNumeratorGapMin parameter from the MATH table when numerator contains text."> +<style> + math, mspace, mtext { + font-size: 20px; + } + mtext { + font-family: math-text; + color: blue; + } + @font-face { + font-family: numeratorgapmin9000-rulethickness1000; + src: url("/fonts/math/fraction-numeratorgapmin9000-rulethickness1000.woff"); + } + @font-face { + /* + math-text has the following properties: + - typo/hhea/win metrics: 2.5em ascent and 2.5em descent. + - glyph A: .5em ascent and .5em descent. + - glyph B: 1em ascent and 0em descent. + - glyph C: 0em ascent and 1em descent. + */ + font-family: math-text; + src: url("/fonts/math/math-text.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math style="font-family: numeratorgapmin9000-rulethickness1000;"> + <!-- This is a dummy mspace element to ensure that the font ascent/descent does not affect the size of the math element. --> + <mspace height="20em" depth="2em"/> + <!-- + All the fraction bars must be aligned. + The gap between the numerators and bar must be FractionNumeratorGapMin. + The gap should be calculated using the exact bounding box of the glyphs. + Hence glyphs A, B, C should be rendered at the same vertical position, even if they have different ascent/descent. + --> + <mfrac> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mtext>A</mtext> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mtext>B</mtext> + <mspace width="3em"/> + </mfrac> + <mfrac> + <mtext>C</mtext> + <mspace width="3em"/> + </mfrac> + </math> + </p> + <div id="frame"></div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-005-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-005-ref.html new file mode 100644 index 0000000000..c794a50047 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-005-ref.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters</title> +<style> + math, mspace { + font-size: 20px; + } + @font-face { + font-family: displaystylegapmin4000; + src: url("/fonts/math/stack-displaystylegapmin4000.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math display="block" style="font-family: displaystylegapmin4000"> + <mspace height="10em" depth="10em"/> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1em"/> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1em"/> + <mspace width="1em" height=".5em" depth=".5em" style="background: blue"/> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1.5em"/> + <mspace width="1em" height="1em" style="background: blue"/> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth=".5em"/> + <mspace width="1em" depth="1em" style="background: blue"/> + </mfrac> + </math> + </p> + <div id="frame"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-005.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-005.html new file mode 100644 index 0000000000..a0aa13e679 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-005.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Stack parameters (display gap between numerator and denominator)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="match" href="frac-parameters-gap-005-ref.html"/> +<meta name="assert" content="Element mfrac with zero linethickness correctly uses the StackDisplayStyleGapMin parameter from the MATH table when denominator contains text."> +<style> + math, mspace, mtext { + font-size: 20px; + } + mtext { + font-family: math-text; + color: blue; + } + @font-face { + font-family: displaystylegapmin4000; + src: url("/fonts/math/stack-displaystylegapmin4000.woff"); + } + @font-face { + /* + math-text has the following properties: + - typo/hhea/win metrics: 2.5em ascent and 2.5em descent. + - glyph A: .5em ascent and .5em descent. + - glyph B: 1em ascent and 0em descent. + - glyph C: 0em ascent and 1em descent. + */ + font-family: math-text; + src: url("/fonts/math/math-text.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math display="block" style="font-family: displaystylegapmin4000"> + <!-- This is a dummy mspace element to ensure that the font ascent/descent does not affect the size of the math element. --> + <mspace height="10em" depth="10em"/> + <!-- + The gap between the numerators/denominators and the math axis must StackDisplayStyleGapMin / 2. + The gap should be calculated using the exact bounding box of the glyphs. + The numerator descent is .5em + the denominator ascent. + Hence glyphs A, B, C should be rendered at the same vertical position, even if they have different ascent/descent. + --> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1em"/> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1em"/> + <mtext>A</mtext> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1.5em"/> + <mtext>B</mtext> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth=".5em"/> + <mtext>C</mtext> + </mfrac> + </math> + </p> + <div id="frame"></div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-006-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-006-ref.html new file mode 100644 index 0000000000..02faaad19f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-006-ref.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Fraction parameters</title> +<style> + math, mspace { + font-size: 20px; + } + @font-face { + font-family: gapmin8000; + src: url("/fonts/math/stack-gapmin8000.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math style="font-family: gapmin8000"> + <mspace height="10em" depth="10em"/> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1em"/> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1em"/> + <mspace width="1em" height=".5em" depth=".5em" style="background: blue"/> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1.5em"/> + <mspace width="1em" height="1em" style="background: blue"/> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth=".5em"/> + <mspace width="1em" depth="1em" style="background: blue"/> + </mfrac> + </math> + </p> + <div id="frame"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-006.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-006.html new file mode 100644 index 0000000000..1260126e55 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-parameters-gap-006.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Stack parameters (display gap between numerator and denominator)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="match" href="frac-parameters-gap-006-ref.html"/> +<meta name="assert" content="Element mfrac with zero linethickness correctly uses the StackGapMin parameter from the MATH table when denominator contains text."> +<style> + math, mspace, mtext { + font-size: 20px; + } + mtext { + font-family: math-text; + color: blue; + } + @font-face { + font-family: gapmin8000; + src: url("/fonts/math/stack-gapmin8000.woff"); + } + @font-face { + /* + math-text has the following properties: + - typo/hhea/win metrics: 2.5em ascent and 2.5em descent. + - glyph A: .5em ascent and .5em descent. + - glyph B: 1em ascent and 0em descent. + - glyph C: 0em ascent and 1em descent. + */ + font-family: math-text; + src: url("/fonts/math/math-text.woff"); + } + #reference { + background: green; + } + #frame { + position: absolute; + border-top: 4px solid black; + border-bottom: 4px solid black; + width: 100%; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + function runTests() { + var div = document.getElementById("frame"); + var refBox = document.getElementById("reference").getBoundingClientRect(); + div.style.top = `${refBox.top-2}px`; + div.style.height = `${refBox.height-4}px`; + document.documentElement.classList.remove('reftest-wait'); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +</head> +<body> + <p> + This test passes if the blue squares are aligned: + </p> + <p> + <math style="font-family: gapmin8000"> + <!-- This is a dummy mspace element to ensure that the font ascent/descent does not affect the size of the math element. --> + <mspace height="10em" depth="10em"/> + <!-- + The gap between the numerators/denominators and the math axis must StackGapMin / 2. + The gap should be calculated using the exact bounding box of the glyphs. + The numerator descent is .5em + the denominator ascent. + Hence glyphs A, B, C should be rendered at the same vertical position, even if they have different ascent/descent. + --> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1em"/> + <mspace id="reference" width="3em" height=".5em" depth=".5em"/> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1em"/> + <mtext>A</mtext> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth="1.5em"/> + <mtext>B</mtext> + </mfrac> + <mfrac linethickness="0px"> + <mspace width="3em" depth=".5em"/> + <mtext>C</mtext> + </mfrac> + </math> + </p> + <div id="frame"></div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-rendering-from-in-flow-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-rendering-from-in-flow-ref.html new file mode 100644 index 0000000000..71f1583fd9 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-rendering-from-in-flow-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>fraction rendering from in-flow children</title> + </head> + <body> + <math> + <mfrac> + <mspace width="64px" height="48px" style="background: lightblue"></mspace> + <mspace width="128px" height="96px" style="background: lightgreen"></mspace> + </mfrac> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-rendering-from-in-flow.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-rendering-from-in-flow.html new file mode 100644 index 0000000000..b57564b574 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-rendering-from-in-flow.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>fraction rendering from in-flow children</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <meta name="assert" content="Verify rendering of fractions is only affected by in-flow children."> + <style> + .oof1 { + position: absolute; + } + .oof2 { + position: fixed; + } + .nobox { + display: none; + } + </style> + <link rel="match" href="frac-rendering-from-in-flow-ref.html"> + </head> + <body> + <math> + <mfrac> + <mspace height="32px" width="24px" class="oof1"/> + <mspace height="16px" width="12px" class="oof2"/> + <mspace height="8px" width="4px" class="nobox"/> + <mspace width="64px" height="48px" style="background: lightblue"></mspace> + <mspace height="32px" width="24px" class="oof1"/> + <mspace height="16px" width="12px" class="oof2"/> + <mspace height="8px" width="4px" class="nobox"/> + <mspace width="128px" height="96px" style="background: lightgreen"></mspace> + <mspace height="32px" width="24px" class="oof1"/> + <mspace height="16px" width="12px" class="oof2"/> + <mspace height="8px" width="4px" class="nobox"/> + </mfrac> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-visibility-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-visibility-001-ref.html new file mode 100644 index 0000000000..41a262d511 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-visibility-001-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Fraction bar visibility</title> + </head> + <body> + <p>This test passes if you see a green square and no red.</p> + <div style="background: green; width: 200px; height: 200px;"> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-visibility-001.html b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-visibility-001.html new file mode 100644 index 0000000000..29212c0594 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/fractions/frac-visibility-001.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Fraction bar visibility</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <meta name="assert" content="The CSS visible property affects the rendering of the fraction bar."> + <link rel="match" href="frac-visibility-001-ref.html"> + </head> + <body> + <p>This test passes if you see a green square and no red.</p> + <div style="background: green; width: 200px; height: 200px;"> + <math> + <mfrac style="visibility: hidden; color: red"> + <mspace width="200px" height="20px"></mspace> + <mspace width="200px" height="20px"></mspace> + </mfrac> + </math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/menclose/legacy-menclose-radical-notation-ref.html b/testing/web-platform/tests/mathml/presentation-markup/menclose/legacy-menclose-radical-notation-ref.html new file mode 100644 index 0000000000..c67ac03f5d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/menclose/legacy-menclose-radical-notation-ref.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Legacy menclose radical notation (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 25px Ahem; + } + </style> + </head> + <body> + <math> + <menclose notation=""> + <mn>123</mn> + </menclose> + <menclose notation="box"> + <mn>123</mn> + </menclose> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/menclose/legacy-menclose-radical-notation.html b/testing/web-platform/tests/mathml/presentation-markup/menclose/legacy-menclose-radical-notation.html new file mode 100644 index 0000000000..353202fd7b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/menclose/legacy-menclose-radical-notation.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Legacy menclose radical notation</title> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.menclose"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.menclose"> + <meta name="assert" content="Verify that the legacy menclose radical notation is ignored."> + <link rel="match" href="legacy-menclose-radical-notation-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 25px Ahem; + } + </style> + </head> + <body> + <math> + <menclose notation="radical"> + <mn>123</mn> + </menclose> + <menclose notation="box radical"> + <mn>123</mn> + </menclose> + </math> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_menclose");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mpadded/legacy-orthogonal-pseudo-units.html b/testing/web-platform/tests/mathml/presentation-markup/mpadded/legacy-orthogonal-pseudo-units.html new file mode 100644 index 0000000000..6eebac1df9 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mpadded/legacy-orthogonal-pseudo-units.html @@ -0,0 +1,101 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Legacy mpadded pseudo-units relying on orthogonal metrics</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mpadded"> +<meta name="assert" content="Legacy pseudo-units depending on orthogonal metrics"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<style> + .testedElement { + background: red; + } +</style> +</head> +<body> + <div id="log"></div> + + <p> + <math> + <mpadded id="reference"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + + <p> + <!-- width cannot use vertical pseudo-units --> + <math> + <mpadded class="testedElement" width="200%height"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + <math> + <mpadded class="testedElement" width="200%depth"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + + <p> + <!-- lspace cannot use vertical pseudo-units --> + <math> + <mpadded class="testedElement" lspace="200%height"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + <math> + <mpadded class="testedElement" lspace="200%depth"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <p> + <!-- height cannot use horizontal pseudo-units --> + <math> + <mpadded class="testedElement" height="200%width"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <p> + <!-- depth cannot use horizontal pseudo-units --> + <math> + <mpadded class="testedElement" depth="200%width"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <p> + <!-- voffset cannot use horizontal pseudo-units --> + <math> + <mpadded class="testedElement" voffset="200%width"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> +<script type="text/javascript"> + Array.from(document.getElementsByClassName("testedElement")).forEach(mpadded => { + var reference = document.getElementById("reference"); + const name = ["width", "depth", "height", "lspace", "voffset"].find(attr => mpadded.hasAttribute(attr)); + const epsilon = 1; + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + compareLayout(mpadded, reference, epsilon); + }, `${mpadded.getAttribute(name)} is not allowed on ${name}`); + }); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-001.html b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-001.html new file mode 100644 index 0000000000..e61dc5af72 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-001.html @@ -0,0 +1,147 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mpadded</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<meta name="assert" content="Verify metrics of empty mpadded element for different values of height, depth and width"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + var epsilon = 1; + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + test(function() { + var none = getBox("none"); + assert_equals(none.width, 0, "zero width"); + assert_approx_equals(getBox("baseline").bottom - none.top, 0, epsilon, "zero depth"); + assert_approx_equals(none.bottom - getBox("baseline").bottom, 0, epsilon, "zero depth"); + }, "mpadded (no attributes)"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var mpadded = getBox("width" + i); + assert_approx_equals(mpadded.width, 25*(i+1), epsilon, "width " + i); + assert_approx_equals(getBox("baseline").bottom - mpadded.top, 0, epsilon, "height" + i); + assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, 0, epsilon, "depth" + i); + } + }, "Different widths"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var mpadded = getBox("height" + i); + assert_equals(mpadded.width, 0, "width" + i); + assert_approx_equals(getBox("baseline").bottom - mpadded.top, 25*(i+1), epsilon, "height" + i); + assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, 0, epsilon, "depth" + i); + } + }, "Different heights"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var mpadded = getBox("depth" + i); + assert_equals(mpadded.width, 0, "width" + i); + assert_approx_equals(getBox("baseline").bottom - mpadded.top, 0, epsilon, "height" + i); + assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, 25*(i+1), epsilon, "depth" + i); + } + }, "Different depths"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var mpadded = getBox("mpadded" + i); + assert_approx_equals(mpadded.width, 25*(1+i%3), epsilon, "width" + i); + assert_approx_equals(getBox("baseline").bottom - mpadded.top, 25*(1+(i+1)%3), epsilon, "height" + i); + assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, 25*(1+(i+2)%3), epsilon, "depth" + i); + } + }, "Various combinations of height, depth and width."); + + test(function() { + var container = document.getElementById("containerForPreferredWidth"); + var mpadded = container.getElementsByTagName("mpadded")[0]; + var containerWidth = container.getBoundingClientRect().width; + var mpaddedWidth = mpadded.getBoundingClientRect().width; + assert_approx_equals(containerWidth, mpaddedWidth, epsilon); + }, "Preferred width"); + + // Dynamically set attributes. + ["width", "height", "depth"].forEach(function (name, index) { + document.getElementById("dynamic-remove").removeAttribute(name); + let length = `${50 + index * 10}px`; + document.getElementById("dynamic-attach").setAttribute(name, length); + document.getElementById("dynamic-modify").setAttribute(name, length); + }); + let baseline = getBox("baseline2").bottom; + + test(function() { + let remove = getBox("dynamic-remove"); + assert_approx_equals(remove.width, 0, epsilon); + assert_approx_equals(remove.height, 0, epsilon); + assert_approx_equals(remove.top, baseline, epsilon); + }, "dynamic attributes (remove)"); + + test(function() { + let attach = getBox("dynamic-attach"); + assert_approx_equals(attach.width, 50, epsilon); + assert_approx_equals(attach.height, 60 + 70, epsilon); + assert_approx_equals(baseline - attach.top, 60, epsilon); + }, "dynamic attributes (attach)"); + + test(function() { + let modify = getBox("dynamic-modify"); + assert_approx_equals(modify.width, 50, epsilon); + assert_approx_equals(modify.height, 60 + 70, epsilon); + assert_approx_equals(baseline - modify.top, 60, epsilon); + }, "dynamic attributes (modify)"); + + done(); + } +</script> +<style> +div.shrink-wrap { + background: yellow; + display: inline-block; + margin-top: 5px; + padding-top: 5px; +} +</style> +</head> +<body> + <div id="log"></div> + <p> + <span id="baseline" style="display: inline-block; width: 30px; height: 5px; background: blue"></span> + <math> + <mpadded id="none"/> + <mpadded id="width0" width="25px"/> + <mpadded id="width1" width="50px"/> + <mpadded id="width2" width="75px"/> + <mpadded id="height0" height="25px"/> + <mpadded id="height1" height="50px"/> + <mpadded id="height2" height="75px"/> + <mpadded id="depth0" depth="25px"/> + <mpadded id="depth1" depth="50px"/> + <mpadded id="depth2" depth="75px"/> + <mpadded id="mpadded0" width="25px" height="50px" depth="75px" style="background: green"/> + <mpadded id="mpadded1" width="50px" height="75px" depth="25px" style="background: blue"/> + <mpadded id="mpadded2" width="75px" height="25px" depth="50px" style="background: green"/> + </math> + </p> + <div> + <div id="containerForPreferredWidth" class="shrink-wrap"> + <math><mpadded width="75px" height="25px" depth="50px" style="background: green"/></math> + </div> + </div> + <p> + <span id="baseline2" style="display: inline-block; width: 30px; height: 5px; background: blue"></span> + <math> + <mpadded id="dynamic-attach" style="background: lightgreen"/> + <mpadded id="dynamic-remove" width="10px" height="20px" depth="30px" style="background: lightyellow"/> + <mpadded id="dynamic-modify" width="100px" height="200px" depth="300px" style="background: pink"/> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-002.html b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-002.html new file mode 100644 index 0000000000..93f2d594c7 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-002.html @@ -0,0 +1,164 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mpadded</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<meta name="assert" content="Verify metrics of nonempty mpadded element for different values of height, depth and width"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + var epsilon = 1; + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + const contentWidth = 100; + const contentDepth = 125; + const contentHeight = 150; + + test(function() { + var none = getBox("none"); + assert_equals(none.width, contentWidth, "content width"); + assert_approx_equals(getBox("baseline").bottom - none.top, contentHeight, epsilon, "content height"); + assert_approx_equals(none.bottom - getBox("baseline").bottom, contentDepth, epsilon, "content height"); + }, "mpadded with no attributes"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var mpadded = getBox("width" + i); + assert_approx_equals(mpadded.width, 25*(i+1), epsilon, "width " + i); + assert_approx_equals(getBox("baseline").bottom - mpadded.top, contentHeight, epsilon, "height" + i); + assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, contentDepth, epsilon, "depth" + i); + } + }, "Different widths"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var mpadded = getBox("height" + i); + assert_equals(mpadded.width, contentWidth, "width" + i); + assert_approx_equals(getBox("baseline").bottom - mpadded.top, 25*(i+1), epsilon, "height" + i); + assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, contentDepth, epsilon, "depth" + i); + } + }, "Different heights"); + + test(function() { + var mpadded = getBox("percentages"); + assert_equals(mpadded.width, contentWidth, "width"); + assert_approx_equals(getBox("baseline").bottom - mpadded.top, contentHeight, epsilon, "height"); + assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, contentDepth, epsilon, "depth"); + }, "Percentage calculation for width, height and depth"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var mpadded = getBox("depth" + i); + assert_equals(mpadded.width, contentWidth, "width" + i); + assert_approx_equals(getBox("baseline2").bottom - mpadded.top, contentHeight, epsilon, "height" + i); + assert_approx_equals(mpadded.bottom - getBox("baseline2").bottom, 25*(i+1), epsilon, "depth" + i); + } + }, "Different depths"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var mpadded = getBox("mpadded" + i); + assert_approx_equals(mpadded.width, 25*(1+i%3), epsilon, "width" + i); + assert_approx_equals(getBox("baseline2").bottom - mpadded.top, 25*(1+(i+1)%3), epsilon, "height" + i); + assert_approx_equals(mpadded.bottom - getBox("baseline2").bottom, 25*(1+(i+2)%3), epsilon, "depth" + i); + } + }, "Various combinations of height, depth and width."); + + test(function() { + var container = document.getElementById("containerForPreferredWidth"); + var mpadded = container.getElementsByTagName("mpadded")[0]; + var containerWidth = container.getBoundingClientRect().width; + var mpaddedWidth = mpadded.getBoundingClientRect().width; + assert_approx_equals(containerWidth, mpaddedWidth, epsilon); + }, "Preferred width"); + + // Dynamically set attributes. + ["width", "height", "depth"].forEach(function (name, index) { + document.getElementById("dynamic-remove").removeAttribute(name); + let length = `${50 + index * 10}px`; + document.getElementById("dynamic-attach").setAttribute(name, length); + document.getElementById("dynamic-modify").setAttribute(name, length); + }); + let baseline = getBox("baseline3").bottom; + + test(function() { + let remove = getBox("dynamic-remove"); + assert_approx_equals(remove.width, contentWidth, epsilon); + assert_approx_equals(remove.height, contentHeight + contentDepth, epsilon); + assert_approx_equals(baseline - remove.top, contentHeight, epsilon); + }, "dynamic attributes (remove)"); + + test(function() { + let attach = getBox("dynamic-attach"); + assert_approx_equals(attach.width, 50, epsilon); + assert_approx_equals(attach.height, 60 + 70, epsilon); + assert_approx_equals(baseline - attach.top, 60, epsilon); + }, "dynamic attributes (attach)"); + + test(function() { + let modify = getBox("dynamic-modify"); + assert_approx_equals(modify.width, 50, epsilon); + assert_approx_equals(modify.height, 60 + 70, epsilon); + assert_approx_equals(baseline - modify.top, 60, epsilon); + }, "dynamic attributes (modify)"); + + done(); + } +</script> +<style> +div.shrink-wrap { + background: yellow; + display: inline-block; + margin-top: 5px; + padding-top: 5px; +} +</style> +</head> +<body> + <div id="log"></div> + <p> + <span id="baseline" style="display: inline-block; width: 30px; height: 5px; background: blue"></span> + <math> + <mpadded id="none"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="width0" width="25px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="width1" width="50px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="width2" width="75px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="height0" height="25px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="height1" height="50px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="height2" height="75px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="percentages" width="50%" height="33%" depth="10%"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + </math> + </p> + <p> + <span id="baseline2" style="display: inline-block; width: 30px; height: 5px; background: blue"></span> + <math> + <mpadded id="depth0" depth="25px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="depth1" depth="50px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="depth2" depth="75px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="mpadded0" width="25px" height="50px" depth="75px" style="background: green"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="mpadded1" width="50px" height="75px" depth="25px" style="background: blue"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="mpadded2" width="75px" height="25px" depth="50px" style="background: green"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + </math> + </p> + <div> + <div id="containerForPreferredWidth" class="shrink-wrap"> + <math><mpadded width="75px" height="25px" depth="50px" style="background: green"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded></math> + </div> + </div> + <p> + <span id="baseline3" style="display: inline-block; width: 30px; height: 5px; background: blue"></span> + <math> + <mpadded id="dynamic-attach" style="background: lightgreen"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="dynamic-remove" width="10px" height="20px" depth="30px" style="background: lightyellow"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + <mpadded id="dynamic-modify" width="100px" height="200px" depth="300px" style="background: pink"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-003.html b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-003.html new file mode 100644 index 0000000000..e0c24307f4 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-003.html @@ -0,0 +1,230 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mpadded</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<meta name="assert" content="Verify metrics of mpadded element with voffset and lspace"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + const contentWidth = 10; + const contentDepth = 15; + const contentHeight = 20; + const epsilon = 1; + + test(function() { + Array.from(document.getElementsByClassName("shrink-wrap")).forEach(container => { + assert_approx_equals(container.getBoundingClientRect().width, contentWidth, epsilon); + }); + }, "lspace/voffset shifts don't affect mpadded preferred width"); + + function GetShifts(mpadded) { + let mpadded_box = mpadded.getBoundingClientRect(); + let mspace_box = mpadded.firstElementChild.getBoundingClientRect(); + return { lspace: mspace_box.left - mpadded_box.left, + voffset: mpadded_box.top - mspace_box.top }; + } + + let mpaddeds = document.getElementById("static_tests").getElementsByTagName("mpadded"); + test(function() { + let baseline = document.getElementById("baseline").getBoundingClientRect().bottom; + Array.from(mpaddeds).forEach(e => { + let mpadded = e.getBoundingClientRect(); + assert_approx_equals(mpadded.width, contentWidth, epsilon); + assert_approx_equals(baseline - mpadded.top, contentHeight, epsilon); + assert_approx_equals(mpadded.bottom - baseline, contentDepth, epsilon); + + }); + }, "lspace/voffset shifts don't affect mpadded size"); + + + test(function() { + let shifts = GetShifts(mpaddeds[0]); + assert_approx_equals(shifts.lspace, 5, epsilon, "positive lspace"); + assert_approx_equals(shifts.voffset, 0, epsilon); + + shifts = GetShifts(mpaddeds[1]); + assert_approx_equals(shifts.lspace, 0, epsilon, "negative lspace is clmaped to zero"); + assert_approx_equals(shifts.voffset, 0, epsilon); + + shifts = GetShifts(mpaddeds[2]); + assert_approx_equals(shifts.lspace, 0, epsilon, "positive lspace percentage"); + assert_approx_equals(shifts.voffset, 0, epsilon); + + shifts = GetShifts(mpaddeds[3]); + assert_approx_equals(shifts.lspace, 0, epsilon, "negative lspace percentage"); + assert_approx_equals(shifts.voffset, 0, epsilon); + + shifts = GetShifts(mpaddeds[4]); + assert_approx_equals(shifts.lspace, 0, epsilon); + assert_approx_equals(shifts.voffset, 10, epsilon, "positive voffset"); + + shifts = GetShifts(mpaddeds[5]); + assert_approx_equals(shifts.lspace, 0, epsilon); + assert_approx_equals(shifts.voffset, -10, epsilon, "negative voffset"); + + shifts = GetShifts(mpaddeds[6]); + assert_approx_equals(shifts.lspace, 0, epsilon); + assert_approx_equals(shifts.voffset, 0, epsilon, "positive voffset percentage"); + + shifts = GetShifts(mpaddeds[7]); + assert_approx_equals(shifts.lspace, 0, epsilon); + assert_approx_equals(shifts.voffset, 0, epsilon, "negative voffset percentage"); + + shifts = GetShifts(mpaddeds[8]); + assert_approx_equals(shifts.lspace, 5, epsilon); + assert_approx_equals(shifts.voffset, 10, epsilon); + + shifts = GetShifts(mpaddeds[9]); + assert_approx_equals(shifts.lspace, 5, epsilon); + assert_approx_equals(shifts.voffset, -10, epsilon); + }, "content is shifted by the specified lspace/voffset"); + + mpaddeds = document.getElementById("static_tests_rtl").getElementsByTagName("mpadded"); + test(function() { + let shifts = GetShifts(mpaddeds[0]); + assert_approx_equals(shifts.lspace, -5, epsilon, "positive lspace"); + assert_approx_equals(shifts.voffset, 0, epsilon); + + shifts = GetShifts(mpaddeds[1]); + assert_approx_equals(shifts.lspace, 0, epsilon, "negative lspace is clmaped to zero"); + assert_approx_equals(shifts.voffset, 0, epsilon); + + shifts = GetShifts(mpaddeds[2]); + assert_approx_equals(shifts.lspace, 0, epsilon); + assert_approx_equals(shifts.voffset, 10, epsilon, "positive voffset"); + + shifts = GetShifts(mpaddeds[3]); + assert_approx_equals(shifts.lspace, 0, epsilon); + assert_approx_equals(shifts.voffset, -10, epsilon, "negative voffset"); + + shifts = GetShifts(mpaddeds[4]); + assert_approx_equals(shifts.lspace, -5, epsilon); + assert_approx_equals(shifts.voffset, 10, epsilon); + + shifts = GetShifts(mpaddeds[5]); + assert_approx_equals(shifts.lspace, -5, epsilon); + assert_approx_equals(shifts.voffset, -10, epsilon); + }, "content is shifted by the specified lspace/voffset (RTL)"); + + mpaddeds = document.getElementById("dynamic_tests").getElementsByTagName("mpadded"); + test(function() { + mpaddeds[0].setAttribute("lspace", "5px") + let shifts = GetShifts(mpaddeds[0]); + assert_approx_equals(shifts.lspace, 5, epsilon, "attach lspace"); + assert_approx_equals(shifts.voffset, 0, epsilon); + + mpaddeds[1].setAttribute("voffset", "10px") + shifts = GetShifts(mpaddeds[1]); + assert_approx_equals(shifts.lspace, 0, epsilon); + assert_approx_equals(shifts.voffset, 10, epsilon, "attach voffset"); + + mpaddeds[2].removeAttribute("lspace") + shifts = GetShifts(mpaddeds[2]); + assert_approx_equals(shifts.lspace, 0, epsilon, "remove lspace"); + assert_approx_equals(shifts.voffset, 10, epsilon); + + mpaddeds[3].removeAttribute("voffset") + shifts = GetShifts(mpaddeds[3]); + assert_approx_equals(shifts.lspace, 5, epsilon); + assert_approx_equals(shifts.voffset, 0, epsilon, "remove voffset"); + + mpaddeds[4].setAttribute("lspace", "15px") + shifts = GetShifts(mpaddeds[4]); + assert_approx_equals(shifts.lspace, 15, epsilon, "modify lspace"); + assert_approx_equals(shifts.voffset, 10, epsilon); + + mpaddeds[5].setAttribute("voffset", "-10px") + shifts = GetShifts(mpaddeds[5]); + assert_approx_equals(shifts.lspace, 5, epsilon); + assert_approx_equals(shifts.voffset, -10, epsilon, "modify voffset"); + }, "dynamic changes of lspace/voffset"); + + done(); + } +</script> +<style> +div.shrink-wrap { + background: yellow; + display: inline-block; + margin-top: 5px; + padding-top: 5px; +} +</style> +</head> +<body> + <div id="log"></div> + <div id="static_tests"> + <span id="baseline" style="display: inline-block; width: 30px; height: 5px; background: blue"></span> + <math> + <mpadded lspace="5px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="-5px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5%" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="-5%" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded voffset="-10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded voffset="10%" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded voffset="-10%" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5px" voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5px" voffset="-10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + <div id="static_tests_rtl"> + <math dir="rtl"> + <mpadded lspace="5px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="-5px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded voffset="-10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5px" voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5px" voffset="-10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + <div id="dynamic_tests"> + <math> + <mpadded style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5px" voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5px" voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5px" voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + <mpadded lspace="5px" voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + <div> + <div class="shrink-wrap"> + <math> + <mpadded lspace="5px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + <div class="shrink-wrap"> + <math> + <mpadded lspace="-5px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + <div class="shrink-wrap"> + <math> + <mpadded voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + <div class="shrink-wrap"> + <math> + <mpadded voffset="-10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + <div class="shrink-wrap"> + <math> + <mpadded lspace="5px" voffset="10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + <div class="shrink-wrap"> + <math> + <mpadded lspace="5px" voffset="-10px" style="background: black"><mspace width="10px" depth="15px" height="20px" style="background: green; opacity: .5"/></mpadded> + </math> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-001-ref.html new file mode 100644 index 0000000000..79d7df39d0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-001-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mpadded percentages (reference)</title> + <style> + .red { + background: red; + } + </style> + </head> + <body> + <p>This test passes if there is a green square with no red.</p> + <math display="block" + style="width: 200px; height: 200px; background: green"> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-001.html b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-001.html new file mode 100644 index 0000000000..ef2391c42b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-001.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mpadded percentages</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#inner-box-and-requested-parameters"> + <meta name="assert" content="Verify that percentage values for mpadded do not use refer to the containing block"> + <link rel="match" href="mpadded-percentage-001-ref.html"> + <style> + .red { + background: red; + } + </style> + </head> + <body> + <p>This test passes if there is a green square with no red.</p> + <math display="block" + style="width: 200px; height: 200px; background: green"> + <mpadded width="5%" height="10px" class="red"></mpadded> + <mpadded width=" 5%" height="10px" class="red"></mpadded> + <mpadded width="5% " height="10px" class="red"></mpadded> + <mpadded width="10px" height="5%" class="red"></mpadded> + <mpadded width="10px" height=" 5%" class="red"></mpadded> + <mpadded width="10px" height="5% " class="red"></mpadded> + <mpadded width="10px" depth="5%" class="red"></mpadded> + <mpadded width="10px" depth=" 5%" class="red"></mpadded> + <mpadded width="10px" depth="5% " class="red"></mpadded> + <mpadded width="10px" height="5%" depth="5%" class="red"></mpadded> + <mpadded width="10px" height=" 5%" depth=" 5%" class="red"></mpadded> + <mpadded width="10px" height="5% " depth="5% " class="red"></mpadded> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-002.html b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-002.html new file mode 100644 index 0000000000..36d1b4f389 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mpadded/mpadded-percentage-002.html @@ -0,0 +1,81 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title></title> + <link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> + <meta name="assert" content="Percentage values are interpreted as the default value"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/mathml/support/feature-detection.js"></script> + <script src="/mathml/support/layout-comparison.js"></script> + <style> + .testedElement { + background: red; + } + </style> + </head> + <body> + <div id="log"></div> + + <p> + <math> + <mpadded id="reference"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <p> + <math> + <mpadded class="testedElement" width="200%"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <p> + <math> + <mpadded class="testedElement" height="200%"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <p> + <math> + <mpadded class="testedElement" depth="200%"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <p> + <math> + <mpadded class="testedElement" lspace="200%"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <p> + <math> + <mpadded class="testedElement" voffset="200%"> + <mspace width="10px" height="20px" depth="30px" + style="background: blue"/> + </mpadded> + </math> + </p> + <script type="text/javascript"> + Array.from(document.getElementsByClassName("testedElement")).forEach(mpadded => { + var reference = document.getElementById("reference"); + const name = ["width", "depth", "height", "lspace", "voffset"].find(attr => mpadded.hasAttribute(attr)); + const epsilon = 1; + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + compareLayout(mpadded, reference, epsilon); + }, `${name}='${mpadded.getAttribute(name)}' is interpreted as the default value`); + }); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/dynamic-mrow-like-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/dynamic-mrow-like-001-ref.html new file mode 100644 index 0000000000..2f823ba955 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/dynamic-mrow-like-001-ref.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Dynamic mrow-like elements (reference)</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math { + font: 25px/1 Ahem; + background: lightblue; + } + li { + padding: 2px; + } +</style> +</head> +<body> + <ol> + <li><math class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></math></li> + <li><math class="testedElement"><mn>X</mn><mn>p</mn></math></li> + <li><math><mrow class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></mrow></math></li> + <li><math><mrow class="testedElement"><mn>X</mn><mn>p</mn></mrow></math></li> + <li><math><maction class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></maction></math></li> + <li><math><maction class="testedElement"><mn>X</mn><mn>p</mn></maction></math></li> + <li><math><merror class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></merror></math></li> + <li><math><merror class="testedElement"><mn>X</mn><mn>p</mn></merror></math></li> + <li><math><mphantom class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></mphantom></math></li> + <li><math><mphantom class="testedElement"><mn>X</mn><mn>p</mn></mphantom></math></li> + <li><math><mstyle class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></mstyle></math></li> + <li><math><mstyle class="testedElement"><mn>X</mn><mn>p</mn></mstyle></math></li> + <li><math><semantics class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></semantics></math></li> + <li><math><semantics class="testedElement"><mn>X</mn><mn>p</mn></semantics></math></li> + <li><math><unknown class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></unknown></math></li> + <li><math><unknown class="testedElement"><mn>X</mn><mn>p</mn></unknown></math></li> + <li><math><none class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></none></math></li> + <li><math><none class="testedElement"><mn>X</mn><mn>p</mn></none></math></li> + <li><math><mprescripts class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></mprescripts></math></li> + <li><math><mprescripts class="testedElement"><mn>X</mn><mn>p</mn></mprescripts></math></li> + </ol> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/dynamic-mrow-like-001.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/dynamic-mrow-like-001.html new file mode 100644 index 0000000000..79de59feec --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/dynamic-mrow-like-001.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Dynamic mrow-like elements</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<script src="/mathml/support/mathml-fragments.js"></script> +<meta name="assert" content="Dynamically set children of mrow-like elements."> +<style> + math { + font: 25px/1 Ahem; + background: lightblue; + } + li { + padding: 2px; + } +</style> +<link rel="match" href="dynamic-mrow-like-001-ref.html"> +<script> + window.addEventListener("load", function() { + + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + Array.from(document.getElementsByClassName("testedElement")).forEach(e => { + if (e.children.length == 0) { + // Add 3 children. + let mn = FragmentHelper.createElement("mn"); + mn.textContent = "X"; + e.appendChild(mn); + mn = FragmentHelper.createElement("mn"); + mn.textContent = "É"; + e.appendChild(mn); + mn = FragmentHelper.createElement("mn"); + mn.textContent = "p"; + e.insertBefore(mn, e.lastElementChild); + } else { + // Remove last child. + e.removeChild(e.lastElementChild); + } + }); + + document.documentElement.classList.remove('reftest-wait'); + }); +</script> +</head> +<body> + <ol> + <li><math class="testedElement"></math></li> + <li><math class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></math></li> + <li><math><mrow class="testedElement"></mrow></math></li> + <li><math><mrow class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></mrow></math></li> + <li><math><maction class="testedElement"></maction></math></li> + <li><math><maction class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></maction></math></li> + <li><math><merror class="testedElement"></merror></math></li> + <li><math><merror class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></merror></math></li> + <li><math><mphantom class="testedElement"></mphantom></math></li> + <li><math><mphantom class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></mphantom></math></li> + <li><math><mstyle class="testedElement"></mstyle></math></li> + <li><math><mstyle class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></mstyle></math></li> + <li><math><semantics class="testedElement"></semantics></math></li> + <li><math><semantics class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></semantics></math></li> + <li><math><unknown class="testedElement"></unknown></math></li> + <li><math><unknown class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></unknown></math></li> + <li><math><none class="testedElement"></none></math></li> + <li><math><none class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></none></math></li> + <li><math><mprescripts class="testedElement"></mprescripts></math></li> + <li><math><mprescripts class="testedElement"><mn>X</mn><mn>p</mn><mn>É</mn></mprescripts></math></li> + </ol> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/inferred-mrow-baseline.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/inferred-mrow-baseline.html new file mode 100644 index 0000000000..0086646859 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/inferred-mrow-baseline.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Baseline of inferred mrows</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> +<link rel="help" href="https://w3c.github.io/mathml-core/#error-message-merror"> +<link rel="help" href="https://w3c.github.io/mathml-core/#making-sub-expressions-invisible-mphantom"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.menclose"> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<meta name="assert" content="Baseline for mrow-like elements is correct."> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script type="text/javascript"> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() + { + ["Mrow", "Sqrt", "Style", "Error", "Phantom", "Math", "Menclose", "Mpadded", "Unknown", "Mtd", "None", "Mprescripts"].forEach((tag) => { + var x = document.getElementById(`above${tag}`).getBoundingClientRect(); + var y = document.getElementById(`below${tag}`).getBoundingClientRect(); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_equals(x.bottom, y.top); + }, `baseline alignment inside ${tag}`); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math><mrow><mspace id="aboveMrow" width="10px" height="30px" style="background: purple"></mspace><mspace id="belowMrow" width="10px" depth="30px" style="background: blue"></mspace></mrow></math> + <math><msqrt><mspace id="aboveSqrt" width="10px" height="30px" style="background: purple"></mspace><mspace id="belowSqrt" width="10px" depth="30px" style="background: blue"></mspace></msqrt></math> + <math><mstyle><mspace id="aboveStyle" width="10px" height="30px" style="background: purple"></mspace><mspace id="belowStyle" width="10px" depth="30px" style="background: blue"></mspace></mstyle></math> + <math><merror><mspace id="aboveError" width="10px" height="30px" style="background: purple"></mspace><mspace id="belowError" width="10px" depth="30px" style="background: blue"></mspace></merror></math> + <math><mphantom><mspace style="visibility: visible;" id="abovePhantom" width="10px" height="30px" style="background: purple"></mspace><mspace style="visibility: visible;" id="belowPhantom" width="10px" depth="30px" style="background: blue"></mspace></mphantom></math> + <math><mspace id="aboveMath" width="10px" height="30px" style="background: purple"></mspace><mspace id="belowMath" width="10px" depth="30px" style="background: blue"></mspace></math> + <!-- menclose is treated as <unknown> in MathML Core --> + <math><menclose notation="box"><mspace id="aboveMenclose" width="10px" height="30px" style="background: purple" +></mspace><mspace id="belowMenclose" width="10px" depth="30px" style="background: blue"></mspace></menclose></math> + <math><mpadded lspace="10px"><mspace id="aboveMpadded" width="10px" height="30px" style="background: purple" +></mspace><mspace id="belowMpadded" width="10px" depth="30px" style="background: blue"></mspace></mpadded></math> + <math><unknown><mspace id="aboveUnknown" width="10px" height="30px" style="background: purple" +></mspace><mspace id="belowUnknown" width="10px" depth="30px" style="background: blue"></mspace></unknown></math> + <math><mtable><mtr><mtd><mspace id="aboveMtd" width="10px" height="30px" style="background: purple" +></mspace><mspace id="belowMtd" width="10px" depth="30px" style="background: blue"></mspace></mtd></mtr></mtable></math> + <math><none><mspace id="aboveNone" width="10px" height="30px" style="background: purple"></mspace><mspace id="belowNone" width="10px" depth="30px" style="background: blue"></mspace></none></math> + <math><mprescripts><mspace id="aboveMprescripts" width="10px" height="30px" style="background: purple"></mspace><mspace id="belowMprescripts" width="10px" depth="30px" style="background: blue"></mspace></none></math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/inferred-mrow-stretchy.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/inferred-mrow-stretchy.html new file mode 100644 index 0000000000..614438deb3 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/inferred-mrow-stretchy.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Stretchy in inferred mrows</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> +<link rel="help" href="https://w3c.github.io/mathml-core/#error-message-merror"> +<link rel="help" href="https://w3c.github.io/mathml-core/#making-sub-expressions-invisible-mphantom"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.menclose"> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<meta name="assert" content="Operators can stretch inside mrow-like elements."> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + mo { + font-size: 10px; + font-family: axisheight5000-verticalarrow14000; + } + @font-face { + font-family: axisheight5000-verticalarrow14000; + src: url("/fonts/math/axisheight5000-verticalarrow14000.woff"); + } +</style> +<script type="text/javascript"> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + function runTests() + { + ["Mrow", "Sqrt", "Style", "Error", "Phantom", "Math", "Menclose", "Mpadded", "Unknown", "Mtd", "None", "Mprescripts"].forEach((tag) => { + var mo = document.getElementById(`mo${tag}`); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_greater_than_equal(mo.getBoundingClientRect().height, 100); + }, `operator stretching inside ${tag}`); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math><mrow><mo id="moMrow">↨</mo><mspace width="1px" height="100px" style="background: blue"></mspace></mrow></math> + <math><msqrt><mo id="moSqrt">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></msqrt></math> + <math><mstyle><mo id="moStyle">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></mstyle></math> + <math><merror><mo id="moError">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></merror></math> + <math><mphantom><mo style="visibilty: visible;" id="moPhantom">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></mphantom></math> + <math><mo id="moMath">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></math> + <!-- menclose is treated as <unknown> in MathML Core --> + <math><menclose notation="box"><mo id="moMenclose">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></menclose></math> + <math><mpadded lspace="10px"><mo id="moMpadded">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></mpadded></math> + <math><unknown><mo id="moUnknown">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></unknown></math> + <math><mtable><mtr><mtd><mo id="moMtd">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></mtd></mtr></mtable></math> + <math><none><mo id="moNone">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></none></math> + <math><mprescripts><mo id="moMprescripts">↨</mo><mspace width="1px" height="100px" style="background: magenta"></mspace></mprescripts></math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mfenced-element-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mfenced-element-001-ref.html new file mode 100644 index 0000000000..00c781b6e4 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mfenced-element-001-ref.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mfenced element</title> + </head> + <body> + <p>Test passes if you see 6 green squares and no red.</p> + <p> + <math> + <mrow> + <mspace width="30px" height="30px" style="background: green"></mspace> + <mspace width="30px" height="30px" style="background: lightgreen"></mspace> + <mspace width="30px" height="30px" style="background: green"></mspace> + </mrow> + <mrow> + <mspace width="30px" height="30px" style="background: lightgreen"></mspace> + <mspace width="30px" height="30px" style="background: green"></mspace> + <mspace width="30px" height="30px" style="background: lightgreen"></mspace> + </mrow> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mfenced-element-001.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mfenced-element-001.html new file mode 100644 index 0000000000..d39ff45f62 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mfenced-element-001.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mfenced element</title> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mfenced"> + <link rel="help" href="https://w3c.github.io/mathml-core/#new-display-math-value"> + <link rel="help" href="https://w3c.github.io/mathml-core/#mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> + <meta name="assert" content="Verify that the mfenced element is not supported."> + <link rel="match" href="legacy-mfenced-element-001-ref.html"> + </head> + <body> + <p>Test passes if you see 6 green squares and no red.</p> + <p> + <math style="color: red"> + <mfenced> + <mspace width="30px" height="30px" style="background: green"></mspace> + <mspace width="30px" height="30px" style="background: lightgreen"></mspace> + <mspace width="30px" height="30px" style="background: green"></mspace> + </mfenced> + <mfenced open="{" close="]" separators="?!"> + <mspace width="30px" height="30px" style="background: lightgreen"></mspace> + <mspace width="30px" height="30px" style="background: green"></mspace> + <mspace width="30px" height="30px" style="background: lightgreen"></mspace> + </mfenced> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-001.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-001.html new file mode 100644 index 0000000000..277529d829 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-001.html @@ -0,0 +1,188 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Legacy maction and semantics elements</title> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.maction"> +<link rel="help" href="https://w3c.github.io/mathml-core/#enlivening-expressions"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.semantics"> +<link rel="help" href="https://w3c.github.io/mathml-core/#semantics-and-presentation"> +<meta name="assert" content="Legacy maction and semantics elements are handled as mrow with special style"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script type="text/javascript"> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() + { + Array.from(document.getElementsByClassName("TestContainer")).forEach(container => { + const id = container.id; + const math = container.getElementsByTagName("math"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace(), "<mspace> is supported"); + const epsilon = 1; + compareLayout(math[0], math[1], epsilon); + }, `Element is laid out as an mrow with only first child displayed (id=${id})`); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace(), "<mspace> is supported"); + let firstChild = math[0].firstElementChild.firstElementChild; + for (var child = firstChild; child; child = child.nextElementSibling) { + var style = window.getComputedStyle(child).getPropertyValue("display"); + if (child == firstChild) { + assert_equals(style, "math", "First child has display: math"); + } else { + assert_equals(style, "none", "Other children have display: none"); + } + } + }, `Computed display of children (id=${id})`); + }); + done(); + } +</script> +<style> + mspace:nth-child(2n) { + background: lightblue; + } + mspace:nth-child(2n+1) { + background: lightgreen; + } + mrow.onlyShowFirstChild > :not(:first-child) { + display: none; + } +</style> +</head> +<body> + <div id="log"></div> + <p class="TestContainer" id="semantics"> + <math> + <semantics> + <mspace width="10px" height="10px"></mspace> + <mspace width="10px" depth="10px"></mspace> + <mspace width="10px" height="15px" depth="5px"></mspace> + <mspace width="10px" height="5px" depth="15px"></mspace> + </semantics> + </math> + <math> + <mrow class="onlyShowFirstChild"> + <mspace width="10px" height="10px"></mspace> + <mspace width="10px" depth="10px"></mspace> + <mspace width="10px" height="15px" depth="5px"></mspace> + <mspace width="10px" height="5px" depth="15px"></mspace> + </mrow> + </math> + </p> + <p class="TestContainer" id="semantics-annotations"> + <math> + <semantics> + <mspace width="10px" height="10px"></mspace> + <annotation>ANNOTATION</annotation> + <annotation-xml>ANNOTATION-XML</annotation-xml> + </semantics> + </math> + <math> + <mrow class="onlyShowFirstChild"> + <mspace width="10px" height="10px"></mspace> + <annotation>ANNOTATION</annotation> + <annotation-xml>ANNOTATION-XML</annotation-xml> + </mrow> + </math> + </p> + <p class="TestContainer" id="maction"> + <math> + <maction> + <mspace width="10px" height="10px"></mspace> + <mspace width="10px" depth="10px"></mspace> + <mspace width="10px" height="15px" depth="5px"></mspace> + <mspace width="10px" height="5px" depth="15px"></mspace> + </maction> + </math> + <math> + <mrow class="onlyShowFirstChild"> + <mspace width="10px" height="10px"></mspace> + <mspace width="10px" depth="10px"></mspace> + <mspace width="10px" height="15px" depth="5px"></mspace> + <mspace width="10px" height="5px" depth="15px"></mspace> + </mrow> + </math> + </p> + <p class="TestContainer" id="maction-toggle"> + <math> + <maction actiontype="toggle"> + <mspace width="10px" height="10px"></mspace> + <mspace width="10px" depth="10px"></mspace> + <mspace width="10px" height="15px" depth="5px"></mspace> + <mspace width="10px" height="5px" depth="15px"></mspace> + </maction> + </math> + <math> + <mrow class="onlyShowFirstChild"> + <mspace width="10px" height="10px"></mspace> + <mspace width="10px" depth="10px"></mspace> + <mspace width="10px" height="15px" depth="5px"></mspace> + <mspace width="10px" height="5px" depth="15px"></mspace> + </mrow> + </math> + </p> + <p class="TestContainer" id="maction-toggle-selection"> + <math> + <maction actiontype="toggle" selection="3"> + <mspace width="10px" height="10px"></mspace> + <mspace width="10px" depth="10px"></mspace> + <mspace width="10px" height="15px" depth="5px"></mspace> + <mspace width="10px" height="5px" depth="15px"></mspace> + </maction> + </math> + <math> + <mrow class="onlyShowFirstChild"> + <mspace width="10px" height="10px"></mspace> + <mspace width="10px" depth="10px"></mspace> + <mspace width="10px" height="15px" depth="5px"></mspace> + <mspace width="10px" height="5px" depth="15px"></mspace> + </mrow> + </math> + </p> + <p class="TestContainer" id="maction-statusline"> + <math> + <maction actiontype="statusline"> + <mspace width="10px" height="10px"></mspace> + <mtext>MESSAGE</mtext> + </maction> + </math> + <math> + <mrow class="onlyShowFirstChild"> + <mspace width="10px" height="10px"></mspace> + <mtext>MESSAGE</mtext> + </mrow> + </math> + </p> + <p class="TestContainer" id="maction-tooltip"> + <math> + <maction actiontype="tooltip"> + <mspace width="10px" height="10px"></mspace> + <mtext>MESSAGE</mtext> + </maction> + </math> + <math> + <mrow class="onlyShowFirstChild"> + <mspace width="10px" height="10px"></mspace> + <mtext>MESSAGE</mtext> + </mrow> + </math> + </p> + <p class="TestContainer" id="maction-input"> + <math> + <maction actiontype="input"> + <mspace width="10px" height="10px"></mspace> + </maction> + </math> + <math> + <mrow class="onlyShowFirstChild"> + <mspace width="10px" height="10px"></mspace> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-002-ref.html new file mode 100644 index 0000000000..4fd4b225f3 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-002-ref.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Legacy maction and semantics elements (reference)</title> +</head> +<body> + <p>This test passes if you see 4 green squares and no red.</p> + <p> + <math> + <mrow> + <mtext> + <span style="display: inline-block; width: 50px; height: 50px; background: green;"></span> + </mtext> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow style="display: inline-block"> + <span style="display: inline-block; width: 50px; height: 50px; background: green;"></span> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace style="background: green" width="50px" height="50px"></mspace> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace style="background: green" width="50px" height="50px"></mspace> + </mrow> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-002.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-002.html new file mode 100644 index 0000000000..99a5721bce --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mrow-like-elements-002.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Legacy maction and semantics elements</title> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.maction"> +<link rel="help" href="https://w3c.github.io/mathml-core/#enlivening-expressions"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.semantics"> +<link rel="help" href="https://w3c.github.io/mathml-core/#semantics-and-presentation"> +<meta name="assert" content="Verify that one can override the default rendering legacy maction and semantics elements using the display property"> +<link rel="match" href="legacy-mrow-like-elements-002-ref.html"> +</head> +<body> + <p>This test passes if you see 4 green squares and no red.</p> + <p> + <math> + <semantics> + <mspace style="display: none; background: red;" width="50px" height="50px"></mspace> + <mspace style="background: red;" width="50px" height="50px"></mspace> + <annotation style="display: math"> + <span style="display: inline-block; width: 50px; height: 50px; background: green;"></span> + </annotation> + </semantics> + </math> + </p> + <p> + <math> + <semantics> + <mspace style="display: none; background: red;" width="50px" height="50px"></mspace> + <mspace style="background: red;" width="50px" height="50px"></mspace> + <annotation-xml style="display: inline-block" encoding="text/html"> + <span style="display: inline-block; width: 50px; height: 50px; background: green;"></span> + </annotation-xml> + </semantics> + </math> + </p> + <p> + <math> + <maction actiontype="toggle"> + <mspace style="display: none; background: red" width="50px" height="50px"></mspace> + <mspace style="display: math; background: green" width="50px" height="50px"></mspace> + </maction> + </math> + </p> + <p> + <math> + <maction actiontype="toggle" selection="2"> + <mspace style="display: none; background: red" width="50px" height="50px"></mspace> + <mspace style="display: math; background: green" width="50px" height="50px"></mspace> + <mspace style="background: red" width="50px" height="50px"></mspace> + </maction> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mstyle-attributes.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mstyle-attributes.html new file mode 100644 index 0000000000..2463c40476 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/legacy-mstyle-attributes.html @@ -0,0 +1,164 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Legacy mstyle attributes</title> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mstyle"> +<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#string-literal-ms"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.menclose"> +<meta name="assert" content="Legacy mstyle attributes are ignored"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script type="text/javascript"> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() + { + Array.from(document.getElementsByClassName("TestContainer")).forEach(container => { + const tag = container.id; + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + const epsilon = 1; + const math = container.getElementsByTagName("math"); + compareLayout(math[0], math[1], epsilon); + }, `Legacy mstyle attributes do not apply to ${tag}`); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <!-- Note: mpadded attributes are not tested since MathML3 did not allow to + set them from mstyle. Also, it is not clear whether munderover's + accent/accentunder could be applied from mstyle, given that the former + clashes with mo@accent. Other legacy mstyle attributes not in MathML + Core or without visual effect are not tested. + --> + <p class="TestContainer" id="mspace"> + <math> + <mstyle width="50px" height="50px" depth="50px"> + <mspace style="background: lightblue"></mspace> + </mstyle> + </math> + <math> + <mstyle> + <mspace style="background: lightblue"></mspace> + </mstyle> + </math> + </p> + <p class="TestContainer" id="mfrac"> + <math> + <mstyle linethickness="50px"> + <mfrac> + <mn>1</mn> + <mn>2</mn> + </mfrac> + </mstyle> + </math> + <math> + <mstyle> + <mfrac> + <mn>1</mn> + <mn>2</mn> + </mfrac> + </mstyle> + </math> + </p> + <p class="TestContainer" id="mo"> + <math displaystyle="true"> + <mstyle lspace="50px" rspace="50px"> + <mn>1</mn> + <mo>A</mo> + <mn>2</mn> + </mstyle> + <mstyle movablelimits="false" largeop="false"> + <munder> + <mo>∑</mo> + <mn>3</mn> + </munder> + </mstyle> + <mstyle accent="false"> + <mover> + <mn>4</mn> + <mo>⇀</mo> + </mover> + </mstyle> + <mstyle stretchy="false" symmetric="false" maxsize="20px"> + <mrow> + <mo>|</mo> + <mspace height="100px"></mspace> + </mrow> + </mstyle> + <mstyle minsize="100px"> + <mrow> + <mo>|</mo> + <mn>4</mn> + </mrow> + </mstyle> + </math> + <math displaystyle="true"> + <mstyle> + <mn>1</mn> + <mo>A</mo> + <mn>2</mn> + </mstyle> + <mstyle> + <munder> + <mo>∑</mo> + <mn>3</mn> + </munder> + </mstyle> + <mstyle> + <mover> + <mn>4</mn> + <mo>⇀</mo> + </mover> + </mstyle> + <mstyle> + <mrow> + <mo>|</mo> + <mspace height="100px"></mspace> + </mrow> + </mstyle> + <mstyle> + <mrow> + <mo>|</mo> + <mn>4</mn> + </mrow> + </mstyle> + </math> + </p> + <!-- notation attribute is from MathML3's menclose element --> + <p class="TestContainer" id="menclose"> + <math> + <mstyle notation="box"> + <mn>1</mn> + </mstyle> + </math> + <math> + <mstyle> + <mn>1</mn> + </mstyle> + </math> + </p> + <p class="TestContainer" id="ms"> + <math> + <mstyle lquote="AAAA" rquote="BBBB"> + <ms>1</ms> + </mstyle> + </math> + <math> + <mstyle> + <ms>1</ms> + </mstyle> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/merror-001.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/merror-001.html new file mode 100644 index 0000000000..a9a021c2e9 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/merror-001.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test the merror element</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#error-message-merror"> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<meta name="assert" content="Verify default merror style and size."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + math { + font: 25px/1 Ahem; + } +</style> +</head> +<body> + <div id="log"></div> + <div> + <math> + <mrow id="reference"><mtext>AN ERROR</mtext></mrow> + <merror id="merror"><mtext>AN ERROR</mtext></merror> + </math> + </div> + <script> + test(function () { + var style = window.getComputedStyle(document.getElementById("merror")); + assert_equals(style.borderWidth, "1px"); + assert_equals(style.borderColor, "rgb(255, 0, 0)"); + assert_equals(style.borderStyle, "solid"); + assert_equals(style.backgroundColor, "rgb(255, 255, 224)"); + }, "Default CSS properties on merror"); + + test(function () { + var merrorBox = document.getElementById("merror").getBoundingClientRect(); + var referenceBox = document.getElementById("reference").getBoundingClientRect(); + assert_equals(merrorBox.width, referenceBox.width + 2); + assert_equals(merrorBox.height, referenceBox.height + 2); + }, "Bounding box is the same as mrow + 1px border"); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-fallback.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-fallback.html new file mode 100644 index 0000000000..3f9d466148 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-fallback.html @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test mrow fallback for some MathML elements</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#script-and-limit-schemata"> +<meta name="assert" content="Verify that invalid markup fallbacks to row layout."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function isValid(tagName, mspaceCount) { + switch (tagName) { + case "mfrac": + case "mroot": + case "munder": + case "mover": + case "msub": + case "msup": + return mspaceCount == 2; + case "munderover": + case "msubsup": + return mspaceCount == 3; + case "mmultiscripts": + return mspaceCount % 2 == 1; + } + } + + function runTests() { + let container = document.getElementById("container"); + const epsilon = 1; + ["mfrac", "mroot", "munder", "mover", "munderover", "msub", "msup", "msubsup", "mmultiscripts"].forEach(tag => { + let element = FragmentHelper.createElement(tag); + let reference = FragmentHelper.createElement("mrow"); + container.appendChild(element); + container.appendChild(reference); + let maxCount = tag == "mmultiscripts" ? 10 : 5; + let mspaceCount = 0; + for (let count = 0; count <= maxCount; count++) { + if (!isValid(tag, mspaceCount)) { + test(function() { + compareLayout(element, reference, epsilon); + }, `Invalid <${element.tagName}> should lay out as an mrow (count == ${count})`); + } + if (tag == "mmultiscripts" && count == maxCount / 2) { + [element, reference].forEach(el => { + el.insertAdjacentHTML("beforeend", `<mprescripts/>`); + }); + } else { + let width = (count + 1) * 10; + let height = (count + 1) * (count % 2 ? 15 : 5); + let depth = (count + 1) * (count % 2 ? 5 : 15); + [element, reference].forEach(el => { + el.insertAdjacentHTML("beforeend", `<mspace height="${height}px" depth="${depth}px" width="${width}px" style="background: black"/>`); + }); + mspaceCount++; + } + } + }); + Array.from(document.getElementById("invalidMultiscripts"). + getElementsByTagName("mmultiscripts")).forEach(element => { + let reference = element.nextElementSibling; + let description = element.dataset.description; + test(function() { + compareLayout(element, reference, epsilon); + }, `Invalid mmultiscripts should lay out as an mrow (${description})`); + }); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <div id="container"></div> + <div id="invalidMultiscripts"> + <math> + <mmultiscripts data-description="first in-flow child is an <mprescripts>"> + <mprescripts/> + <mspace height="5px" depth="15px" width="10px" style="background: black"/> + <mspace height="30px" depth="10px" width="20px" style="background: black"/> + <mspace height="15px" depth="45px" width="30px" style="background: black"/> + <mspace height="60px" depth="20px" width="40px" style="background: black"/> + + </mmultiscripts> + <mrow> + <mprescripts/> + <mspace height="5px" depth="15px" width="10px" style="background: black"/> + <mspace height="30px" depth="10px" width="20px" style="background: black"/> + <mspace height="15px" depth="45px" width="30px" style="background: black"/> + <mspace height="60px" depth="20px" width="40px" style="background: black"/> + + </mrow> + </math> + <math> + <mmultiscripts data-description="one of the even number of children after the first <mprescripts> is an <mprescripts>"> + <mspace height="5px" depth="15px" width="10px" style="background: black"/> + <mspace height="30px" depth="10px" width="20px" style="background: black"/> + <mspace height="15px" depth="45px" width="30px" style="background: black"/> + <mprescripts/> + <mspace height="60px" depth="20px" width="40px" style="background: black"/> + <mprescripts/> + <mspace height="25px" depth="75px" width="50px" style="background: black"/> + <mspace height="35px" depth="105px" width="70px" style="background: black"/> + </mmultiscripts> + <mrow> + <mspace height="5px" depth="15px" width="10px" style="background: black"/> + <mspace height="30px" depth="10px" width="20px" style="background: black"/> + <mspace height="15px" depth="45px" width="30px" style="background: black"/> + <mprescripts/> + <mspace height="60px" depth="20px" width="40px" style="background: black"/> + <mprescripts/> + <mspace height="25px" depth="75px" width="50px" style="background: black"/> + <mspace height="35px" depth="105px" width="70px" style="background: black"/> + </mrow> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-painting-order-ref.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-painting-order-ref.html new file mode 100644 index 0000000000..72694959a8 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-painting-order-ref.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mrow painting order (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + .container { + position: absolute; + left: 2em; + top: 10em; + } + math { + font: 50px/1 Ahem; + } + .hidden { + visibility: hidden; + } + </style> + </head> + <body> + <p>This test passes if there is no red and content is stacked such that</p> + <ul> + <li>foreground (dark colors) is above background (light colors)</li> + <li>yellow foreground is above green foreground which is itself above blue foreground</li> + <li>yellow background is above green background which is itself above blue background</li> + </ul> + <!-- Paint lightblue background --> + <div class="container"> + <math> + <mrow> + <mrow style="background: lightblue"><mn class="hidden">XXÉ</mn></mrow> + </mrow> + </math> + </div> + <!-- Paint lightgreen background --> + <div class="container"> + <math> + <mrow> + <mn class="hidden">XXÉX</mn> + <mrow style="background: lightgreen; margin-inline-start: -3em"><mn style="visibility: hidden">p XXÉ</mn></mrow> + </mrow> + </math> + </div> + <!-- Paint lightyellow background --> + <div class="container"> + <math> + <mrow> + <mn class="hidden">XXÉX</mn> + <mn class="hidden" style="margin-inline-start: -3em">p XXÉX</mn> + <mrow style="background: lightyellow; margin-inline-start: -3em"><mn style="visibility: hidden">p X</mn></mrow> + </mrow> + </math> + </div> + <!-- Paint blue foreground --> + <div class="container"> + <math> + <mrow> + <mn style="color: blue;">XXÉ</mn> + </mrow> + </math> + </div> + <!-- Paint green foreground --> + <div class="container"> + <math> + <mrow> + <mn class="hidden">XXÉX</mn> + <mn style="color: green; margin-inline-start: -3em">p XXÉ</mn> + </mrow> + </math> + </div> + <!-- Paint yellow foreground --> + <div class="container"> + <math> + <mrow> + <mn class="hidden">XXÉX</mn> + <mn class="hidden" style="margin-inline-start: -3em">p XXÉX</mn> + <mn style="color: yellow; margin-inline-start: -3em">p X</mn> + </mrow> + </math> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-painting-order.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-painting-order.html new file mode 100644 index 0000000000..516359a545 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-painting-order.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mrow painting order</title> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mfenced"> + <link rel="help" href="https://w3c.github.io/mathml-core/#stacking-contexts"> + <link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> + <meta name="assert" content="Verify in which order the children paint"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <link rel="match" href="mrow-painting-order-ref.html"> + <style> + .container { + position: absolute; + left: 2em; + top: 10em; + } + math { + font: 50px/1 Ahem; + } + </style> + </head> + <body> + <p>This test passes if there is no red and content is stacked such that</p> + <ul> + <li>foreground (dark colors) is above background (light colors)</li> + <li>yellow foreground is above green foreground which is itself above blue foreground</li> + <li>yellow background is above green background which is itself above blue background</li> + </ul> + <div class="container"> + <math> + <mrow> + <mn style="color: blue; background: lightblue">XXÉ</mn> + <mn style="color: red">X</mn> + <mn style="color: green; background: lightgreen; margin-inline-start: -3em">p XXÉ</mn> + <mn style="color: red">X</mn> + <mn style="color: yellow; background: lightyellow; margin-inline-start: -3em">p X</mn> + </mrow> + </math> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-preferred-width.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-preferred-width.html new file mode 100644 index 0000000000..8f0e3216c1 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/mrow-preferred-width.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Preferred width of mrow-like elements</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> +<link rel="help" href="https://w3c.github.io/mathml-core/#making-sub-expressions-invisible-mphantom"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<meta name="assert" content="The preferred width of mrow-like elements is the sum of children's width, modulo extra spacing."> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script type="text/javascript"> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() + { + var epsilon = 1; + + function MrowWidthFromChildren(mrow) { + var first = mrow.firstElementChild.getBoundingClientRect(); + var last = mrow.lastElementChild.getBoundingClientRect(); + return last.right - first.left; + } + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + Array.from(document.getElementById("mspace-tests").getElementsByClassName("shrink-wrap")).forEach((container) => { + var containerWidth = container.getBoundingClientRect().width; + var mrow = container.getElementsByClassName("mrow-like")[0]; + var mrowWidth = MrowWidthFromChildren(mrow); + assert_approx_equals(containerWidth, mrowWidth, epsilon, mrow.tagName); + }); + }, "Preferred width of mrow with mspace children"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + + Array.from(document.getElementById("tokens-tests").getElementsByClassName("shrink-wrap")).forEach((container) => { + var containerWidth = container.getBoundingClientRect().width; + var mrow = container.getElementsByClassName("mrow-like")[0]; + var mrowWidth = MrowWidthFromChildren(mrow); + assert_approx_equals(containerWidth, mrowWidth, epsilon, mrow.tagName); + }); + }, "Preferred width of mrow with mn and mo children"); + + done(); + } +</script> +<style> +div.shrink-wrap { + background: yellow; + display: inline-block; + margin-top: 5px; + padding-top: 5px; +} +</style> +</head> +<body> + <div id="log"></div> + <div id="mspace-tests"> + <div><div class="shrink-wrap"> + <math><mrow class="mrow-like"><mspace width="30px" height="15px" style="background: blue"/><mspace width="20px" depth="30px" style="background: green"/><mspace width="15px" height="5px" depth="10px" style="background: black"/></mrow></math> + </div></div> + <div> + <div class="shrink-wrap"> + <math><mstyle class="mrow-like"><mspace width="30px" height="15px" style="background: blue"/><mspace width="20px" depth="30px" style="background: green"/><mspace width="15px" height="5px" depth="10px" style="background: black"/></mstyle></math> + </div> + </div> + <div> + <div class="shrink-wrap"> + <math><mphantom class="mrow-like"><mspace width="30px" height="15px" style="background: blue"/><mspace width="20px" depth="30px" style="background: green"/><mspace width="15px" height="5px" depth="10px" style="background: black"/></mphantom></math> + </div> + </div> + <div> + <div class="shrink-wrap"> + <math class="mrow-like"><mspace width="30px" height="15px" style="background: blue"/><mspace width="20px" depth="30px" style="background: green"/><mspace width="15px" height="5px" depth="10px" style="background: black"/></math> + </div> + </div> + <div> + <div class="shrink-wrap"> + <math><unknown class="mrow-like"><mspace width="30px" height="15px" style="background: blue"/><mspace width="20px" depth="30px" style="background: green"/><mspace width="15px" height="5px" depth="10px" style="background: black"/></unknown></math> + </div> + </div> + <div> + </div> + </div> + <div id="tokens-tests"> + <div> + <div class="shrink-wrap"> + <math><mrow class="mrow-like"><mtext>blah</mtext><mo lspace="30px" rspace="20px">|</mo><mn>2</mn></mrow></math> + </div> + </div> + <div> + <div class="shrink-wrap"> + <math><mstyle class="mrow-like"><mtext>blah</mtext><mo lspace="30px" rspace="20px">|</mo><mn>2</mn></mstyle></math> + </div> + </div> + <div> + <div class="shrink-wrap"> + <math><mphantom class="mrow-like"><mtext>blah</mtext><mo lspace="30px" rspace="20px">|</mo><mn>2</mn></mphantom></math> + </div> + </div> + <div> + <div class="shrink-wrap"> + <math class="mrow-like"><mtext>blah</mtext><mo lspace="30px" rspace="20px">|</mo><mn>2</mn></math> + </div> + </div> + <div> + <div class="shrink-wrap"> + <math><unknown class="mrow-like"><mtext>blah</mtext><mo lspace="30px" rspace="20px">|</mo><mn>2</mn></unknown></math> + </div> + </div> + </div> +</p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/no-spacing.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/no-spacing.html new file mode 100644 index 0000000000..a2e7eb7d8d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/no-spacing.html @@ -0,0 +1,139 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>No spacing in elements</title> +<meta name="assert" content="Spacing is not added around operators when an element does not use mrow layout. However, when the element is embellished, spacing of the core mo is added around it."> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts"> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<script type="text/javascript"> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + function runTests() + { + Array.from(document.getElementsByClassName("testedElement")).forEach((e) => { + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + let box = e.getBoundingClientRect(); + let spacing = 100; + assert_less_than_equal(box.width, spacing); + }, `Spacing inside <${e.tagName}>.`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + let box = e.parentNode.getBoundingClientRect(); + let spacing = 100; + if (e.classList.contains("embellished")) + assert_greater_than_equal(box.width, spacing * 2); + else + assert_less_than_equal(box.width, spacing); + }, `Spacing around <${e.tagName}>.`); + }); + done(); + } +</script> +<style> + .testedElement { + background: lightgreen; + } + math { + background: lightblue; + } + math, math * { + font: 25px/1 Ahem; + } +</style> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mfrac class="testedElement embellished"> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + </mfrac> + </math> + </p> + <p> + <math> + <msub class="testedElement embellished"> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + </msub> + </math> + </p> + <p> + <math> + <msup class="testedElement embellished"> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + </msup> + </math> + </p> + <p> + <math> + <msubsup class="testedElement embellished"> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + </msubsup> + </math> + </p> + <p> + <math> + <mmultiscripts class="testedElement embellished"> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + <mprescripts/> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + </mmultiscripts> + </math> + </p> + <p> + <math> + <munder class="testedElement embellished"> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + </munder> + </math> + </p> + <p> + <math> + <mover class="testedElement embellished"> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + </mover> + </math> + </p> + <p> + <math> + <munderover class="testedElement embellished"> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + <mo lspace="100px" rspace="100px">X</mo> + </munderover> + </math> + </p> + <p> + <math> + <mroot class="testedElement"> + <mtext>X</mtext> + <mo lspace="100px" rspace="100px">X</mo> + </mroot> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/spacing.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/spacing.html new file mode 100644 index 0000000000..c066f72cde --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/spacing.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Spacing in mrows</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> +<link rel="help" href="https://w3c.github.io/mathml-core/#error-message-merror"> +<link rel="help" href="https://w3c.github.io/mathml-core/#making-sub-expressions-invisible-mphantom"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.menclose"> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<meta name="assert" content="Spacing is added around operators inside mrow-like elements."> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script type="text/javascript"> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + function runTests() + { + ["Mrow", "Sqrt", "Style", "Error", "Phantom", "Math", "Menclose", "Mpadded", "Unknown", "Mtd"].forEach((tag) => { + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var mrow = document.getElementById(tag); + var mn1 = mrow.firstElementChild.getBoundingClientRect(); + var mn2 = mrow.lastElementChild.getBoundingClientRect(); + assert_greater_than_equal(mn2.left - mn1.right, 50); + }, `operator spacing inside ${tag}`); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math><mrow id="Mrow"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></mrow></math> + <math><msqrt id="Sqrt"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></msqrt></math> + <math><mstyle id="Style"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></mstyle></math> + <math><merror id="Error"><mn>1</mn><mo lspace="50px"></mo><mn>2</mn></merror></math> + <math><mphantom id="Phantom"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></mphantom></math> + <math id="Math"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></math> + <!-- menclose is treated as <unknown> in MathML Core --> + <math><menclose id="Menclose" notation="box"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></menclose></math> + <math><mpadded id="Mpadded" lspace="10px"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></mpadded></math> + <math><unknown id="Unknown"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></unknown></math> + <math><mtable><mtr><mtd id="Mtd"><mn>1</mn><mo lspace="50px">|</mo><mn>2</mn></mtd></mtr></mtable></math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/mrow/stretch-along-block-axis-001.html b/testing/web-platform/tests/mathml/presentation-markup/mrow/stretch-along-block-axis-001.html new file mode 100644 index 0000000000..31385f5388 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/mrow/stretch-along-block-axis-001.html @@ -0,0 +1,176 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Stretching operators along the block axis</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#dfn-algorithm-for-stretching-operators-along-the-block-axis"> +<meta name="assert" content=""> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math { + font: 25px/1 Ahem; + } + @font-face { + font-family: stretchy; + src: url("/fonts/math/stretchy.woff"); + } + mo { + font-family: stretchy; + } +</style> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + + var epsilon = 2; + var emToPx = 25; + var element; + + test(function() { + element = document.getElementById("horizontal_arrow"); + assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "horizontal characters don't stretch vertically"); + + element = document.getElementById("vertical_arrow"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "vertical characters stretch vertically"); + }, `Taking into account stretch axis.`); + + test(function() { + element = document.getElementById("non_stretchy_horizontal_arrow"); + assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "horizontal characters don't stretch vertically"); + + element = document.getElementById("non_stretchy_vertical_arrow"); + assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "vertical characters stretch vertically"); + }, `Taking into account stretchy property.`); + + test(function() { + // There are only stretchy operators : the maximum of their base sizes + // is used as the target size. + let tallest_base_size = 2 * emToPx; + + element = document.getElementById("small_vertical"); + assert_approx_equals(element.getBoundingClientRect().width, .5 * emToPx, epsilon, "small width"); + assert_approx_equals(element.getBoundingClientRect().height, tallest_base_size, epsilon, "height is the max(.5em, 1em, 2em)"); + + element = document.getElementById("medium_vertical"); + assert_approx_equals(element.getBoundingClientRect().width, 1 * emToPx, epsilon, "normal width"); + assert_approx_equals(element.getBoundingClientRect().height, tallest_base_size, epsilon, "height is the max(.5em, 1em, 2em)"); + + element = document.getElementById("big_vertical"); + assert_approx_equals(element.getBoundingClientRect().width, 2 * emToPx, epsilon, "large width"); + assert_approx_equals(element.getBoundingClientRect().height, tallest_base_size, epsilon, "height is the max(.5em, 1em, 2em)"); + + }, `Only operators with a stretchy property and block stretch axis.`); + + test(function() { + // There are non-stretchy operators : the maximum of their base sizes + // is used as the target size. In any case, operators remain at least + // as large as their base size. + + element = document.getElementById("smaller_op"); + assert_approx_equals(element.getBoundingClientRect().width, .5 * emToPx, epsilon, "small width"); + assert_approx_equals(element.getBoundingClientRect().height, 1.5 * emToPx, epsilon, "height is the max(.5em, 1em)"); + + element = document.getElementById("bigger_op"); + assert_approx_equals(element.getBoundingClientRect().width, 2 * emToPx, epsilon, "large width"); + assert_approx_equals(element.getBoundingClientRect().height, 2 * emToPx, epsilon, "height is the max(1em, 2em)"); + + }, `Operators smaller and larger than non-stretchy siblings.`); + + test(function() { + element = document.getElementById("core_operator_1"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "mrow"); + + element = document.getElementById("core_operator_2"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "munder"); + + element = document.getElementById("core_operator_3"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "mover"); + + element = document.getElementById("core_operator_4"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "mundeover"); + + element = document.getElementById("core_operator_5"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "complex nesting"); + }, `Embellished operators`); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow> + <mspace width="1em" height="3em" depth="3em" style="background: blue"/> + <mo id="horizontal_arrow" stretchy="true">⥚</mo> + <mo id="vertical_arrow" stretchy="true">⥜</mo> + <mo id="non_stretchy_horizontal_arrow" stretchy="false">⥚</mo> + <mo id="non_stretchy_vertical_arrow" stretchy="false">⥜</mo> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <!-- This contains only vertical stretchy operators. --> + <mo style="font-size: 50%" id="small_vertical" stretchy="true">⥜</mo> + <mo style="font-size: 200%" id="big_vertical" stretchy="true">⥜</mo> + <mo style="font-size: 100%" id="medium_vertical" stretchy="true">⥜</mo> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace style="background: blue" width="1em" height=".75em"/> + <mo style="font-size: 50%" id="smaller_op" stretchy="true">⥜</mo> + <mspace style="background: blue" width="1em" height="1.5em"/> + <mo style="font-size: 200%" id="bigger_op" stretchy="true">⥜</mo> + <mspace style="background: blue" width="1em" height="1em"/> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="3em" depth="3em" style="background: blue"/> + <mrow><mo id="core_operator_1" stretchy="true">⥜</mo></mrow> + <munder> + <mo id="core_operator_2" stretchy="true">⥜</mo> + <mspace></mspace> + </munder> + <mover> + <mo id="core_operator_3" stretchy="true">⥜</mo> + <mspace></mspace> + </mover> + <munderover> + <mo id="core_operator_4" stretchy="true">⥜</mo> + <mspace></mspace> + </munderover> + <mrow> + <mspace></mspace> + <munderover> + <mover> + <munder> + <mrow> + <mo id="core_operator_5" stretchy="true">⥜</mo> + </mrow> + <mspace></mspace> + </munder> + <mspace></mspace> + </mover> + <mspace></mspace> + <mspace></mspace> + </munderover> + </mrow> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001-crash.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001-crash.html new file mode 100644 index 0000000000..15e9a0367c --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001-crash.html @@ -0,0 +1,10 @@ +<!DOCTYPE> +<!-- See https://github.com/w3c/mathml-core/issues/108 --> +<math> + <mrow style="display: inline">A</mrow> +</math> +<math> + <mrow> + <mrow style="display: inline">A</mrow> + </mrow> +</math> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001.html new file mode 100644 index 0000000000..b8e2cefc1c --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001.html @@ -0,0 +1,521 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Embellished operators</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<meta name="assert" content="Verify definition of embellished operators"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/box-navigation.js"></script> +<style> + /* Default spacing of operator 'X' is 0.2777777777777778em so quite different + from the measured/specified 0em and 1em. */ + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + .testedElement mo { + color: yellow !important; + } + .testedElement, .testedElement * { + color: blue !important; + background: blue !important; + } + .oof1 { + position: absolute; + } + .oof2 { + position: fixed; + } + .nobox { + display: none; + } +</style> +<script> + function spaceBeforeElement(id) { + var element = document.getElementById(id); + var mnBefore = previousInFlowSibling(element); + return element.getBoundingClientRect().left - mnBefore.getBoundingClientRect().right; + } + + function spaceBeforeCoreOperator(id) { + var element = document.getElementById(id); + var coreMo = element.getElementsByTagName("mo")[0]; + return coreMo.getBoundingClientRect().left - element.getBoundingClientRect().left; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + + ["mrow", "mstyle", "mphantom", "mpadded", "merror", "mprescripts", "none", "unknown"].forEach(tag => { + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBeforeElement(`${tag}-op-1`), 2 * emToPx, epsilon); + assert_approx_equals(spaceBeforeCoreOperator(`${tag}-op-1`), 0, epsilon); + }, `${tag} (embellished operator)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBeforeElement(`${tag}-op-2`), 2 * emToPx, epsilon); + assert_approx_equals(spaceBeforeCoreOperator(`${tag}-op-2`), 0, epsilon); + }, `${tag} (embellished operator, from in-flow children)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBeforeElement(`${tag}-nonop-1`), 0, epsilon); + assert_approx_equals(spaceBeforeCoreOperator(`${tag}-nonop-1`), 2 * emToPx, epsilon); + }, `${tag} (not embellished operator)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBeforeElement(`${tag}-nonop-2`), 0, epsilon); + assert_approx_equals(spaceBeforeCoreOperator(`${tag}-nonop-2`), 2 * emToPx, epsilon); + }, `${tag} (not embellished operator, from in-flow children)`); + }); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <!-- mrow is an embellished operator if its in-flow children consist + of one embellished operator and zero or more space-like elements. --> + <p> + <math> + <mn>X</mn> + <mrow id="mrow-op-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mtext class="space-like">X</mtext> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow id="mrow-nonop-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> <!-- "mn" is not space-like --> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mrow id="mrow-op-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext class="space-like">X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mrow id="mrow-nonop-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- "mn" is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <!-- mstyle is an embellished operator if its in-flow children consist + of one embellished operator and zero or more space-like elements. --> + <p> + <math> + <mn>X</mn> + <mstyle id="mstyle-op-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </mstyle> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mstyle id="mstyle-nonop-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> <!-- "mn" is not space-like --> + </mstyle> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mstyle id="mstyle-op-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mstyle id="mstyle-nonop-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- "mn" is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <!-- mphantom is an embellished operator if its in-flow children consist + of one embellished operator and zero or more space-like elements. --> + <p> + <math> + <mn>X</mn> + <mphantom id="mphantom-op-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </mphantom> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mphantom id="mphantom-nonop-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> <!-- "mn" is not space-like --> + </mphantom> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mphantom id="mphantom-op-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mphantom id="mphantom-nonop-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- "mn" is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <!-- mpadded is an embellished operator if its in-flow children consist + of one embellished operator and zero or more space-like elements. --> + <p> + <math> + <mn>X</mn> + <mpadded id="mpadded-op-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </mpadded> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mpadded id="mpadded-nonop-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> <!-- "mn" is not space-like --> + </mpadded> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mpadded id="mpadded-op-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mpadded id="mpadded-nonop-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- "mn" is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <!-- merror is an embellished operator if its in-flow children consist + of one embellished operator and zero or more space-like elements. --> + <p> + <math> + <mn>X</mn> + <merror id="merror-op-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </merror> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <merror id="merror-nonop-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> <!-- "mn" is not space-like --> + </merror> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <merror id="merror-op-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </merror> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <merror id="merror-nonop-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- "mn" is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </merror> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <!-- mprescripts is an embellished operator if its in-flow children consist + of one embellished operator and zero or more space-like elements. --> + <p> + <math> + <mn>X</mn> + <mprescripts id="mprescripts-op-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </mprescripts> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mprescripts id="mprescripts-nonop-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> <!-- "mn" is not space-like --> + </mprescripts> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mprescripts id="mprescripts-op-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mprescripts> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mprescripts id="mprescripts-nonop-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- "mn" is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mprescripts> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <!-- none is an embellished operator if its in-flow children consist + of one embellished operator and zero or more space-like elements. --> + <p> + <math> + <mn>X</mn> + <none id="none-op-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </none> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <none id="none-nonop-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> <!-- "mn" is not space-like --> + </none> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <none id="none-op-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </none> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <none id="none-nonop-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- "mn" is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </none> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <!-- unknown is an embellished operator if its in-flow children consist + of one embellished operator and zero or more space-like elements. --> + <p> + <math> + <mn>X</mn> + <unknown id="unknown-op-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </unknown> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <unknown id="unknown-nonop-1" class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> <!-- "mn" is not space-like --> + </unknown> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <unknown id="unknown-op-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </unknown> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <unknown id="unknown-nonop-2" class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- "mn" is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </unknown> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-002.html new file mode 100644 index 0000000000..7ab05441c3 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-002.html @@ -0,0 +1,559 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Embellished operators</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<meta name="assert" content="Verify definition of embellished operators"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/box-navigation.js"></script> +<style> + /* Default spacing of operator 'X' is 0.2777777777777778em so quite different + from the measured/specified 0em and 1em. */ + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + mtext.space-like { + color: lightblue !important; + } + .testedElement mo { + color: yellow !important; + } + .testedElement, .testedElement * { + color: blue !important; + background: blue !important; + } + .oof1 { + position: absolute; + } + .oof2 { + position: fixed; + } + .nobox { + display: none; + } +</style> +<script> + function spaceBeforeElement(element) { + var mnBefore = previousInFlowSibling(element); + return element.getBoundingClientRect().left - mnBefore.getBoundingClientRect().right; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + + ["msub", "msup", "msubsup", "munder", "mover", "munderover", + "mmultiscripts", "mfrac"].forEach(tag => { + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[0]; + assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon); + }, `${tag} (embellished operator)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[1]; + assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon); + }, `${tag} (embellished operator, from in-flow children)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[2]; + assert_approx_equals(spaceBeforeElement(element), 0, epsilon); + }, `${tag} (not embellished operator)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[3]; + assert_approx_equals(spaceBeforeElement(element), 0, epsilon); + }, `${tag} (not embellished operator, from in-flow children)`); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <!-- <msub>, <msup>, <msubsup>, <munder>, <mover>, <munderover>, + <mmultiscripts>, <mfrac> are embellished + operators if their first in-flow + child exists and is an embellished operator --> + <p> + <math> + <mn>X</mn> + <msub class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + </msub> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <msup class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + </msup> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <msubsup class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + <mn>X</mn> + </msubsup> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <munder class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + </munder> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mover class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + </mover> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <munderover class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + </munderover> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mmultiscripts class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + <mn>X</mn> + <mn>X</mn> + <mn>X</mn> + </mmultiscripts> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mfrac class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + </mfrac> + <mn>X</mn> + </math> + </p> + + <!-- Only in-flow children affect determination of embellished operators. --> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <msub class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </msub> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <msup class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </msup> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <msubsup class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </msubsup> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <munder class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </munder> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mover class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mover> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <munderover class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </munderover> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mmultiscripts class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mmultiscripts> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mfrac class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mfrac> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + + <!-- <msub>, <msup>, <msubsup>, <munder>, <mover>, <munderover>, + <mmultiscripts>, <mfrac> are not embellished + operators if their first in-flow child is not an embellished operator --> + <p> + <math> + <mn>X</mn> + <msub class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </msub> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <msup class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </msup> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <msubsup class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + </msubsup> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <munder class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </munder> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mover class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </mover> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <munderover class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </munderover> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mmultiscripts class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + <mn>X</mn> + <mn>X</mn> + </mmultiscripts> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mfrac class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </mfrac> + <mn>X</mn> + </math> + </p> + + <!-- Only in-flow children affect determination of embellished operators. --> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <msub class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </msub> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <msup class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </msup> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <msubsup class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </msubsup> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <munder class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </munder> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mover class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mover> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <munderover class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </munderover> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mmultiscripts class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mmultiscripts> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mfrac class="testedElement"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mfrac> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-003.html new file mode 100644 index 0000000000..7b36665787 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-003.html @@ -0,0 +1,394 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Embellished operators</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<meta name="assert" content="Verify definition of embellished operators"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/box-navigation.js"></script> +<style> + /* Default spacing of operator 'X' is 0.2777777777777778em so quite different + from the measured/specified 0em and 1em. */ + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + mtext.space-like { + color: lightblue !important; + } + .testedElement mo { + color: yellow !important; + } + .testedElement, .testedElement * { + color: blue !important; + background: blue !important; + } + .oof1 { + position: absolute; + } + .oof2 { + position: fixed; + } + .nobox { + display: none; + } + .allChildrenVisible > *:not(.nobox) { + display: inline math; + } +</style> +<script> + function spaceBeforeElement(element) { + var mnBefore = previousInFlowSibling(element); + return element.getBoundingClientRect().left - mnBefore.getBoundingClientRect().right; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + + ["maction", "semantics"].forEach(tag => { + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[0]; + assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon); + }, `${tag} (embellished operator)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[1]; + assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon); + }, `${tag} (embellished operator, from in-flow children)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[2]; + assert_approx_equals(spaceBeforeElement(element), 0, epsilon); + }, `${tag} (not embellished operator)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[3]; + assert_approx_equals(spaceBeforeElement(element), 0, epsilon); + }, `${tag} (not embellished operator, from in-flow children)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[4]; + assert_approx_equals(spaceBeforeElement(element), 0, epsilon); + }, `${tag} (not embellished operator, empty)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[5]; + assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon); + }, `${tag} (embellished operator, one child)`); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var element = document.getElementsByTagName(tag)[6]; + assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon); + }, `${tag} (embellished operator, complex)`); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <!-- <semantics> or <maction> are embellished operators if their children + consist (in any order) of one embellished operator and zero or more + space-like elements. --> + <p> + <math> + <mn>X</mn> + <maction class="testedElement" actiontype="statusline"> + <mo lspace="2em" rspace="0em">X</mo> + <mn>STATUS MESSAGE</mn> + </maction> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <semantics class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <annotation>TEXT ANNOTATION</annotation> + <mn>X</mn> + </semantics> + <mn>X</mn> + </math> + </p> + + <!-- Only in-flow children affect determination of embellished operators. --> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <maction class="testedElement" actiontype="statusline"> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>STATUS MESSAGE</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </maction> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <semantics class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <annotation>TEXT ANNOTATION</annotation> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </semantics> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + + <!-- <semantics> or <maction> are not embellished + operators if their first in-flow child is not an embellished operator --> + <p> + <math> + <mn>X</mn> + <msub class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </msub> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <msup class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </msup> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <msubsup class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + </msubsup> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <munder class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </munder> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mover class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </mover> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <munderover class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </munderover> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mmultiscripts class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn>X</mn> + <mn>X</mn> + <mn>X</mn> + </mmultiscripts> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mfrac class="testedElement"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </mfrac> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <maction class="testedElement" actiontype="statusline"> + <mn>X</mn> + <mo lspace="2em" rspace="0em">STATUS MESSAGE</mo> + </maction> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <semantics class="testedElement"> + <mrow> + <mn>X</mn> + <mo lspace="2em" rspace="0em">X</mo> + </mrow> + <annotation>TEXT ANNOTATION</annotation> + </semantics> + <mn>X</mn> + </math> + </p> + + <!-- Only in-flow children affect determination of embellished operators. --> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <maction class="testedElement" actiontype="statusline"> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">STATUS MESSAGE</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </maction> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <semantics class="testedElement"> + <mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <annotation>TEXT ANNOTATION</annotation> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </semantics> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + + <!-- Empty <maction> and <semantics> (invalid in MathML3). --> + <p> + <math> + <mn>X</mn> + <maction class="testedElement"> + </maction> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <semantics class="testedElement"> + </semantics> + <mn>X</mn> + </math> + </p> + + <!-- One-child <maction> and <semantics> (invalid in MathML3). --> + <p> + <math> + <mn>X</mn> + <maction class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </maction> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <semantics class="testedElement"> + <mo lspace="2em" rspace="0em">X</mo> + </semantics> + <mn>X</mn> + </math> + </p> + + <!-- Complex structure (invalid in MathML3). --> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <maction class="testedElement allChildrenVisible"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext class="space-like">X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </maction> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <semantics class="testedElement allChildrenVisible"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="2em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext class="space-like">X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </semantics> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001-ref.html new file mode 100644 index 0000000000..b37ce125a7 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001-ref.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Embellished operators - tree change and relayout (reference)</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + mo { + color: blue; + } +</style> +</head> +<body> + <p>There should be the five 1em squares on the same line, with colors + black, orange, blue, orange, black:</p> + <math display="block"> + <mrow style="background: yellow"> + <mn>1</mn> + <mrow style="background: orange"> + <mrow id="change_to_non_embellished_operator"> + <mrow> + <mo lspace="1em" rspace="1em">X</mo> + </mrow> + <mn></mn> + </mrow> + </mrow> + <mn>2</mn> + </mrow> + </math> + + <p>There should be the five 1em squares on the same line, with colors + black, yellow, blue, yellow, black:</p> + <math display="block"> + <mrow style="background: yellow"> + <mn>3</mn> + <mrow style="background: orange"> + <mrow id="change_to_embellished_operator"> + <mrow> + <mo lspace="1em" rspace="1em">X</mo> + </mrow> + </mrow> + </mrow> + <mn>4</mn> + </mrow> + </math> + + <p>There should be the five 1em squares on the same line, with colors + black, orange, blue, orange, black:</p> + <math display="block"> + <mrow style="background: yellow"> + <mn>5</mn> + <mrow style="background: orange"> + <mrow> + <mrow> + <mo lspace="1em" rspace="1em">X</mo> + </mrow> + </mrow> + <mrow id="change_to_not_space_like"> + <mspace></mspace> + <mtext></mtext> + <mn></mn> + </mrow> + </mrow> + <mn>6</mn> + </mrow> + </math> + + <p>There should be the five 1em squares on the same line, with colors + black, yellow, blue, yellow, black:</p> + <math display="block"> + <mrow style="background: yellow"> + <mn>7</mn> + <mrow style="background: orange"> + <mrow> + <mrow> + <mo lspace="1em" rspace="1em">X</mo> + </mrow> + <mrow id="change_to_space_like"> + <mspace></mspace> + <mtext></mtext> + </mrow> + </mrow> + </mrow> + <mn>8</mn> + </mrow> + </math> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001.html new file mode 100644 index 0000000000..09a7fe412a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001.html @@ -0,0 +1,123 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Embellished operators - tree change and relayout</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<script src="/mathml/support/mathml-fragments.js"></script> +<meta name="assert" content="Verify relayout of an mrow with a child that has a deeply nested <mo> element."> +<link rel="match" href="embellished-operator-dynamic-001-ref.html"> +<style> + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + mo { + color: blue; + } +</style> +</head> +<body> + <p>There should be the five 1em squares on the same line, with colors + black, orange, blue, orange, black:</p> + <math display="block"> + <mrow style="background: yellow"> + <mn>1</mn> + <mrow style="background: orange"> + <mrow id="change_to_not_embellished_operator"> + <mrow> + <mo lspace="1em" rspace="1em">X</mo> + </mrow> + </mrow> + </mrow> + <mn>2</mn> + </mrow> + </math> + + <p>There should be the five 1em squares on the same line, with colors + black, yellow, blue, yellow, black:</p> + <math display="block"> + <mrow style="background: yellow"> + <mn>3</mn> + <mrow style="background: orange"> + <mrow id="change_to_embellished_operator"> + <mrow> + <mo lspace="1em" rspace="1em">X</mo> + </mrow> + <mn></mn> + </mrow> + </mrow> + <mn>4</mn> + </mrow> + </math> + + <p>There should be the five 1em squares on the same line, with colors + black, orange, blue, orange, black:</p> + <math display="block"> + <mrow style="background: yellow"> + <mn>5</mn> + <mrow style="background: orange"> + <mrow> + <mrow> + <mo lspace="1em" rspace="1em">X</mo> + </mrow> + </mrow> + <mrow id="change_to_not_space_like"> + <mspace></mspace> + <mtext></mtext> + </mrow> + </mrow> + <mn>6</mn> + </mrow> + </math> + + <p>There should be the five 1em squares on the same line, with colors + black, yellow, blue, yellow, black:</p> + <math display="block"> + <mrow style="background: yellow"> + <mn>7</mn> + <mrow style="background: orange"> + <mrow> + <mrow> + <mo lspace="1em" rspace="1em">X</mo> + </mrow> + <mrow id="change_to_space_like"> + <mspace></mspace> + <mtext></mtext> + <mn></mn> + </mrow> + </mrow> + </mrow> + <mn>8</mn> + </mrow> + </math> + + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing"); + + // After adding a not space-like element to mrow1, it is no longer an + // embellished operator : lspace/rspace should be around its mrow child. + let mrow1 = document.getElementById("change_to_not_embellished_operator"); + mrow1.appendChild(FragmentHelper.createElement("mn")); + + // Removing the not space-like element from mrow2 makes its orange parent + // an embellished operator. lspace/rspace should be around this parent. + let mrow2 = document.getElementById("change_to_embellished_operator"); + mrow2.removeChild(mrow2.lastElementChild); + + // Same as above, but changing the space-like nature of one child. + let mrow3 = document.getElementById("change_to_not_space_like"); + mrow3.appendChild(FragmentHelper.createElement("mn")); + let mrow4 = document.getElementById("change_to_space_like"); + mrow4.removeChild(mrow4.lastElementChild); + + document.documentElement.classList.remove('reftest-wait'); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-002.html new file mode 100644 index 0000000000..2c52684765 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-002.html @@ -0,0 +1,185 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Embellished operators - tree change and relayout</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<link rel="help" href="https://chromium-review.googlesource.com/c/chromium/src/+/3059456"> +<meta name="assert" content="Verify relayout of an mrow with a child that has a deeply nested <mo> element."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + .relative_positioned_and_fixed_size { + position: relative; + height: 0px; + width: 0px; + overflow: scroll; + } +</style> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + + function assertCorrectSpacing(container, + zero_size_mrow_is_embellished_op) { + // The container should add lspace/rspace around the zero size mrow + // if and only if that mrow is an embellished operator. + let mnBefore = container.children[0].getBoundingClientRect(); + let zeroSizeMrow = container.children[1].getBoundingClientRect(); + let mnAfter = container.children[2].getBoundingClientRect(); + assert_approx_equals(zeroSizeMrow.left - mnBefore.right, + zero_size_mrow_is_embellished_op ? + emToPx * 1 : 0, epsilon, + "lspace"); + assert_approx_equals(mnAfter.left - zeroSizeMrow.right, + zero_size_mrow_is_embellished_op ? + emToPx * 2 : 0, epsilon, + "rspace"); + } + + let container1 = document.getElementById("container1"); + test(function() { + assertCorrectSpacing(container1, true); + }, "container1: Initially an embellished operator"); + + let container2 = document.getElementById("container2"); + test(function() { + assertCorrectSpacing(container2, false); + }, "container2: Initially not an embellished operator"); + + test(function() { + let mrow1 = document.getElementById("change_to_not_embellished_operator"); + mrow1.appendChild(FragmentHelper.createElement("mn")); + assertCorrectSpacing(container1, false); + }, " container1: No longer an embellished operator"); + + test(function() { + let mrow2 = document.getElementById("change_to_embellished_operator"); + mrow2.removeChild(mrow2.lastElementChild); + assertCorrectSpacing(container2, true); + }, "container2: Became an embellished operator"); + + let container3 = document.getElementById("container3"); + test(function() { + assertCorrectSpacing(container3, true); + }, "container3: Initially an embellished operator (testing space-like)"); + + let container4 = document.getElementById("container4"); + test(function() { + assertCorrectSpacing(container4, false); + }, "container4/space-like: Initially not an embellished operator (testing space-like)"); + + test(function() { + let mrow = document.getElementById("change_to_not_space_like"); + mrow.appendChild(FragmentHelper.createElement("mn")); + assertCorrectSpacing(container3, false); + }, " container3: No longer an embellished operator (testing space-like)"); + + test(function() { + let mrow = document.getElementById("change_to_space_like"); + mrow.removeChild(mrow.lastElementChild); + assertCorrectSpacing(container4, true); + }, "container4: Became an embellished operator (testing space-like)"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + + <div> + <math display="block"> + <mrow id="container1"> + <mn>1</mn> + <mrow class="relative_positioned_and_fixed_size"> + <mrow id="change_to_not_embellished_operator"> + <mrow> + <mo lspace="1em" rspace="2em"></mo> + </mrow> + </mrow> + </mrow> + <mn>2</mn> + </mrow> + </math> + </div> + + <div> + <math display="block"> + <mrow id="container2"> + <mn>3</mn> + <mrow class="relative_positioned_and_fixed_size"> + <mrow id="change_to_embellished_operator"> + <mrow> + <mo lspace="1em" rspace="2em"></mo> + </mrow> + <mn></mn> + </mrow> + </mrow> + <mn>4</mn> + </mrow> + </math> + </div> + + <div> + <math display="block"> + <mrow id="container3"> + <mn>5</mn> + <mrow> + <mrow> + <mrow> + <mo lspace="1em" rspace="2em"></mo> + </mrow> + <mrow class="relative_positioned_and_fixed_size"> + <mrow id="change_to_not_space_like"> + <mspace></mspace> + <mtext></mtext> + </mrow> + </mrow> + </mrow> + </mrow> + <mn>6</mn> + </mrow> + </math> + </div> + + <div> + <math display="block"> + <mrow id="container4"> + <mn>7</mn> + <mrow> + <mrow> + <mrow> + <mo lspace="1em" rspace="2em"></mo> + </mrow> + <mrow class="relative_positioned_and_fixed_size"> + <mrow id="change_to_space_like"> + <mspace></mspace> + <mtext></mtext> + <mn></mn> + </mrow> + </mrow> + </mrow> + </mrow> + <mn>8</mn> + </mrow> + </math> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/largeop-hit-testing.html b/testing/web-platform/tests/mathml/presentation-markup/operators/largeop-hit-testing.html new file mode 100644 index 0000000000..2b81eb692a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/largeop-hit-testing.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test hit testing on large operators</title> +<meta name="assert" content="Verify that hit testing works on large operators."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/largeop-displayoperatorminheight5000.woff"); + } + mo { + font-family: TestFont; + font-size: 16px; + } +</style> +<script> + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + + let bbox = getBox("largeop"); + let hit = document.getElementById("largeop"); + let reference = getBox("reference"); + assert_true(bbox.height > reference.height, "height of large op is bigger than the equivalent normal operator"); + assert_equals(hit, document.elementFromPoint(bbox.left + 1, bbox.top + 1), "hit testing top-left corner of large op works"); + assert_equals(hit, document.elementFromPoint(bbox.right - 1, bbox.bottom - 1), "hit testing bottom-right corner of large op works"); + }, "Large op hit testing"); + + done(); + } +</script> +</head> +<body> + <math> + <mtable> + <mtr> + <mtd> + <mstyle displaystyle="false"> + <mo id="reference">⫿</mo> + </mstyle> + </mtd> + <mtd> + <mstyle displaystyle="true"> + <mo id="largeop">⫿</mo> + </mstyle> + </mtd> + </mtr> + </mtable> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-axis-height-1.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-axis-height-1.html new file mode 100644 index 0000000000..6de6284188 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-axis-height-1.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mo axis height</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<meta name="assert" content="Element mo correctly uses the axis height parameter from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace { + font-size: 10px; + } + @font-face { + font-family: axisheight5000-verticalarrow14000; + src: url("/fonts/math/axisheight5000-verticalarrow14000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 5; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + var v1 = 5000 * emToPx; + var moMiddle = (getBox("mo1").bottom + getBox("mo1").top) / 2; + assert_approx_equals(getBox("mo1").height, + 14000 * emToPx, epsilon, "mo: size"); + assert_approx_equals(getBox("baseline1").bottom - moMiddle, + v1, epsilon, "mo: axis height"); + }, "AxisHeight (size variant)"); + + test(function() { + var v1 = 5000 * emToPx; + var moMiddle = (getBox("mo2").bottom + getBox("mo2").top) / 2; + assert_approx_equals(getBox("mo2").height, + 2 * (getBox("target2").height - v1), + epsilon, "mo: size"); + assert_approx_equals(getBox("baseline2").bottom - moMiddle, + v1, epsilon, "mo: axis height"); + }, "AxisHeight (glyph assembly)"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: axisheight5000-verticalarrow14000;"> + <mrow> + <mspace id="baseline1" style="background: blue" width="50px" height="1px"/> + <mpadded voffset="50px"><mspace style="background: cyan" width="50px" height="1px"/></mpadded> + <mo id="mo1" symmetric="true" style="color: green">↨</mo> + <mspace style="background: gray" width="10px" height="50px"/> + </mrow> + </math> + <math style="font-family: axisheight5000-verticalarrow14000;"> + <mrow> + <mspace id="baseline2" style="background: blue" width="50px" height="1px"/> + <mpadded voffset="50px"><mspace style="background: cyan" width="50px" height="1px"/></mpadded> + <mo id="mo2" symmetric="true" style="color: green">↨</mo> + <mspace id="target2" style="background: gray" width="10px" height="200px"/> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-font-relative-lengths-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-font-relative-lengths-001.html new file mode 100644 index 0000000000..209e59ee33 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-font-relative-lengths-001.html @@ -0,0 +1,114 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Font-relative lengths on an operator</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<meta name="assert" content="Verify font-relative lengths refer to the core operator, not the embellished operator"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math { + font: 100px/1 Ahem; + } + @font-face { + font-family: operators; + src: url("/fonts/math/operators.woff"); + } + mo { + font-family: operators; + } +</style> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + var epsilon = 1; + var baseSizePx = 100; + + test(function() { + var beforeRight = document.getElementById("before1").getBoundingClientRect().right; + var afterLeft = document.getElementById("after1").getBoundingClientRect().left; + var fontScalePercent = .5; + var lspaceEm = 1; + var moWidthEm = 1; + assert_approx_equals(afterLeft - beforeRight, baseSizePx * fontScalePercent * (lspaceEm + moWidthEm), epsilon, "baseSizePx * fontScalePercent * lspaceEm"); + }, `font-relative lspace refers to the core operator`); + + test(function() { + var beforeRight = document.getElementById("before2").getBoundingClientRect().right; + var afterLeft = document.getElementById("after2").getBoundingClientRect().left; + var fontScalePercent = 2; + var rspaceEm = 1; + var moWidthEm = 1; + assert_approx_equals(afterLeft - beforeRight, baseSizePx * fontScalePercent * (rspaceEm + moWidthEm), epsilon, "baseSizePx * fontScalePercent * rspaceEm"); + }, `font-relative rspace refers to the core operator`); + + test(function() { + var moStretchSize = document.getElementById("operator1").getBoundingClientRect().height; + var fontScalePercent = .5; + var minsizeEm = 8; + var beforeHeight = document.getElementById("before1").getBoundingClientRect().height; + + assert_approx_equals(moStretchSize, baseSizePx * minsizeEm * fontScalePercent, epsilon, "baseSizePx * fontScalePercent * minsizeEm"); + + // This is really testing the same thing but do make sure minsize is + // applied i.e. the unconstrained target size is less than the actual + // stretch size. + assert_approx_equals(beforeHeight, moStretchSize / 2, epsilon); + + }, `font-relative minsize refers to the core operator`); + + test(function() { + var moStretchSize = document.getElementById("operator2").getBoundingClientRect().height; + var fontScalePercent = 2; + var maxsizeEm = 1; + var afterHeight = document.getElementById("after2").getBoundingClientRect().height; + + assert_approx_equals(moStretchSize, baseSizePx * maxsizeEm * fontScalePercent, epsilon, "baseSizePx * fontScalePercent * maxsizeEm"); + + // This is really testing the same thing but do make sure maxsize is + // applied i.e. the unconstrained target size is more than the actual + // stretch size. + assert_approx_equals(afterHeight, 2 * moStretchSize, epsilon); + + }, `font-relative maxsize refers to the core operator`); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow> + <mspace id="before1" width="1em" height="1em" depth="1em" style="background: blue"/> + <mrow style="font-size: 50%;"> + <mo id="operator1" lspace="1em" rspace="0em" minsize="8em">⥯</mo> + <mspace id="after1" width="1em" height=".5em" depth=".5em" style="background: green"/> + </mrow> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow style="font-size: 200%"> + <mspace id="before2" width="1em" height=".5em" depth=".5em" style="background: green"/> + <mo id="operator2" lspace="0em" rspace="1em" maxsize="1em">⥯</mo> + </mrow> + <mspace id="after2" width="1em" height="2em" depth="2em" style="background: blue"/> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002-ref.html new file mode 100644 index 0000000000..be7f5aa173 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002-ref.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title><mo> dynamic form</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 60px/1 Ahem; + } + mo { + color: blue; + } + </style> + </head> + <body> + <p> + <math> + <mn>1</mn><mo id="infix_attach_prefix" form="prefix">+</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mo id="prefix_attach_infix" form="infix">+</mo><mn>3</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="infix_remove">+</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mo id="prefix_remove">+</mo><mn>3</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="infix_set_to_prefix" form="prefix">+</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mo id="prefix_set_to_infix" form="infix">+</mo><mn>3</mn> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002.html new file mode 100644 index 0000000000..862fc36a20 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <meta charset="utf-8"> + <title><mo> dynamic form</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies that the form (and thus spacing) can be changed dynamically"> + <link rel="match" href="mo-form-dynamic-002-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 60px/1 Ahem; + } + mo { + color: blue; + } + </style> + <script> + window.addEventListener("load", () => { + document.getElementById("infix_attach_prefix").setAttribute("form", "prefix"); + document.getElementById("prefix_attach_infix").setAttribute("form", "infix"); + document.getElementById("infix_remove").removeAttribute("form"); + document.getElementById("prefix_remove").removeAttribute("form"); + document.getElementById("infix_set_to_prefix").setAttribute("form", "prefix"); + document.getElementById("prefix_set_to_infix").setAttribute("form", "infix"); + document.documentElement.classList.remove("reftest-wait"); + }); + </script> + </head> + <body> + <!-- Prefix and infix forms of "+" have different default spacing in + the operator dictionary. --> + <p> + <math> + <mn>1</mn><mo id="infix_attach_prefix">+</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mo id="prefix_attach_infix">+</mo><mn>3</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="infix_remove" form="prefix">+</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mo id="prefix_remove" form="infix">+</mo><mn>3</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="infix_set_to_prefix" form="postfix">+</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mo id="prefix_set_to_infix" form="postfix">+</mo><mn>3</mn> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-ref.html new file mode 100644 index 0000000000..8f8d3da2c3 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-ref.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title><mo> dynamic form</title> + </head> + <body> + + <p>The test should render the same as the static reference.</p> + + _<math><merror><mi>x</mi><mo>+</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo>+</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo>+</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo>+</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo>+</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo>+</mo><mi>y</mi></mstyle></math>_ + + _<math><merror><mo>−</mo><mi>y</mi></merror></math>_ + _<math><mo>−</mo><mi>y</mi></math>_ + _<math><mphantom><mo>−</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mo>−</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mo>−</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mo>−</mo><mi>y</mi></mstyle></math>_ + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic.html new file mode 100644 index 0000000000..cec203f517 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <meta charset="utf-8"/> + <title><mo> dynamic form</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> + <meta name="assert" content="This test verifies that the form of the operators (and thus their spacing) is updated when you change the child list."> + <link rel="match" href="mo-form-dynamic-ref.html"> + + <script> + window.addEventListener("load", () => { + + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + for (var i = 1; i <= 6; i++) { + var row = document.getElementById("row" + i); + var x = document.getElementById("x" + i); + + x.parentNode.removeChild(x); + + row.insertBefore(x, row.firstElementChild); + } + + document.documentElement.classList.remove('reftest-wait'); + }) + </script> + </head> + <body> + + <p>The test should render the same as the static reference.</p> + + _<math><merror id="row1"><mo>+</mo><mi>y</mi></merror></math>_ + _<math id="row2"><mo>+</mo><mi>y</mi></math>_ + _<math><mphantom id="row3"><mo>+</mo><mi>y</mi></mphantom></math>_ + _<math><mrow id="row4"><mo>+</mo><mi>y</mi></mrow></math>_ + _<math><msqrt id="row5"><mo>+</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle id="row6"><mo>+</mo><mi>y</mi></mstyle></math>_ + + _<math><merror><mi id="x1">x</mi><mo>−</mo><mi>y</mi></merror></math>_ + _<math><mi id="x2">x</mi><mo>−</mo><mi>y</mi></math>_ + _<math><mphantom><mi id="x3">x</mi><mo>−</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi id="x4">x</mi><mo>−</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi id="x5">x</mi><mo>−</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi id="x6">x</mi><mo>−</mo><mi>y</mi></mstyle></math>_ + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback-ref.html new file mode 100644 index 0000000000..8d964eba45 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>form fallback</title> + </head> + <body> + + <math> + <mo stretchy="true">(</mo> <mspace height="3em" depth="3em"/> <mo stretchy="true">)</mo> + <mo stretchy="true">(</mo> <mspace height="3em" depth="3em"/> <mo stretchy="true">)</mo> + </math> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback.html new file mode 100644 index 0000000000..b49db9d9ff --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>form fallback</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verify fallback to postfix/prefix forms."> + <link rel="match" href="mo-form-fallback-ref.html"> + </head> + <body> + + <!-- The left (respectively right) parenthesis only has a prefix + (respectively postfix) form which gives its stretchiness. + In theory, the parenthesis in the middle of the <math> element are + considered infix operators and should not stretch. Let's check that we + fallback to the postfix/prefix forms and actually make them stretchy. + This is to handle bad MathML markup that misses explicit <mrow> tags. + --> + + <math> + <mo>(</mo> <mspace height="3em" depth="3em"/> <mo>)</mo> + <mo>(</mo> <mspace height="3em" depth="3em"/> <mo>)</mo> + </math> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus-ref.html new file mode 100644 index 0000000000..b46b307dbe --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus-ref.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>form plus/minus</title> + </head> + <body> + + <!-- These operators should have form "prefix" --> + + _<math><merror><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></merror></math>_ + _<math><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></math>_ + _<math><mphantom><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></mphantom></math>_ + _<math><mrow><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></mrow></math>_ + _<math><msqrt><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></msqrt></math>_ + _<math><mstyle><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></mstyle></math>_ + + <br/> + + _<math><merror><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></merror></math>_ + _<math><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></math>_ + _<math><mphantom><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></mphantom></math>_ + _<math><mrow><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></mrow></math>_ + _<math><msqrt><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></msqrt></math>_ + _<math><mstyle><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></mstyle></math>_ + + <br/> + + _<math><merror><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></merror></math>_ + _<math><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></math>_ + _<math><mphantom><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></mphantom></math>_ + _<math><mrow><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></mrow></math>_ + _<math><msqrt><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></msqrt></math>_ + _<math><mstyle><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></mstyle></math>_ + + <br/> + + _<math><merror><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></merror></math>_ + _<math><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></math>_ + _<math><mphantom><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></mphantom></math>_ + _<math><mrow><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></mrow></math>_ + _<math><msqrt><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></msqrt></math>_ + _<math><mstyle><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></mstyle></math>_ + + <br/> + + <!-- These operators should have form "infix" --> + + _<math><merror><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></mstyle></math>_ + + <br/> + + _<math><merror><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></mstyle></math>_ + + <br/> + + _<math><merror><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></mstyle></math>_ + + <br/> + + _<math><merror><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></mstyle></math>_ + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus.html new file mode 100644 index 0000000000..eb7dbbce2a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus.html @@ -0,0 +1,89 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>form plus/minus</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies behavior of form of plus/minus etc."> + <link rel="match" href="mo-form-minus-plus-ref.html"> + </head> + <body> + + <!-- These operators should have form "prefix" --> + + _<math><merror><mo>−</mo><mi>x</mi></merror></math>_ + _<math><mo>−</mo><mi>x</mi></math>_ + _<math><mphantom><mo>−</mo><mi>x</mi></mphantom></math>_ + _<math><mrow><mo>−</mo><mi>x</mi></mrow></math>_ + _<math><msqrt><mo>−</mo><mi>x</mi></msqrt></math>_ + _<math><mstyle><mo>−</mo><mi>x</mi></mstyle></math>_ + + <br/> + + _<math><merror><mo>+</mo><mi>x</mi></merror></math>_ + _<math><mo>+</mo><mi>x</mi></math>_ + _<math><mphantom><mo>+</mo><mi>x</mi></mphantom></math>_ + _<math><mrow><mo>+</mo><mi>x</mi></mrow></math>_ + _<math><msqrt><mo>+</mo><mi>x</mi></msqrt></math>_ + _<math><mstyle><mo>+</mo><mi>x</mi></mstyle></math>_ + + <br/> + + _<math><merror><mo>±</mo><mi>x</mi></merror></math>_ + _<math><mo>±</mo><mi>x</mi></math>_ + _<math><mphantom><mo>±</mo><mi>x</mi></mphantom></math>_ + _<math><mrow><mo>±</mo><mi>x</mi></mrow></math>_ + _<math><msqrt><mo>±</mo><mi>x</mi></msqrt></math>_ + _<math><mstyle><mo>±</mo><mi>x</mi></mstyle></math>_ + + <br/> + + _<math><merror><mo>∓</mo><mi>x</mi></merror></math>_ + _<math><mo>∓</mo><mi>x</mi></math>_ + _<math><mphantom><mo>∓</mo><mi>x</mi></mphantom></math>_ + _<math><mrow><mo>∓</mo><mi>x</mi></mrow></math>_ + _<math><msqrt><mo>∓</mo><mi>x</mi></msqrt></math>_ + _<math><mstyle><mo>∓</mo><mi>x</mi></mstyle></math>_ + + <br/> + + <!-- These operators should have form "infix" --> + + _<math><merror><mi>x</mi><mo>−</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo>−</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo>−</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo>−</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo>−</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo>−</mo><mi>y</mi></mstyle></math>_ + + <br/> + + _<math><merror><mi>x</mi><mo>+</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo>+</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo>+</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo>+</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo>+</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo>+</mo><mi>y</mi></mstyle></math>_ + + <br/> + + _<math><merror><mi>x</mi><mo>±</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo>±</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo>±</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo>±</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo>±</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo>±</mo><mi>y</mi></mstyle></math>_ + + <br/> + + _<math><merror><mi>x</mi><mo>∓</mo><mi>y</mi></merror></math>_ + _<math><mi>x</mi><mo>∓</mo><mi>y</mi></math>_ + _<math><mphantom><mi>x</mi><mo>∓</mo><mi>y</mi></mphantom></math>_ + _<math><mrow><mi>x</mi><mo>∓</mo><mi>y</mi></mrow></math>_ + _<math><msqrt><mi>x</mi><mo>∓</mo><mi>y</mi></msqrt></math>_ + _<math><mstyle><mi>x</mi><mo>∓</mo><mi>y</mi></mstyle></math>_ + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-ref.html new file mode 100644 index 0000000000..b249fe43b5 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-ref.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title><mo> form attribute</title> + </head> + <body> + + <!-- This checks the effect of @form on a prefix operator. --> + _<math><mo lspace="0.27777em" rspace="0.27777em">∇</mo></math>_ + _<math><mo lspace="0em" rspace="0em">∇</mo></math>_ + _<math><mo lspace="0.27777em" rspace="0.27777em">∇</mo></math>_ + + <!-- This checks the effect of @form on an infix operator. --> + _<math><mo lspace="0.166666em" rspace="0.166666em">⋉</mo></math>_ + _<math><mo lspace="0.27777em" rspace="0.27777em">⋉</mo></math>_ + _<math><mo lspace="0.27777em" rspace="0.27777em">⋉</mo></math>_ + + <!-- This checks the effect of @form on a postfix operator. --> + _<math><mo lspace="0.27777em" rspace="0.27777em">”</mo></math>_ + _<math><mo lspace="0.27777em" rspace="0.27777em">”</mo></math>_ + _<math><mo lspace="0em" rspace="0em">”</mo></math>_ + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form.html new file mode 100644 index 0000000000..38cbd6bb4b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title><mo> form attribute</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies behavior of form attribute."> + <link rel="match" href="mo-form-ref.html"> + </head> + <body> + + <!-- This checks the effect of @form on a prefix operator. --> + _<math><mo form="infix">∇</mo></math>_ + _<math><mo form="prefix">∇</mo></math>_ + _<math><mo form="postfix">∇</mo></math>_ + + <!-- This checks the effect of @form on an infix operator. --> + _<math><mo form="infix">⋉</mo></math>_ + _<math><mo form="prefix">⋉</mo></math>_ + _<math><mo form="postfix">⋉</mo></math>_ + + <!-- This checks the effect of @form on a postfix operator. --> + _<math><mo form="infix">”</mo></math>_ + _<math><mo form="prefix">”</mo></math>_ + _<math><mo form="postfix">”</mo></math>_ + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2-ref.html new file mode 100644 index 0000000000..4ffe6cbc23 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2-ref.html @@ -0,0 +1,363 @@ +<!DOCTYPE html> +<html> + <head> + <title>mo-lspace-rspace-2 (reference)</title> + <style type="text/css"> + mo,td { + background-color: red; + } + msub, mfrac, msup, msubsup, mmultiscripts, + mover, munder, munderover, mpadded, merror + { + background-color: blue + } + math[display] + { + background-color: blue + } + </style> + </head> + <body> + + <p> + <math> + <mrow> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mrow> + </math> + <math> + <mfrac> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mfrac> + </math> + <math> + <msqrt> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </msqrt> + </math> + <math> + <mroot> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mroot> + </math> + <math> + <mstyle> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mstyle> + </math> + </p> + + <p> + <table> + <tr> + <td> + <math> + <mphantom> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mphantom> + </math> + </td> + </tr> + </table> + </p> + + <p> + <math> + <menclose notation="circle"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </menclose> + </math> + <math> + <msub> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </msub> + </math> + <math> + <msup> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </msup> + </math> + <math> + <msubsup> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </msubsup> + </math> + <math> + <munder> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </munder> + </math> + <math> + <mover> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mover> + </math> + <math> + <munderover> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </munderover> + </math> + </p> + + <p> + <math> + <mmultiscripts> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mprescripts/> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mmultiscripts> + </math> + <math> + <mtable> + <mtr> + <mtd> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mtd> + </mtr> + </mtable> + </math> + <math> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </math> + <math> + <msub> + <mrow> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mrow> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </msub> + </math> + </p> + + <p> + <math> + <msub> + <msub> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </msub> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </msub> + </math> + <math> + <munder> + <munder> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </munder> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </munder> + </math> + <math> + <mfrac> + <mfrac> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mfrac> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mfrac> + </math> + </p> + + <p> + <math> + <menclose notation="circle"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </menclose> + <menclose notation="circle"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </menclose> + <mroot> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mroot> + </math> + <math> + <mpadded height="+1em"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mpadded> + </math> + <math> + <merror> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </merror> + </math> + </p> + + <math display="block"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </math> + + <p> + <math> + <mrow> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mrow> + <mfrac> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + </mfrac> + <msqrt> + <mo lspace="0" rspace="0">*</mo> + </msqrt> + <mstyle> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mstyle> + </math> + </p> + + <p> + <table> + <tr> + <td> + <math> + <mphantom> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mphantom> + </math> + </td> + </tr> + </table> + </p> + + <p> + <math> + <menclose notation="circle"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </menclose> + <msub> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + </msub> + <msup> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + </msup> + <msubsup> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + <mo lspace="0" rspace="0">*</mo> + </msubsup> + <munder> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + </munder> + <mover> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + </mover> + <munderover> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + <mo lspace="0" rspace="0">*</mo> + </munderover> + </math> + </p> + + <p> + <math> + <mmultiscripts> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + <mo lspace="0" rspace="0">*</mo> + <mprescripts/> + <mo lspace="0" rspace="0">*</mo> + <mo lspace="0" rspace="0">*</mo> + </mmultiscripts> + <mtable> + <mtr> + <mtd> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mtd> + </mtr> + </mtable> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <msub> + <mrow> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mrow> + <mo lspace="0" rspace="0">*</mo> + </msub> + <msub> + <mrow> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mrow> + <mo lspace="0" rspace="0">*</mo> + </msub> + </math> + </p> + + <p> + <math> + <msub> + <msub> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + </msub> + <mo lspace="0" rspace="0">*</mo> + </msub> + <munder> + <munder> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + </munder> + <mo lspace="0" rspace="0">*</mo> + </munder> + <mfrac> + <mfrac> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0" rspace="0">*</mo> + </mfrac> + <mo lspace="0" rspace="0">*</mo> + </mfrac> + </math> + </p> + + <p> + <math> + <mrow> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mpadded height="+1em"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mpadded> + </mrow> + </math> + <math> + <mpadded height="+1em"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </mpadded> + </math> + <math> + <merror> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </merror> + </math> + </p> + + <math display="block"> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </math> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2.html new file mode 100644 index 0000000000..d54f45c21d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2.html @@ -0,0 +1,363 @@ +<!DOCTYPE html> +<html> + <head> + <title>mo-lspace-rspace-2</title> + <link rel="match" href="mo-lspace-rspace-2-ref.html"> + <style type="text/css"> + mo,td { + background-color: red; + } + msub, mfrac, msup, msubsup, mmultiscripts, + mover, munder, munderover, mpadded, merror + { + background-color: blue + } + math[display] + { + background-color: blue + } + </style> + </head> + <body> + + <p> + <math> + <mrow> + <mo>*</mo> + </mrow> + </math> + <math> + <mfrac> + <mo>*</mo> + <mo>*</mo> + </mfrac> + </math> + <math> + <msqrt> + <mo>*</mo> + </msqrt> + </math> + <math> + <mroot> + <mo>*</mo> + <mo>*</mo> + </mroot> + </math> + <math> + <mstyle> + <mo>*</mo> + </mstyle> + </math> + </p> + + <p> + <table> + <tr> + <td> + <math> + <mphantom> + <mo>*</mo> + </mphantom> + </math> + </td> + </tr> + </table> + </p> + + <p> + <math> + <menclose notation="circle"> + <mo>*</mo> + </menclose> + </math> + <math> + <msub> + <mo>*</mo> + <mo>*</mo> + </msub> + </math> + <math> + <msup> + <mo>*</mo> + <mo>*</mo> + </msup> + </math> + <math> + <msubsup> + <mo>*</mo> + <mo>*</mo> + <mo>*</mo> + </msubsup> + </math> + <math> + <munder> + <mo>*</mo> + <mo>*</mo> + </munder> + </math> + <math> + <mover> + <mo>*</mo> + <mo>*</mo> + </mover> + </math> + <math> + <munderover> + <mo>*</mo> + <mo>*</mo> + <mo>*</mo> + </munderover> + </math> + </p> + + <p> + <math> + <mmultiscripts> + <mo>*</mo> + <mo>*</mo> + <mo>*</mo> + <mprescripts/> + <mo>*</mo> + <mo>*</mo> + </mmultiscripts> + </math> + <math> + <mtable> + <mtr> + <mtd> + <mo>*</mo> + </mtd> + </mtr> + </mtable> + </math> + <math> + <mo>*</mo> + </math> + <math> + <msub> + <mrow> + <mo>*</mo> + </mrow> + <mo>*</mo> + </msub> + </math> + </p> + + <p> + <math> + <msub> + <msub> + <mo>*</mo> + <mo>*</mo> + </msub> + <mo>*</mo> + </msub> + </math> + <math> + <munder> + <munder> + <mo>*</mo> + <mo>*</mo> + </munder> + <mo>*</mo> + </munder> + </math> + <math> + <mfrac> + <mfrac> + <mo>*</mo> + <mo>*</mo> + </mfrac> + <mo>*</mo> + </mfrac> + </math> + </p> + <p> + <math> + <menclose notation="circle"> + <mo>*</mo> + </menclose> + <menclose notation="circle"> + <mo>*</mo> + </menclose> + <mroot> + <mo>*</mo> + <mo>*</mo> + </mroot> + </math> + <math> + <mpadded height="+1em"> + <mo>*</mo> + </mpadded> + </math> + <math> + <merror> + <mo>*</mo> + </merror> + </math> + </p> + + <math display="block"> + <mo>*</mo> + </math> + + <p> + <math> + <mrow> + <mo>*</mo> + </mrow> + <mfrac> + <mo>*</mo> + <mo>*</mo> + </mfrac> + <msqrt> + <mo>*</mo> + </msqrt> + <mstyle> + <mo>*</mo> + </mstyle> + </math> + </p> + + <p> + <table> + <tr> + <td> + <math> + <mphantom> + <mo>*</mo> + <mo>*</mo> + </mphantom> + </math> + </td> + </tr> + </table> + </p> + + <p> + <math> + <menclose notation="circle"> + <mo>*</mo> + <mo>*</mo> + </menclose> + <msub> + <mo>*</mo> + <mo>*</mo> + </msub> + <msup> + <mo>*</mo> + <mo>*</mo> + </msup> + <msubsup> + <mo>*</mo> + <mo>*</mo> + <mo>*</mo> + </msubsup> + <munder> + <mo>*</mo> + <mo>*</mo> + </munder> + <mover> + <mo>*</mo> + <mo>*</mo> + </mover> + <munderover> + <mo>*</mo> + <mo>*</mo> + <mo>*</mo> + </munderover> + </math> + </p> + + <p> + <math> + <mmultiscripts> + <mo>*</mo> + <mo>*</mo> + <mo>*</mo> + <mprescripts/> + <mo>*</mo> + <mo>*</mo> + </mmultiscripts> + <mtable> + <mtr> + <mtd> + <mo>*</mo> + <mo>*</mo> + </mtd> + </mtr> + </mtable> + <mo>*</mo> + <msub> + <mrow> + <mo>*</mo> + </mrow> + <mo>*</mo> + </msub> + <msub> + <mrow> + <mo>*</mo> + <mo>*</mo> + </mrow> + <mo>*</mo> + </msub> + </math> + </p> + + <p> + <math> + <msub> + <msub> + <mo>*</mo> + <mo>*</mo> + </msub> + <mo>*</mo> + </msub> + <munder> + <munder> + <mo>*</mo> + <mo>*</mo> + </munder> + <mo>*</mo> + </munder> + <mfrac> + <mfrac> + <mo>*</mo> + <mo>*</mo> + </mfrac> + <mo>*</mo> + </mfrac> + </math> + </p> + + <p> + <math> + <mrow> + <mo>*</mo> + <mo>*</mo> + <mpadded height="+1em"> + <mo>*</mo> + </mpadded> + </mrow> + </math> + <math> + <mpadded height="+1em"> + <mo>*</mo> + <mo>*</mo> + </mpadded> + </math> + <math> + <merror> + <mo>*</mo> + <mo>*</mo> + </merror> + </math> + </p> + + <math display="block"> + <mo>*</mo> + <mo>*</mo> + </math> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3-ref.html new file mode 100644 index 0000000000..1830e11474 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3-ref.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> + <head> + <title>mo-lspace-rspace-3 (reference)</title> + </head> + <body> + <p> + <math> + <mo id="mo1" lspace="3em" rspace="0.16666666666666666em">*</mo> + </math> + </p> + <p> + <math> + <mo id="mo2" lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </math> + </p> + <p> + <math> + <mo id="mo3" lspace="3em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </math> + </p> + <p> + <math> + <mo id="mo4" lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </math> + </p> + <p> + <math> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </math> + </p> + <p> + <math> + <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3.html new file mode 100644 index 0000000000..4574ff39c9 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <title>mo-lspace-rspace-3</title> + <link rel="match" href="mo-lspace-rspace-3-ref.html"> + </head> + <body> + <p> + <math> + <mo id="mo1">*</mo> + </math> + </p> + <p> + <math> + <mo id="mo2" lspace="3em">*</mo> + </math> + </p> + <p> + <math> + <mo id="mo3">*</mo> + <mo>*</mo> + </math> + </p> + <p> + <math> + <mo id="mo4" lspace="3em">*</mo> + <mo >*</mo> + </math> + </p> + <p> + <math id="math1"> + <mo>*</mo> + </math> + </p> + <p> + <math id="math2"> + <mo>*</mo> + <mo id="mo5">*</mo> + </math> + </p> + <script type="text/javascript"> + function doTest() { + // Add and remove lspace + document.getElementById("mo1").setAttribute("lspace", "3em"); + document.getElementById("mo2").removeAttribute("lspace"); + // and again but with an inferred mrow + document.getElementById("mo3").setAttribute("lspace", "3em"); + document.getElementById("mo4").removeAttribute("lspace"); + + // Change to/from inferred mrow + var mo1 = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mo"); + mo1.innerHTML = "*"; + document.getElementById("math1").appendChild(mo1); + document.getElementById("math2").removeChild(document.getElementById("mo5")); + + document.documentElement.removeAttribute("class"); + } + window.addEventListener("load", doTest); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4-ref.html new file mode 100644 index 0000000000..ab4c08dde1 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4-ref.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <head> + <title>mo-lspace-rspace-4 (reference)</title> + </head> + <body> + <p> + <math> + <mtext>_</mtext> + <mrow> + <mfrac> + <mo lspace="1em" rspace="2em">_</mo> + <mtext>_</mtext> + </mfrac> + </mrow> + <mtext>_</mtext> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4.html new file mode 100644 index 0000000000..4798454868 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <title>mo-lspace-rspace-4</title> + <link rel="match" href="mo-lspace-rspace-4-ref.html"> + </head> + <body> + <p> + <math> + <mtext>_</mtext> + <mfrac> + <mo lspace="1em" rspace="2em">_</mo> + <mtext>_</mtext> + </mfrac> + <mtext>_</mtext> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic-ref.html new file mode 100644 index 0000000000..85cabd287d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic-ref.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title><mo> dynamic lspace rspace (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 60px/1 Ahem; + } + mo { + color: blue; + } + </style> + </head> + <body> + <p> + <math> + <mn>1</mn><mo id="mo_attach_lspace" lspace="2em">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_attach_rspace" rspace="3em">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_modify_lspace" lspace="4em" rspace="1em">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_modify_rspace" lspace="1em" rspace="5em">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_remove_lspace" rspace="1em">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_remove_rspace" lspace="1em">X</mo><mn>2</mn> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic.html new file mode 100644 index 0000000000..70098bebf9 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <meta charset="utf-8"> + <title><mo> dynamic lspace rspace</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies dynamic setting of lspace and rspace"> + <link rel="match" href="mo-lspace-rspace-dynamic-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math, math * { + font: 60px/1 Ahem; + } + mo { + color: blue; + } + </style> + <script> + window.addEventListener("load", () => { + document.getElementById("mo_attach_lspace").setAttribute("lspace", "2em"); + document.getElementById("mo_attach_rspace").setAttribute("rspace", "3em"); + document.getElementById("mo_modify_lspace").setAttribute("lspace", "4em"); + document.getElementById("mo_modify_rspace").setAttribute("rspace", "5em"); + document.getElementById("mo_remove_lspace").removeAttribute("lspace"); + document.getElementById("mo_remove_rspace").removeAttribute("rspace"); + document.documentElement.classList.remove("reftest-wait"); + }); + </script> + </head> + <body> + <p> + <math> + <mn>1</mn><mo id="mo_attach_lspace">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_attach_rspace">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_modify_lspace" lspace="1em" rspace="1em">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_modify_rspace" lspace="1em" rspace="1em">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_remove_lspace" lspace="1em" rspace="1em">X</mo><mn>2</mn> + </math> + </p> + <p> + <math> + <mn>1</mn><mo id="mo_remove_rspace" lspace="1em" rspace="1em">X</mo><mn>2</mn> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-ref.html new file mode 100644 index 0000000000..46be5079e6 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-ref.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> + <head> + <title>mo-lspace-rspace (reference)</title> + </head> + + <body> + + <p> + <!-- not in the operator dictionary --> + <math> + <mtext>_</mtext> + <mspace width="0.2777777777777778em" height="0" depth="0"></mspace> + <mtext>MO</mtext> + <mspace width="0.2777777777777778em" height="0" depth="0"></mspace> + <mtext>_</mtext> + </math> + </p> + + <p> + <!-- operator.\u223F.infix = lspace:3 rspace:3 # sine wave --> + <math> + <mtext>_</mtext> + <mspace width="0.16666666666666666em" height="0" depth="0"></mspace> + <mtext>∿</mtext> + <mspace width="0.16666666666666666em" height="0" depth="0"></mspace> + <mtext>_</mtext> + </math> + </p> + + <p> + <!-- Invisible operator --> + <math> + <mtext>_</mtext> + <mtext>⁡</mtext> + <mtext>_</mtext> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace.html new file mode 100644 index 0000000000..5774e4ced0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> + <head> + <title>mo-lspace-rspace</title> + <link rel="match" href="mo-lspace-rspace-ref.html"> + </head> + + <body> + + <p> + <!-- not in the operator dictionary --> + <math> + <mtext>_</mtext> + <mo>MO</mo> + <mtext>_</mtext> + </math> + </p> + + <p> + <!-- operator.\u223F.infix = lspace:3 rspace:3 # sine wave --> + <math> + <mtext>_</mtext> + <mo>∿</mo> + <mtext>_</mtext> + </math> + </p> + + <p> + <!-- Invisible operator --> + <math> + <mtext>_</mtext> + <mo>⁡</mo> + <mtext>_</mtext> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-minsize-maxsize-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-minsize-maxsize-001.html new file mode 100644 index 0000000000..3e7e5c9bcc --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-minsize-maxsize-001.html @@ -0,0 +1,143 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Edge cases for minsize and maxsize</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<meta name="assert" content="Verify edge cases for minsize and maxsize ."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math { + font: 25px/1 Ahem; + } + @font-face { + font-family: operators; + src: url("/fonts/math/operators.woff"); /* AxisHeight == 0 */ + } + mo { + font-family: operators; + } +</style> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + test(function() { + assert_approx_equals(document.getElementById("negative_minsize").getBoundingClientRect().height, 5 * emToPx, epsilon); + }, `minsize < 0 is treated as 0`); + + test(function() { + assert_approx_equals(document.getElementById("maxsize_less_than_minsize").getBoundingClientRect().height, 7 * emToPx, epsilon); + }, `maxsize < minsize is treated as maxsize = minsize`); + + test(function() { + assert_less_than(document.getElementById("minsize_less_than_negative_maxsize").getBoundingClientRect().height, 2 * emToPx); + }, `minsize < maxsize < 0 is treated as maxsize = minsize = 0`); + + test(function() { + assert_approx_equals(document.getElementById("zero_target_size_with_minsize").getBoundingClientRect().height, 2 * emToPx, epsilon); + assert_approx_equals(document.getElementById("zero_target_size_with_minsize").getBoundingClientRect().bottom - document.getElementById("zero_target_size_with_minsize_math_axis").getBoundingClientRect().bottom, emToPx, epsilon); + }, `target size = 0 is treated as Tascent = Tdescent = minsize/2`); + + test(function() { + assert_approx_equals(document.getElementById("percent_minsize").getBoundingClientRect().height, 12 * emToPx, epsilon, "percent minsize"); + assert_approx_equals(document.getElementById("percent_maxsize").getBoundingClientRect().height, 3 * emToPx, epsilon, "percent maxsize"); + }, `minsize/maxsize percentages are relative to the target size`); + + test(function() { + // These tests are not really strong: + // - The smallest glyph for this stretchy operator is a 1em square so + // it can't go under a minsize of 1em anyway. + // - The maxsize is theorically infinite, this only tests that a large + // value of 300em is clamped. + assert_approx_equals(document.getElementById("default_minsize").getBoundingClientRect().height, 1 * emToPx, epsilon, "default minsize is 1em"); + assert_approx_equals(document.getElementById("default_maxsize").getBoundingClientRect().height, 300 * emToPx, epsilon, "default maxsize is infinity"); + }, `default minsize/maxsize percentages`); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow> + <mspace width="1em" height="5em" style="background: blue"/> + <mo id="negative_minsize" minsize="-10em" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="5em" style="background: blue"/> + <mo id="maxsize_less_than_minsize" minsize="7em" maxsize="2em" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="5em" style="background: blue"/> + <mo id="minsize_less_than_negative_maxsize" minsize="-2em" maxsize="-1em" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace id="zero_target_size_with_minsize_math_axis" width="1em" height="0em" style="background: blue"/> + <mo id="zero_target_size_with_minsize" minsize="2em" stretchy="true" symmetric="true">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="6em" style="background: blue"/> + <mo id="percent_minsize" minsize="200%" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="6em" style="background: blue"/> + <mo id="percent_maxsize" maxsize="50%" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height=".5em" style="background: blue"/> + <mo id="default_minsize" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="300em" style="background: blue"/> + <mo id="default_maxsize" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator-ref.html new file mode 100644 index 0000000000..cca8b9b697 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator-ref.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"/> + <title><mo> movablelimits and embellished operator (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { font: 25px/1 Ahem; } + </style> +</head> +<body> + <math> + <msub> + <mrow><mtext>A</mtext></mrow> + <mn>2</mn> + </msub> + <munder> + <mrow><mtext>A</mtext></mrow> + <mn>2</mn> + </munder> + </math> + <math displaystyle="true"> + <munder> + <mrow><mtext>A</mtext></mrow> + <mn>2</mn> + </munder> + <munder> + <mrow><mtext>A</mtext></mrow> + <mn>2</mn> + </munder> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator.html new file mode 100644 index 0000000000..2bdfa15bc6 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title><mo> movablelimits and embellished operator (reference)</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> + <meta name="assert" content="Verifies effect of movablelimits on the core operator of an embellished operator, in both displaystyle modes."> + <link rel="match" href="mo-movablelimits-and-embellished-operator-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { font: 25px/1 Ahem; } + </style> + </head> + <body> + <math> + <munder> + <mrow><mo lspace="0px" rspace="0px" movablelimits="true">A</mo></mrow> + <mn>2</mn> + </munder> + <munder> + <mrow><mo lspace="0px" rspace="0px" movablelimits="false">A</mo></mrow> + <mn>2</mn> + </munder> + </math> + <math displaystyle="true"> + <munder> + <mrow><mo lspace="0px" rspace="0px" movablelimits="true">A</mo></mrow> + <mn>2</mn> + </munder> + <munder> + <mrow><mo lspace="0px" rspace="0px" movablelimits="false">A</mo></mrow> + <mn>2</mn> + </munder> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default-ref.html new file mode 100644 index 0000000000..8328637397 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <title>mo movablelimits default value</title> + <meta charset="utf-8"/></head> +<body> + <math> + <munder> + <mo movablelimits="true">∑</mo> + <mi>x</mi> + </munder> + <munder> + <mo movablelimits="false">∫</mo> + <mi>x</mi> + </munder> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default.html new file mode 100644 index 0000000000..4d6ee00d82 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title><mo> movablelimits default value</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies default value of movablelimits for some operators."> + <link rel="match" href="mo-movablelimits-default-ref.html"> + </head> + <body> + <math> + <munder> + <mo>∑</mo> <!-- This has movablelimits="true" in the operator dictionary --> + <mi>x</mi> + </munder> + <munder> + <mo>∫</mo> <!-- This has movablelimits="false" in the operator dictionary --> + <mi>x</mi> + </munder> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic-ref.html new file mode 100644 index 0000000000..ee5bce2ca8 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Test dynamically removing movablelimits attribute</title> + </head> + <body> + <math> + <munder> + <mo>∑</mo> + <mi>x</mi> + </munder> + </math> + </body> + </html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html new file mode 100644 index 0000000000..647fc52321 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <meta charset="utf-8"/> + <title>Test dynamically removing movablelimits attribute</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> + <meta name="assert" content="Verifies dynamically removing movablelimits."> + <link rel="match" href="mo-movablelimits-dynamic-ref.html"> + <script> + window.addEventListener("load", () => { + document.getElementById('a').removeAttribute('movablelimits'); + document.documentElement.classList.remove('reftest-wait'); + }); + </script> + </head> + <body> + <math> + <munder> + <mo id="a" movablelimits="false">∑</mo> + <mi>x</mi> + </munder> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow-ref.html new file mode 100644 index 0000000000..3efeaa0dfe --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow-ref.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title><mo> movablelimits</title> + <style> + math, math * { + font: 25px/1 Ahem; + } + </style> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + </head> + <body> + <math> + <msub> + <mo lspace="0px" rspace="0px">+</mo> + <mn>1</mn> + </msub> + <msup> + <mo lspace="0px" rspace="0px">+</mo> + <mn>1</mn> + </msup> + <msubsup> + <mo lspace="0px" rspace="0px">+</mo> + <mn>1</mn> + <mn>2</mn> + </msubsup> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow.html new file mode 100644 index 0000000000..d1a2422c98 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title><mo> movablelimits</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verify movablelimits is read from the first in-flow child."> + <style> + math, math * { + font: 25px/1 Ahem; + } + .oof1 { + position: absolute; + } + .oof2 { + position: fixed; + } + .nobox { + display: none; + } + </style> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <link rel="match" href="mo-movablelimits-from-in-flow-ref.html"> + </head> + <body> + <math> + <munder> + <mo class="oof1" movablelimits="false"></mo> + <mo class="oof2" movablelimits="false"></mo> + <mo class="nobox" movablelimits="false"></mo> + <mo lspace="0px" rspace="0px" movablelimits="true">+</mo> + <mn>1</mn> + </munder> + <mover> + <mo class="oof1" movablelimits="false"></mo> + <mo class="oof2" movablelimits="false"></mo> + <mo class="nobox" movablelimits="false"></mo> + <mo lspace="0px" rspace="0px" movablelimits="true">+</mo> + <mn>1</mn> + </mover> + <munderover> + <mo class="oof1" movablelimits="false"></mo> + <mo class="oof2" movablelimits="false"></mo> + <mo class="nobox" movablelimits="false"></mo> + <mo lspace="0px" rspace="0px" movablelimits="true">+</mo> + <mn>1</mn> + <mn>2</mn> + </munderover> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-ref.html new file mode 100644 index 0000000000..cb868d2400 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-ref.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"/> + <title><mo> movablelimits</title> +</head> +<body> + <math> + <msub> + <mtext>A</mtext> + <mi>B</mi> + </msub> + <munder> + <mtext>A</mtext> + <mi>B</mi> + </munder> + </math> + <math displaystyle="true"> + <munder> + <mtext>A</mtext> + <mi>B</mi> + </munder> + <munder> + <mtext>A</mtext> + <mi>B</mi> + </munder> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits.html new file mode 100644 index 0000000000..e7aa17380b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title><mo> movablelimits</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies effect of movablelimits on mo in both displaystyle modes."> + <link rel="match" href="mo-movablelimits-ref.html"> + </head> + <body> + <math> + <munder> + <mo lspace="0px" rspace="0px" movablelimits="true">A</mo> + <mi>B</mi> + </munder> + <munder> + <mo lspace="0px" rspace="0px" movablelimits="false">A</mo> + <mi>B</mi> + </munder> + </math> + <math displaystyle="true"> + <munder> + <mo lspace="0px" rspace="0px" movablelimits="true">A</mo> + <mi>B</mi> + </munder> + <munder> + <mo lspace="0px" rspace="0px" movablelimits="false">A</mo> + <mi>B</mi> + </munder> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace-ref.html new file mode 100644 index 0000000000..3938db19a7 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace-ref.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>lspace/rspace default value for unknown operators (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 100px/1 Ahem; + } + mo { + color: blue; + } + </style> + </head> + <body> + <p>This test passes if on each row, the space around the blue rectangle + is 0.2777777777777778em.</p> + <p> + <math> + <mrow> + <mn>p</mn> + <mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">X</mo> <!-- Single character --> + <mn>p</mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mn>p</mn> + <mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">XX</mo> <!-- Multiple characters --> + <mn>p</mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mn>p</mn> + <mo form="infix" lspace="0.2777777777777778em" rspace="0.2777777777777778em">X</mo> <!-- Explicit form --> + <mn>p</mn> + </mrow> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace.html new file mode 100644 index 0000000000..e6b5b172c3 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>lspace/rspace default value for unknown operators</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies that the default lspace/rspace are 0.2777777777777778em for entries that are not in the operator dictionary."> + <link rel="match" href="mo-not-in-dictionary-lspace-rspace-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 100px/1 Ahem; + } + mo { + color: blue; + } + </style> + </head> + <body> + <p>This test passes if on each row, the space around the blue rectangle + is 0.2777777777777778em.</p> + <p> + <math> + <mrow> + <mn>p</mn> + <mo>X</mo> <!-- Single character --> + <mn>p</mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mn>p</mn> + <mo>XX</mo> <!-- Multiple characters --> + <mn>p</mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mn>p</mn> + <mo form="infix">X</mo> <!-- Explicit form --> + <mn>p</mn> + </mrow> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits-ref.html new file mode 100644 index 0000000000..e7ffc78994 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits-ref.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>movablelimits default value for unknown operators (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 50px/1 Ahem; + } + mo { + color: blue; + } + </style> + </head> + <body> + <p>This test passes if the black scripts are attached above and below + the corresponding blue base.</p> + <p> + <math> + <munderover> + <mo movablelimits="false">X</mo> <!-- Single character --> + <mn>X</mn> + <mn>X</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover> + <mo movablelimits="false">XX</mo> <!-- Multiple characters --> + <mn>X</mn> + <mn>X</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover> + <mo movablelimits="false" form="infix">X</mo> <!-- Explicit form --> + <mn>X</mn> + <mn>X</mn> + </munderover> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits.html new file mode 100644 index 0000000000..8a96e31953 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>movablelimits default value for unknown operators</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies that the default movablelimits is false for entries that are not in the operator dictionary."> + <link rel="match" href="mo-not-in-dictionary-movablelimits-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 50px/1 Ahem; + } + mo { + color: blue; + } + </style> + </head> + <body> + <p>This test passes if the black scripts are attached above and below + the corresponding blue base.</p> + <p> + <math> + <munderover> + <mo>X</mo> <!-- Single character --> + <mn>X</mn> + <mn>X</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover> + <mo>XX</mo> <!-- Multiple characters --> + <mn>X</mn> + <mn>X</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover> + <mo form="infix">X</mo> <!-- Explicit form --> + <mn>X</mn> + <mn>X</mn> + </munderover> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace-ref.html new file mode 100644 index 0000000000..da0b79ff9a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace-ref.html @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<html> + <head> + <title><mo> paint lspace rspace</title> + <meta charset="utf-8"> + </head> + <body> + <h1>LTR case</h1> + + <p>The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the left, + and a trailing space of 200px, which is as wide as the black block to the right.</p> + + <math> + <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace> + <mspace width="100px"></mspace> + <mo lspace="0px" rspace="0px">→</mo> + <mspace width="200px"></mspace> + <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <p>The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the left, + and a trailing space of 150px, which is as wide as the black block to the right.</p> + + <math> + <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace> + <mspace width="150px"></mspace> + <mo lspace="0px" rspace="0px">→</mo> + <mspace width="150px"></mspace> + <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <p>The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the left, + and a trailing space of 100px, which is as wide as the black block to the right.</p> + + <math> + <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace> + <mspace width="200px"></mspace> + <mo lspace="0px" rspace="0px">→</mo> + <mspace width="100px"></mspace> + <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <h1>RTL case</h1> + + <p>The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the right, + and a trailing space of 200px, which is as wide as the black block to the left.</p> + + <math dir="rtl"> + <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace> + <mspace width="100px"></mspace> + <mo lspace="0px" rspace="0px">→</mo> + <mspace width="200px"></mspace> + <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <p>The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the right, + and a trailing space of 150px, which is as wide as the black block to the left.</p> + + <math dir="rtl"> + <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace> + <mspace width="150px"></mspace> + <mo lspace="0px" rspace="0px">→</mo> + <mspace width="150px"></mspace> + <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <p>The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the right, + and a trailing space of 100px, which is as wide as the black block to the left.</p> + + <math dir="rtl"> + <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace> + <mspace width="200px"></mspace> + <mo lspace="0px" rspace="0px">→</mo> + <mspace width="100px"></mspace> + <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html new file mode 100644 index 0000000000..a3a3ed501e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html @@ -0,0 +1,71 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title><mo> paint lspace rspace</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <meta name="assert" content="Verifies values for lspace and rspace for element mo in LTR and RTL modes."> + <link rel="match" href="mo-paint-lspace-rspace-ref.html"> + </head> + <body> + <h1>LTR case</h1> + + <p>The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the left, + and a trailing space of 200px, which is as wide as the black block to the right.</p> + + <math> + <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace> + <mo lspace="100px" rspace="200px">→</mo> + <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <p>The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the left, + and a trailing space of 150px, which is as wide as the black block to the right.</p> + + <math> + <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace> + <mo lspace="150px" rspace="150px">→</mo> + <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <p>The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the left, + and a trailing space of 100px, which is as wide as the black block to the right.</p> + + <math> + <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace> + <mo lspace="200px" rspace="100px">→</mo> + <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <h1>RTL case</h1> + + <p>The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the right, + and a trailing space of 200px, which is as wide as the black block to the left.</p> + + <math dir="rtl"> + <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace> + <mo lspace="100px" rspace="200px">→</mo> + <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <p>The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the right, + and a trailing space of 150px, which is as wide as the black block to the left.</p> + + <math dir="rtl"> + <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace> + <mo lspace="150px" rspace="150px">→</mo> + <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace> + </math> + + <p>The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the right, + and a trailing space of 100px, which is as wide as the black block to the left.</p> + + <math dir="rtl"> + <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace> + <mo lspace="200px" rspace="100px">→</mo> + <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children-ref.html new file mode 100644 index 0000000000..6b4ccc775c --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children-ref.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title><mo> with a single character and children (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"/> + <style> + math { font: 25px/1 Ahem; } + </style> + </head> + <body> + <p>There should be 5/18em horizontal gaps around the middle rectangles:</p> + <p><math><mn>p</mn><mo><span>X</span></mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo>X<span></span></mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo><span></span>X</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo id="dynamic-add">X</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo id="dynamic-text-add">XX</mo><mn>p</mn></math></p> + + <p>There should be no horizontal gap around the middle rectangles:</p> + + <p><math><mn>p</mn><mo stretchy="false" lspace="0" rspace="0">X</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo id="dynamic-remove" stretchy="false" lspace="0" rspace="0"><span></span>X</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo stretchy="false" lspace="0" rspace="0"><!-- COMMENT -->X</mo><mn>p</mn></math></p> + + <p>There should be 4/18em horizontal gaps around the middle rectangles:</p> + <p><math><mn>p</mn><mo lspace="0.2222222222222222em" rspace="0.2222222222222222em">XX</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo id="dynamic-text-add-2" lspace="0.2222222222222222em" rspace="0.2222222222222222em">XX</mo><mn>p</mn></math></p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children.html new file mode 100644 index 0000000000..a911c44411 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <meta charset="utf-8"> + <title><mo> with a single character and children</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#dfn-algorithm-for-determining-the-properties-of-an-embellished-operator"> + <meta name="assert" content="Verify that the default operator properties are used for an mo element whose text is a single character but which contains children."> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"/> + <link rel="match" href="mo-single-char-and-children-ref.html"> + <style> + math { font: 25px/1 Ahem; } + </style> + </head> + <body> + <p>There should be 5/18em horizontal gaps around the middle rectangles:</p> + <p><math><mn>p</mn><mo><span>(</span></mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo>(<span></span></mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo><span></span>(</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo id="dynamic-add">(</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo id="dynamic-text-add">=</mo><mn>p</mn></math></p> + + <p>There should be no horizontal gap around the middle rectangles:</p> + + <p><math><mn>p</mn><mo stretchy="false">(</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo id="dynamic-remove" stretchy="false"><span></span>(</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo stretchy="false"><!-- COMMENT -->(</mo><mn>p</mn></math></p> + + <p>There should be 4/18em horizontal gaps around the middle rectangles:</p> + <p><math><mn>p</mn><mo>&<!-- COMMENT -->&</mo><mn>p</mn></math></p> + <p><math><mn>p</mn><mo id="dynamic-text-add-2">&</mo><mn>p</mn></math></p> + + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing"); + + let mo = document.getElementById("dynamic-add"); + mo.appendChild(document.createElement("span")); + + mo = document.getElementById("dynamic-text-add"); + mo.appendChild(document.createTextNode("=")); + + mo = document.getElementById("dynamic-text-add-2"); + mo.appendChild(document.createTextNode("&")); + + mo = document.getElementById("dynamic-remove"); + mo.removeChild(mo.firstElementChild); + + document.documentElement.classList.remove('reftest-wait'); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-001.html new file mode 100644 index 0000000000..f734253930 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-001.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Stretch properties</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<meta name="assert" content="Verify "> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math { + font: 25px/1 Ahem; + } + @font-face { + font-family: operators; + src: url("/fonts/math/operators.woff"); + } + mo { + font-family: operators; + } +</style> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + + var epsilon = 1; + var emToPx = 25; + var element; + + test(function() { + element = document.getElementById("mn_vertical_line"); + assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "<mn> element"); + + element = document.getElementById("mo_prefix_vertical_line"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "Prefix <mo> element"); + + element = document.getElementById("mo_infix_vertical_line"); + assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "Infix <mo> element"); + + element = document.getElementById("mo_postfix_vertical_line"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "Postfix <mo> element"); + }, `Stretchy vertical line`); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow> + <!-- Some non-element nodes before --> + <mo id="mo_prefix_vertical_line" style="color: green">|</mo> + <mn id="mn_vertical_line">|</mn> + <mspace width="1em" height="3em" depth="3em" style="background: blue"/> + <mo id="mo_infix_vertical_line" lspace="0" rspace="0">|</mo> + <mo id="mo_postfix_vertical_line" style="color: green">|</mo> + <!-- Some non-element nodes after --> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-dynamic-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-dynamic-001.html new file mode 100644 index 0000000000..5d447aa1d2 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-dynamic-001.html @@ -0,0 +1,154 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Dynamic stretch properties</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<meta name="assert" content="Verify stretchy, symmetric, largeop, minsize and maxsize are updated dynamically."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math { + font: 25px/1 Ahem; + } + @font-face { + font-family: operators; + src: url("/fonts/math/operators.woff"); + } + mo { + font-family: operators; + } +</style> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + + var epsilon = 1; + var emToPx = 25; + var element; + + test(function() { + element = document.getElementById("minsize_attach"); + element.setAttribute("minsize", "4em"); + assert_approx_equals(element.getBoundingClientRect().height, 4 * emToPx, epsilon, "attach"); + + element = document.getElementById("minsize_modify"); + element.setAttribute("minsize", "5em"); + assert_approx_equals(element.getBoundingClientRect().height, 5 * emToPx, epsilon, "modify"); + + element = document.getElementById("minsize_remove"); + element.removeAttribute("minsize"); + assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "remove"); + }, `minsize`); + + test(function() { + element = document.getElementById("maxsize_attach"); + element.setAttribute("maxsize", "4em"); + assert_approx_equals(element.getBoundingClientRect().height, 4 * emToPx, epsilon, "attach"); + + element = document.getElementById("maxsize_modify"); + element.setAttribute("maxsize", "5em"); + assert_approx_equals(element.getBoundingClientRect().height, 5 * emToPx, epsilon, "modify"); + + element = document.getElementById("maxsize_remove"); + element.removeAttribute("maxsize"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "remove"); + }, `maxsize`); + + test(function() { + element = document.getElementById("largeop_set_true"); + element.setAttribute("largeop", "true"); + assert_approx_equals(element.getBoundingClientRect().height, 2 * emToPx, epsilon, "set true"); + + element = document.getElementById("largeop_set_false"); + element.setAttribute("largeop", "false"); + assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "set false"); + }, `largeop`); + + test(function() { + element = document.getElementById("symmetric_set_true"); + element.setAttribute("symmetric", "true"); + assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "set true"); + + element = document.getElementById("symmetric_set_false"); + element.setAttribute("symmetric", "false"); + assert_approx_equals(element.getBoundingClientRect().height, 3 * emToPx, epsilon, "set false"); + }, `symmetric`); + + test(function() { + element = document.getElementById("stretchy_set_true"); + element.setAttribute("stretchy", "true"); + assert_approx_equals(element.getBoundingClientRect().height, 3 * emToPx, epsilon, "set true"); + + element = document.getElementById("stretchy_set_false"); + element.setAttribute("stretchy", "false"); + assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "set false"); + }, `stretchy`); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow> + <mspace width="1em" height="1em" style="background: blue"/> + <mo id="minsize_attach" stretchy="true" symmetric="false">⥯</mo> + <mo id="minsize_modify" minsize="3em" stretchy="true" symmetric="false">⥯</mo> + <mo id="minsize_remove" minsize="2em" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="6em" style="background: blue"/> + <mo id="maxsize_attach" stretchy="true" symmetric="false">⥯</mo> + <mo id="maxsize_modify" maxsize="3em" stretchy="true" symmetric="false">⥯</mo> + <mo id="maxsize_remove" maxsize="2em" stretchy="true" symmetric="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math displaystyle="true"> + <mspace width="1em" height="1em" style="background: blue"/> + <mrow> + <mo id="largeop_set_true" largeop="false" stretchy="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + <mrow> + <mo id="largeop_set_false" largeop="true" stretchy="false">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="3em" style="background: blue"/> + <mo id="symmetric_set_true" symmetric="false" stretchy="true">⥯</mo> + <mo id="symmetric_set_false" symmetric="true" stretchy="true">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mspace width="1em" height="3em" style="background: blue"/> + <mo id="stretchy_set_true" symmetric="false" stretchy="false">⥯</mo> + <mo id="stretchy_set_false" symmetric="false" stretchy="true">⥯</mo> + <mn><!-- not space like --></mn> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1-notref.html new file mode 100644 index 0000000000..5650be1936 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1-notref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict mo form</title> +</head> +<body> + <math> + <mrow> + <mo form="prefix">+</mo> + <!-- need a second child to avoid zeroing dictionary spacing --> + <mn>1</mn> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1.html new file mode 100644 index 0000000000..cdfcca4a57 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict mo form</title> + <link rel="mismatch" href="op-dict-1-notref.html"> +</head> +<body> + <math> + <mrow> + <mo form="infix">+</mo> + <mn>1</mn> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12-ref.html new file mode 100644 index 0000000000..3365b47d39 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict mo movablelimits</title> +</head> +<body> + <math> + <munder> + <mo>∑</mo> + <mi>x</mi> + </munder> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12.html new file mode 100644 index 0000000000..7d75c4c174 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict mo movablelimits</title> + <link rel="match" href="op-dict-12-ref.html"> +</head> +<body> + <math> + <munder> + <mo movablelimits="true">∑</mo> + <mi>x</mi> + </munder> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13-notref.html new file mode 100644 index 0000000000..e9e7614836 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13-notref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict mo movablelimits</title> +</head> +<body> + <math> + <munder> + <mo movablelimits="true">∑</mo> + <mi>x</mi> + </munder> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13.html new file mode 100644 index 0000000000..1b7c6bf38f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict mo movablelimits</title> + <link rel="mismatch" href="op-dict-13-notref.html"> +</head> +<body> + <math> + <munder> + <mo movablelimits="false">∑</mo> + <mi>x</mi> + </munder> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2-ref.html new file mode 100644 index 0000000000..9c910f8411 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict symmetric</title> +</head> +<body> + <math> + <mrow> + <mo symmetric="true">(</mo> + <mspace height="5em" depth="5em"/> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2.html new file mode 100644 index 0000000000..0a26fcae78 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict symmetric</title> + <link rel="match" href="op-dict-2-ref.html"> +</head> +<body> + <math> + <mrow> + <mo>(</mo> + <mspace height="5em" depth="5em"/> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3-notref.html new file mode 100644 index 0000000000..9c910f8411 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3-notref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict symmetric</title> +</head> +<body> + <math> + <mrow> + <mo symmetric="true">(</mo> + <mspace height="5em" depth="5em"/> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3.html new file mode 100644 index 0000000000..bf54ef8582 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict symmetric</title> + <link rel="mismatch" href="op-dict-3-notref.html"> +</head> +<body> + <math> + <mrow> + <mo symmetric="false">(</mo> + <mspace height="5em" depth="5em"/> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4-ref.html new file mode 100644 index 0000000000..a501e45c8c --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict stretchy</title> +</head> +<body> + <math> + <mrow> + <mo>(</mo> + <mfrac> + <mi>a</mi> + <mi>b</mi> + </mfrac> + <mo>)</mo> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4.html new file mode 100644 index 0000000000..f847890aa7 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict stretchy</title> + <link rel="match" href="op-dict-4-ref.html"> +</head> +<body> + <math> + <mrow> + <mo stretchy="true">(</mo> + <mfrac> + <mi>a</mi> + <mi>b</mi> + </mfrac> + <mo stretchy="true">)</mo> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5-notref.html new file mode 100644 index 0000000000..7ab29e3769 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5-notref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict stretchy</title> +</head> +<body> + <math> + <mrow> + <mo stretchy="false">(</mo> + <mfrac> + <mi>a</mi> + <mi>b</mi> + </mfrac> + <mo>)</mo> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5.html new file mode 100644 index 0000000000..8c8260d4cd --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict stretchy</title> + <link rel="mismatch" href="op-dict-5-notref.html"> +</head> +<body> + <math> + <mrow> + <mo>(</mo> + <mfrac> + <mi>a</mi> + <mi>b</mi> + </mfrac> + <mo>)</mo> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6-ref.html new file mode 100644 index 0000000000..cb642c4928 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict largeop</title> +</head> +<body> + <math displaystyle="true"> + <mrow> + <mo largeop="true">∑</mo> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6.html new file mode 100644 index 0000000000..6be4cc90a7 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict largeop</title> + <link rel="match" href="op-dict-6-ref.html"> +</head> +<body> + <math displaystyle="true"> + <mrow> + <mo>∑</mo> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7-notref.html new file mode 100644 index 0000000000..78dd195558 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7-notref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict largeop</title> +</head> +<body> + <math displaystyle="true"> + <mrow> + <mo>∑</mo> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7.html new file mode 100644 index 0000000000..04496eb4f3 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict largeop</title> + <link rel="mismatch" href="op-dict-7-notref.html"> +</head> +<body> + <math displaystyle="true"> + <mrow> + <mo largeop="false">∑</mo> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8-ref.html new file mode 100644 index 0000000000..b51ce01f36 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict lspace and rspace</title> +</head> +<body> + <math> + <mrow> + <mi>x</mi><mo form="prefix" lspace="0.16666666666666666em" rspace="0em">∂</mo><mi>y</mi> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8.html new file mode 100644 index 0000000000..0f9b81900e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict lspace and rspace</title> + <link rel="match" href="op-dict-8-ref.html"> +</head> +<body> + <math> + <mrow> + <mi>x</mi><mo form="prefix">∂</mo><mi>y</mi> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9-notref.html new file mode 100644 index 0000000000..b976536fac --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9-notref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict lspace and rspace</title> +</head> +<body> + <math> + <mrow> + <!-- This spacing was specified in older MathML specification, see + https://www.w3.org/TR/MathML3/appendixc.html --> + <mi>x</mi><mo form="prefix" lspace="0.1111111111111111em" rspace="0.05555555555555555em">∂</mo><mi>y</mi> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9.html new file mode 100644 index 0000000000..1e833e31a0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> + <title>op-dict lspace and rspace</title> + <link rel="mismatch" href="op-dict-9-notref.html"> +</head> +<body> + <math> + <mrow> + <mi>x</mi><mo form="prefix">∂</mo><mi>y</mi> + </mrow> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001-ref.html new file mode 100644 index 0000000000..88e0f5f736 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001-ref.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Spacing of Arabic operators (reference)</title> + <link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> + <style> + mo { + color: blue; + } + </style> + </head> + <body> + + <p>There should be no horizontal gaps between the squares:</p> + <p><math><mn>_</mn><mo lspace="0" rspace="0">𞻰</mo><mn>_</mn></math></p> + <p><math><mn>_</mn><mo lspace="0" rspace="0">𞻱</mo><mn>_</mn></math></p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001.html new file mode 100644 index 0000000000..05d2714af5 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Spacing of Arabic operators</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> + <meta name="assert" content="Verifies default spacing of the Arabic characters U+1EEF0 and U+1EEF1."> + <link rel="match" href="operator-dictionary-arabic-001-ref.html"> + <link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> + <style> + mo { + color: blue; + } + </style> + </head> + <body> + + <p>There should be no horizontal gaps between the squares:</p> + <p><math><mn>_</mn><mo>𞻰</mo><mn>_</mn></math></p> + <p><math><mn>_</mn><mo>𞻱</mo><mn>_</mn></math></p> + + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002-ref.html new file mode 100644 index 0000000000..f72fdc8403 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002-ref.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Stretching of Arabic operators (reference)</title> + <link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> + </head> + <body> + + <p>You should see two rectangles of width 3em and height 1em:</p> + + <p> + <math> + <munder> + <mo stretchy="true">_</mo> + <mspace width="3em"/> + </munder> + </math> + </p> + <p> + <math> + <munder> + <mo stretchy="true">_</mo> + <mspace width="3em"/> + </munder> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002.html new file mode 100644 index 0000000000..d116e1778d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Stretching of Arabic operators</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> + <meta name="assert" content="Verifies stretchy property of the Arabic characters U+1EEF0 and U+1EEF1."> + <link rel="match" href="operator-dictionary-arabic-002-ref.html"> + <link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> + </head> + <body> + + <p>You should see two rectangles of width 3em and height 1em:</p> + + <p> + <math> + <munder> + <mo>𞻰</mo> + <mspace width="3em"/> + </munder> + </math> + </p> + <p> + <math> + <munder> + <mo>𞻱</mo> + <mspace width="3em"/> + </munder> + </math> + </p> + + <script src="/mathml/support/feature-detection.js"></script> + <script src="/mathml/support/feature-detection-operators.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_operator_stretchy"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-combining.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-combining.html new file mode 100644 index 0000000000..8c891a2a25 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-combining.html @@ -0,0 +1,159 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary (combining char)</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<meta name="assert" content="Verify special handling of 2-char operator with a combining character"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<style> + mo { + color: blue; + } + mn { + background: black; + } +</style> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function spaceBetween(element, i, j) { + return element.children[j].getBoundingClientRect().left - + element.children[i].getBoundingClientRect().right; + } + function runTests() { + var epsilon = 1; + var emToPx = 25; + + [ + "equal", + "vertical_bar", + "left_normal_factor_semidirect_product", + "there_exists", + ].forEach(id => { + var div = document.getElementById(id); + var ref = div.getElementsByClassName("reference")[0]; + var totalSpaceRef = spaceBetween(ref, 0, 2); + var lspaceRef = spaceBetween(ref, 0, 1); + var rspaceRef = spaceBetween(ref, 1, 2); + Array.from(div.getElementsByClassName("combining")).forEach(element => { + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + var totalSpace = spaceBetween(element, 0, 2); + var lspace = spaceBetween(element, 0, 1); + var rspace = spaceBetween(element, 1, 2); + assert_approx_equals(totalSpace, totalSpaceRef, epsilon); + assert_approx_equals(rspace, rspaceRef, epsilon); + assert_approx_equals(lspace, lspaceRef, epsilon); + }, `Spacing around ${element.children[1].textContent}`); + }); + }); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <div id="equal"> + <p> + <math class="reference"> + <mn> </mn> + <mo>=</mo> + <mn> </mn> + </math> + </p> + <p> + <math class="combining"> + <mn> </mn> + <mo>≠</mo> + <mn> </mn> + </math> + </p> + <p> + <math class="combining"> + <mn> </mn> + <mo>=⃒</mo> + <mn> </mn> + </math> + </p> + </div> + <div id="vertical_bar"> + <p> + <math class="reference"> + <mn> </mn> + <mo stretchy="false">|</mo> + <mn> </mn> + </math> + </p> + <p> + <math class="combining"> + <mn> </mn> + <mo stretchy="false">|̸</mo> + <mn> </mn> + </math> + </p> + <p> + <math class="combining"> + <mn> </mn> + <mo stretchy="false">|⃒</mo> + <mn> </mn> + </math> + </p> + </div> + <div id="left_normal_factor_semidirect_product"> + <p> + <math class="reference"> + <mn> </mn> + <mo stretchy="false">⋉</mo> + <mn> </mn> + </math> + </p> + <p> + <math class="combining"> + <mn> </mn> + <mo stretchy="false">⋉̸</mo> + <mn> </mn> + </math> + </p> + <p> + <math class="combining"> + <mn> </mn> + <mo stretchy="false">⋉⃒</mo> + <mn> </mn> + </math> + </p> + </div> + <div id="there_exists"> + <p> + <math class="reference"> + <mn> </mn> + <mo stretchy="false">∃</mo> + <mn> </mn> + </math> + </p> + <p> + <math class="combining"> + <mn> </mn> + <mo stretchy="false">∄</mo> + <mn> </mn> + </math> + </p> + <p> + <math class="combining"> + <mn> </mn> + <mo stretchy="false">∃⃒</mo> + <mn> </mn> + </math> + </p> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars-ref.html new file mode 100644 index 0000000000..2cbed12940 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars-ref.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Spacing of empty and three-char operators (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 50px/1 Ahem; + } + mn:first-child { + color: blue; + } + mn:last-child { + color: yellow; + } + </style> + </head> + <body> + + <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">_</mo><mn>_</mn></math></p> + + <p>The spacing after the blue squares and before the yellow squares should be the same as the above reference:</p> + + <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em"><!-- empty --></mo><mn>_</mn></math></p> + <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">...</mo><mn>_</mn></math></p> + <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">lim</mo><mn>_</mn></math> + <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">max</mo><mn>_</mn></math> + <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">min</mo><mn>_</mn></math> + <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">|||</mo><mn>_</mn></math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars.html new file mode 100644 index 0000000000..231041c17f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Spacing of empty and three-char operators</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> + <meta name="assert" content="Verifies that empty and three-char operators use the default spacing."> + <link rel="match" href="operator-dictionary-empty-and-three-chars-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 50px/1 Ahem; + } + mn:first-child { + color: blue; + } + mn:last-child { + color: yellow; + } + </style> + </head> + <body> + + <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">_</mo><mn>_</mn></math></p> + + <p>The spacing after the blue squares and before the yellow squares should be the same as the above reference:</p> + + <p><math><mn>_</mn><mo><!-- empty --></mo><mn>_</mn></math></p> + <p><math><mn>_</mn><mo>...</mo><mn>_</mn></math></p> + <p><math><mn>_</mn><mo>lim</mo><mn>_</mn></math> + <p><math><mn>_</mn><mo>max</mo><mn>_</mn></math> + <p><math><mn>_</mn><mo>min</mo><mn>_</mn></math> + <p><math><mn>_</mn><mo>|||</mo><mn>_</mn></math> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-001.html new file mode 100644 index 0000000000..457deb3422 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-001.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "largeop", 0); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-002.html new file mode 100644 index 0000000000..5f132ac3b2 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-002.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "largeop", 1); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-003.html new file mode 100644 index 0000000000..cb1b1e6b9b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-003.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "largeop", 2); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-004.html new file mode 100644 index 0000000000..19a6f9b2f1 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-004.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "largeop", 3); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-005.html new file mode 100644 index 0000000000..fd04712693 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-005.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "largeop", 4); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-006.html new file mode 100644 index 0000000000..77d23f60f7 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-006.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "largeop", 5); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-001.html new file mode 100644 index 0000000000..0a21e277b4 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-001.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "movablelimits", 0); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-002.html new file mode 100644 index 0000000000..2d7dc414a0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-002.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "movablelimits", 1); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-003.html new file mode 100644 index 0000000000..e166d7ffbb --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-003.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "movablelimits", 2); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-004.html new file mode 100644 index 0000000000..d5dd12b383 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-004.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "movablelimits", 3); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-005.html new file mode 100644 index 0000000000..d8e96e17a6 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-005.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "movablelimits", 4); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-006.html new file mode 100644 index 0000000000..a6ddeb92ff --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-006.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "movablelimits", 5); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-001.html new file mode 100644 index 0000000000..6839b183be --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-001.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "lspace/rspace", 0); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-002.html new file mode 100644 index 0000000000..84113a9ac8 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-002.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "lspace/rspace", 1); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-003.html new file mode 100644 index 0000000000..387f61922d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-003.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "lspace/rspace", 2); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-004.html new file mode 100644 index 0000000000..b27024c2d3 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-004.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "lspace/rspace", 3); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-005.html new file mode 100644 index 0000000000..7acf5ab20e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-005.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "lspace/rspace", 4); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-006.html new file mode 100644 index 0000000000..928182cbe6 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-006.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "lspace/rspace", 5); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-001.html new file mode 100644 index 0000000000..beebe77ed7 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-001.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "stretchy", 0); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-002.html new file mode 100644 index 0000000000..2cdf0114db --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-002.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "stretchy", 1); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-003.html new file mode 100644 index 0000000000..4f0f0b3641 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-003.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "stretchy", 2); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-004.html new file mode 100644 index 0000000000..08428b8928 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-004.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "stretchy", 3); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-005.html new file mode 100644 index 0000000000..94fe507755 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-005.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "stretchy", 4); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-006.html new file mode 100644 index 0000000000..c4d5e44d43 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-006.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "stretchy", 5); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-001.html new file mode 100644 index 0000000000..c1154cebf5 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-001.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "symmetric", 0); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-002.html new file mode 100644 index 0000000000..3cb4b07a55 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-002.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "symmetric", 1); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-003.html new file mode 100644 index 0000000000..7588df48f8 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-003.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "symmetric", 2); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-004.html new file mode 100644 index 0000000000..f7d8bdc89d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-004.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "symmetric", 3); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-005.html new file mode 100644 index 0000000000..9303b9a482 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-005.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "symmetric", 4); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-006.html new file mode 100644 index 0000000000..90a812786a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-006.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Operator dictionary</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> +<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis"> +<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/feature-detection-operators.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/operator-dictionary.js"></script> +<script src="./support/operator-dictionary-tests.js"></script> +<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + async function runTests() { + let json = await fetchOperatorDictionary(); + await OperatorDictionaryTests.run(json, "symmetric", 5); + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001-ref.html new file mode 100644 index 0000000000..0c7642a20a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001-ref.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Painting of vertical assembly (reference)</title> +<style> + .container { + font-size: 50px; + position: absolute; + left: 1em; + top: 1em; + padding: 5px; + background: green; + width: 4em; + height: 8em; + } +</style> +<body> + <p>This test passes if you see a green rectangle and no red.</p> + <div class="container"> + </div> +</body> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001.html new file mode 100644 index 0000000000..2a9578badc --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001.html @@ -0,0 +1,73 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Painting of vertical assembly</title> +<link rel="match" href="painting-stretchy-operator-001-ref.html"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://crbug.com/1409380"> +<meta name="assert" content="Verify that vertical glyph assemblies are painted at the position of their bounding box."> +<script src="/mathml/support/fonts.js"></script> +<style> + .container { + font-size: 50px; + position: absolute; + left: 1em; + top: 1em; + padding: 5px; + background: green; + width: 4em; + height: 8em; + } + mo { + color: green; + background: red; + } + .frame { + position: absolute; + box-sizing: border-box; + border: 2px solid green; + } + @font-face { + font-family: stretchy; + src: url("/fonts/math/stretchy.woff"); + } + @font-face { + font-family: stretchy-centered-on-baseline; + src: url("/fonts/math/stretchy-centered-on-baseline.woff"); + } +</style> +<script> + function runTests() { + // Add a green frame around mo to avoid antialisasing/rounding issues. + Array.from(document.getElementsByTagName('mo')).forEach(mo => { + let box = mo.getBoundingClientRect(); + let div = document.createElement("div"); + div.className = 'frame'; + div.style.left = `${box.left-1}px`; + div.style.top = `${box.top-1}px`; + div.style.width = `${box.width+1}px`; + div.style.height = `${box.height+1}px`; + document.body.appendChild(div); + }); + document.documentElement.classList.remove("reftest-wait"); + } + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); +</script> +<body> + <p>This test passes if you see a green rectangle and no red.</p> + <div class="container"> + <!-- This font uses assembly glyphs with zero ink descent, which is what + Latin Modern Math does for U+007C VERTICAL LINE. --> + <math style="font-family: stretchy"> + <mspace height="4em"/> + <mo stretchy="true" symmetric="true">⥜</mo> + </math> + <!-- This font uses assembly glyphs with non-zero ink descent, which is what + Cambria Math does for U+007C VERTICAL LINE. --> + <math style="font-family: stretchy-centered-on-baseline"> + <mspace height="4em"/> + <mo stretchy="true" symmetric="true">⥜</mo> + </math> + </div> +</body> diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.css b/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.css new file mode 100644 index 0000000000..4f80ad7f8d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.css @@ -0,0 +1,10 @@ +@font-face { + font-family: operators; + src: url("/fonts/math/operators.woff"); +} +math, math * { + font-family: operators; + /* Use large enough font-size so that 1/18em = 2.77px > epsilon and + one can really distinguish lspace/rspace values. */ + font-size: 50px; +} diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.js b/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.js new file mode 100644 index 0000000000..35efc2ecb9 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.js @@ -0,0 +1,226 @@ +var OperatorDictionaryTests = { + "lspace/rspace": function(json, key) { + let parsedKey = splitKey(key); + let entry = json.dictionary[key]; + let epsilon = 1; + + document.body.insertAdjacentHTML("beforeend", `<div>\ +lspace/rspace for "${parsedKey.characters}" (${parsedKey.form}): \ +<math>\ + <mrow>\ + <mn> </mn>\ + <mo form="${parsedKey.form}">${parsedKey.characters}</mo>\ + <mn> </mn>\ + </mrow>\ +</math>\ + VS \ +<math>\ + <mrow>\ + <mn> </mn>\ + <mo form="${parsedKey.form}" lspace="${defaultPropertyValue(entry, 'lspace')}" rspace="${defaultPropertyValue(entry, 'rspace')}">${parsedKey.characters}</mo>\ + <mn> </mn>\ + </mrow>\ +</math>\ +</div>`); + var div = document.body.lastElementChild; + var mrows = div.getElementsByTagName("mrow"); + function spaceBetween(element, i, j) { + return element.children[j].getBoundingClientRect().left - + element.children[i].getBoundingClientRect().right; + } + var lspace = spaceBetween(mrows[0], 0, 1); + var rspace = spaceBetween(mrows[0], 1, 2); + var lspaceRef = spaceBetween(mrows[1], 0, 1); + var rspaceRef = spaceBetween(mrows[1], 1, 2); + assert_approx_equals(lspace, lspaceRef, epsilon, `lspace (${key})`); + assert_approx_equals(rspace, rspaceRef, epsilon, `rspace (${key})`); + div.style.display = "none"; + }, + + "movablelimits": function(json, key) { + let parsedKey = splitKey(key); + let entry = json.dictionary[key]; + let epsilon = 1; + + var defaultValue = defaultPropertyValue(entry, "movablelimits"); + document.body.insertAdjacentHTML("beforeend", `<div>\ +movablelimits for "${parsedKey.characters}" (${parsedKey.form}): \ +<math>\ + <munder>\ + <mo stretchy="false" form="${parsedKey.form}">${parsedKey.characters}</mo>\ + <mn> </mn>\ + </munder>\ +</math>\ + VS \ +<math>\ + <munder>\ + <mo stretchy="false" form="${parsedKey.form}" movablelimits="${defaultValue}">${parsedKey.characters}</mo>\ + <mn> </mn>\ + </munder>\ +</math>\ +</div>`); + var div = document.body.lastElementChild; + var munders = div.getElementsByTagName("munder"); + munder = munders[0].getBoundingClientRect() + munderRef = munders[1].getBoundingClientRect() + assert_approx_equals(munder.height, munderRef.height, epsilon, `Movablelimits property for ${key} should be '${defaultValue}'`); + div.style.display = "none"; + }, + + "largeop": function(json, key) { + let parsedKey = splitKey(key); + let entry = json.dictionary[key]; + let epsilon = 1; + + var defaultValue = defaultPropertyValue(entry, "largeop"); + document.body.insertAdjacentHTML("beforeend", `<div>\ +largeop for "${parsedKey.characters}" (${parsedKey.form}): \ +<math displaystyle="true">\ + <mo form="${parsedKey.form}">${parsedKey.characters}</mo>\ +</math>\ + VS \ +<math displaystyle="true">\ + <mo form="${parsedKey.form}" largeop="${defaultValue}">${parsedKey.characters}</mo>\ +</math>\ +</div>`); + var div = document.body.lastElementChild; + var mos = div.getElementsByTagName("mo"); + mo = mos[0].getBoundingClientRect() + moRef = mos[1].getBoundingClientRect() + assert_approx_equals(mo.height, moRef.height, epsilon, `Largeop property for ${key} should be '${defaultValue}'`); + div.style.display = "none"; + }, + + "stretchy": function(json, key) { + let parsedKey = splitKey(key); + let entry = json.dictionary[key]; + let epsilon = 1; + + if (entry.horizontal) { + // FIXME: Should really do a MathMLFeatureDetection to verify + // support for *horizontal* stretching. + var defaultValue = defaultPropertyValue(entry, "stretchy"); + document.body.insertAdjacentHTML("beforeend", `<div>\ +stretchy for "${parsedKey.characters}" (${parsedKey.form}): \ +<math>\ + <munder>\ + <mn> </mn>\ + <mo form="${parsedKey.form}">${parsedKey.characters}</mo>\ + </munder>\ +</math>\ + VS \ +<math>\ + <munder>\ + <mn> </mn>\ + <mo form="${parsedKey.form}" stretchy="${defaultValue}">${parsedKey.characters}</mo>\ + </munder>\ +</math>\ +</div>`); + var div = document.body.lastElementChild; + var mos = div.getElementsByTagName("mo"); + mo = mos[0].getBoundingClientRect() + moRef = mos[1].getBoundingClientRect() + assert_approx_equals(mo.width, moRef.width, epsilon, `Stretchy property for ${key} should be '${defaultValue}'`); + div.style.display = "none"; + } else { + var defaultValue = defaultPropertyValue(entry, "stretchy"); + document.body.insertAdjacentHTML("beforeend", `<div>\ +stretchy for "${parsedKey.characters}" (${parsedKey.form}): \ +<math>\ + <mrow>\ + <mo form="${parsedKey.form}" symmetric="false">${parsedKey.characters}</mo>\ + <mspace height="2em"></mspace>\ + </mrow>\ +</math>\ + VS \ +<math>\ + <mrow>\ + <mo form="${parsedKey.form}" symmetric="false" stretchy="${defaultValue}">${parsedKey.characters}</mo>\ + <mspace height="2em"></mspace>\ + </mrow>\ +</math>\ +</div>`); + var div = document.body.lastElementChild; + var mos = div.getElementsByTagName("mo"); + mo = mos[0].getBoundingClientRect() + moRef = mos[1].getBoundingClientRect() + assert_approx_equals(mo.height, moRef.height, epsilon, `Stretchy property for ${key} should be '${defaultValue}'`); + div.style.display = "none"; + } + }, + + "symmetric": function(json, key) { + let parsedKey = splitKey(key); + let entry = json.dictionary[key]; + let epsilon = 1; + + var defaultValue = defaultPropertyValue(entry, "symmetric"); + document.body.insertAdjacentHTML("beforeend", `<div>\ +symmetric for "${parsedKey.characters}" (${parsedKey.form}): \ +<math>\ + <mrow>\ + <mo form="${parsedKey.form}" stretchy="true">${parsedKey.characters}</mo>\ + <mspace height="1.5em"></mspace>\ + </mrow>\ +</math>\ + VS \ +<math>\ + <mrow>\ + <mo form="${parsedKey.form}" stretchy="true" symmetric="${defaultValue}">${parsedKey.characters}</mo>\ + <mspace height="1.5em"></mspace>\ + </mrow>\ +</math>\ +</div>`); + var div = document.body.lastElementChild; + var mos = div.getElementsByTagName("mo"); + mo = mos[0].getBoundingClientRect() + moRef = mos[1].getBoundingClientRect() + assert_approx_equals(mo.height, moRef.height, epsilon, `Symmetric property for ${key} should be '${defaultValue}'`); + div.style.display = "none"; + }, + + run: async function(json, name, fileIndex) { + let has_required_feature_for_testing = + await MathMLFeatureDetection[`has_operator_${name}`](); + + // The operator dictionary has more than one thousand of entries so the + // tests are grouped in chunks so that these don't get much more + // importance than other MathML tests. For easy debugging, one can set the + // chunk size to 1. Also, note that the test div will remain visible for + // failed tests. + const entryPerChunk = 50 + const filesPerProperty = 6 + + var counter = 0; + var test; + + for (key in json.dictionary) { + + // Skip this key if it does not belong to that test file. + if (counter % filesPerProperty != fileIndex) { + counter++; + continue; + } + + var counterInFile = (counter - fileIndex) / filesPerProperty; + if (counterInFile % entryPerChunk === 0) { + // Start of a new chunk. + // Complete current async tests and create new ones for the next chunk. + if (test) test.done(); + test = async_test(`Operator dictionary chunk ${1 + counterInFile / entryPerChunk} - ${name}`); + + test.step(function() { + assert_true(has_required_feature_for_testing, `${name} is supported`); + }); + } + test.step(function() { + OperatorDictionaryTests[name](json, key); + }); + + counter++; + } + + // Complete current async test. + if (test) test.done(); + } +}; diff --git a/testing/web-platform/tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001-ref.html new file mode 100644 index 0000000000..632d6739db --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001-ref.html @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Dynamic radical: paint invalidation (expectation)</title> +<style> + @font-face { + font-family: RadicalFont; + src: url("/fonts/math/radical-displaystyleverticalgap7000-rulethickness1000.woff"); + } + math { + font-family: RadicalFont; + font-size: 10px; + } + #container > div { + height: 80px; + border-top: solid; + } + .withPaddingBorderAndMargin { + padding: 5px; + border: 5px solid yellow; + margin: 5px; + } +</style> +</head> +<body> + <div id="container"> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="60px" height="10px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="60px" height="10px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="20px" height="20px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="20px" height="20px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="20px" height="10px" depth="40px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="20px" height="10px" depth="40px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt class="withPaddingBorderAndMargin"> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot class="withPaddingBorderAndMargin"> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001.html b/testing/web-platform/tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001.html new file mode 100644 index 0000000000..4e9375842d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/radicals/dynamic-radical-paint-invalidation-001.html @@ -0,0 +1,167 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Dynamic radical: paint invalidation</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<meta name="assert" content=""> +<link rel="match" href="dynamic-radical-paint-invalidation-001-ref.html"> +<style> + @font-face { + font-family: RadicalFont; + src: url("/fonts/math/radical-displaystyleverticalgap7000-rulethickness1000.woff"); + } + @font-face { + font-family: RadicalFont2; + src: url("/fonts/math/radical-kernbeforedegree4000-rulethickness1000.woff"); + } + math { + font-family: RadicalFont; + font-size: 10px; + } + #container > div { + height: 80px; + border-top: solid; + } + .withPaddingBorderAndMargin { + padding: 5px; + border: 5px solid yellow; + margin: 5px; + } +</style> +<script src="/mathml/support/fonts.js"></script> +<script> + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + function runTests() { + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + var mroot = document.getElementsByTagName("mroot"); + var msqrt = document.getElementsByTagName("msqrt"); + + // Modify base's width. + msqrt[0].firstElementChild.setAttribute("width", "60px") + mroot[0].firstElementChild.setAttribute("width", "60px") + + // Modify base's ascent. + msqrt[1].firstElementChild.setAttribute("height", "20px") + mroot[1].firstElementChild.setAttribute("height", "20px") + + // Modify base's descent. + msqrt[2].firstElementChild.setAttribute("depth", "40px") + mroot[2].firstElementChild.setAttribute("depth", "40px") + + // Modify the radical's font family. + msqrt[3].parentNode.removeAttribute("style"); + mroot[3].parentNode.removeAttribute("style"); + + // Modify radical's margin/border/padding + msqrt[4].setAttribute("class", "withPaddingBorderAndMargin"); + mroot[4].setAttribute("class", "withPaddingBorderAndMargin"); + + document.documentElement.classList.remove('reftest-wait'); + }; +</script> +</head> +<body> + <div id="container"> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math style="font-family: RadicalFont2"> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math style="font-family: RadicalFont2"> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + </msqrt> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + <div> + <math> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + <mroot> + <mspace width="20px" height="10px" depth="10px" style="background: blue"/> + <mspace width="20px" height="10px" depth="10px" style="background: lightblue"/> + </mroot> + <mspace width="20px" height="10px" depth="10px" style="background: gray"/> + </math> + </div> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/radicals/radical-rendering-from-in-flow-ref.html b/testing/web-platform/tests/mathml/presentation-markup/radicals/radical-rendering-from-in-flow-ref.html new file mode 100644 index 0000000000..e1b8c3d161 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/radicals/radical-rendering-from-in-flow-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>radicals rendering from in-flow children</title> + </head> + <body> + <math> + <msqrt> + <mspace width="64px" height="8px" style="background: lightblue"></mspace> + </msqrt> + <mroot> + <mspace width="64px" height="12px" style="background: lightblue"></mspace> + <mspace width="128px" height="24px" style="background: lightgreen"></mspace> + </mroot> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/radicals/radical-rendering-from-in-flow.html b/testing/web-platform/tests/mathml/presentation-markup/radicals/radical-rendering-from-in-flow.html new file mode 100644 index 0000000000..7a5de3811b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/radicals/radical-rendering-from-in-flow.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>radicals rendering from in-flow children</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> + <meta name="assert" content="Verify rendering of radicals is only affected by in-flow children."> + <style> + .oof1 { + position: absolute; + } + .oof2 { + position: fixed; + } + .nobox { + display: none; + } + </style> + <link rel="match" href="radical-rendering-from-in-flow-ref.html"> + </head> + <body> + <math> + <msqrt> + <mspace width="32px" class="oof1"/> + <mspace width="16px" class="oof2"/> + <mspace width="8px" class="nobox"/> + <mspace width="64px" height="8px" style="background: lightblue"></mspace> + <mspace width="32px" class="oof1"/> + <mspace width="16px" class="oof2"/> + <mspace width="8px" class="nobox"/> + </msqrt> + <mroot> + <mspace width="32px" class="oof1"/> + <mspace width="16px" class="oof2"/> + <mspace width="8px" class="nobox"/> + <mspace width="64px" height="12px" style="background: lightblue"></mspace> + <mspace width="32px" class="oof1"/> + <mspace width="16px" class="oof2"/> + <mspace width="8px" class="nobox"/> + <mspace width="128px" height="24px" style="background: lightgreen"></mspace> + <mspace width="32px" class="oof1"/> + <mspace width="16px" class="oof2"/> + <mspace width="8px" class="nobox"/> + </mroot> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_msqrt");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/radicals/root-parameters-1.html b/testing/web-platform/tests/mathml/presentation-markup/radicals/root-parameters-1.html new file mode 100644 index 0000000000..7600c35c59 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/radicals/root-parameters-1.html @@ -0,0 +1,222 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Radical parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<meta name="assert" content="Elements msqrt and mroot correctly use the radical parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace { + font-size: 10px; + } + @font-face { + font-family: degreebottomraisepercent25-rulethickness1000; + src: url("/fonts/math/radical-degreebottomraisepercent25-rulethickness1000.woff"); + } + @font-face { + font-family: displaystyleverticalgap7000-rulethickness1000; + src: url("/fonts/math/radical-displaystyleverticalgap7000-rulethickness1000.woff"); + } + @font-face { + font-family: extraascender3000-rulethickness1000; + src: url("/fonts/math/radical-extraascender3000-rulethickness1000.woff"); + } + @font-face { + font-family: kernafterdegreeminus5000-rulethickness1000; + src: url("/fonts/math/radical-kernafterdegreeminus5000-rulethickness1000.woff"); + } + @font-face { + font-family: kernbeforedegree4000-rulethickness1000; + src: url("/fonts/math/radical-kernbeforedegree4000-rulethickness1000.woff"); + } + @font-face { + font-family: verticalgap6000-rulethickness1000; + src: url("/fonts/math/radical-verticalgap6000-rulethickness1000.woff"); + } + @font-face { + font-family: rulethickness8000; + src: url("/fonts/math/radical-rulethickness8000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 25; + var v2 = 1000 * emToPx; + var radicalHeight = getBox("base001").height + v2; + assert_approx_equals(getBox("ref001").top - getBox("index001").bottom, + v1 * radicalHeight / 100, epsilon, + "mroot: vertical position of index"); + }, "RadicalDegreeBottomRaisePercent"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 7000 * emToPx; + var v2 = 1000 * emToPx; + assert_approx_equals(getBox("base0021").top - getBox("radical0021").top, + v1 + v2, epsilon, + "msqrt: vertical gap"); + assert_approx_equals(getBox("base0022").top - getBox("radical0022").top, + v1 + v2, epsilon, + "mroot: vertical gap"); + }, "RadicalDisplayStyleVerticalGap"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 3000 * emToPx; + var v2 = 1000 * emToPx; + assert_approx_equals(getBox("base0031").top - getBox("radical0031").top, + v1 + v2, epsilon, + "msqrt: vertical gap"); + assert_approx_equals(getBox("base0032").top - getBox("radical0032").top, + v1 + v2, epsilon, + "mroot: vertical gap"); + }, "RadicalExtraAscender"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + // Note: the size variants of U+221A in this font have width 1000. + var v1 = 5000 * emToPx; + var radicalSymbolWidth = 1000 * emToPx; + var radicalLeft = getBox("base004").left - radicalSymbolWidth; + assert_approx_equals(getBox("index004").right - radicalLeft, + v1, epsilon, + "mroot: kern after degree"); + }, "RadicalKernAfterDegree"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 4000 * emToPx; + assert_approx_equals(getBox("index005").left - getBox("radical005").left, + v1, epsilon, + "mroot: kern before degree"); + }, "RadicalKernBeforeDegree"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 8000 * emToPx; + assert_approx_equals(getBox("base0061").top - getBox("radical0061").top, + v, epsilon, + "msqrt: vertical gap"); + assert_approx_equals(getBox("base0062").top - getBox("radical0062").top, + v, epsilon, + "msqrt: vertical gap"); + }, "RadicalRuleThickness"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 6000 * emToPx; + var v2 = 1000 * emToPx; + assert_approx_equals(getBox("base0071").top - getBox("radical0071").top, + v1 + v2, epsilon, + "msqrt: vertical gap"); + assert_approx_equals(getBox("base0072").top - getBox("radical0072").top, + v1 + v2, epsilon, + "msqrt: vertical gap"); + }, "RadicalVerticalGap"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: degreebottomraisepercent25-rulethickness1000;"> + <mspace id="ref001" width="3em" depth="1em" style="background: green"/> + <mroot> + <mspace id="base001" width="3em" height="10em" style="background: green"/> + <mspace id="index001" width="3em" height="1em" style="background: blue"/> + </mroot> + </math> + </p> + <hr/> + <p> + <math display="block" + style="font-family: displaystyleverticalgap7000-rulethickness1000;"> + <msqrt style="background: green" id="radical0021"> + <mspace id="base0021" width="3em" height="1em" style="background: blue"/> + </msqrt> + <mroot style="background: green" id="radical0022"> + <mspace id="base0022" width="3em" height="1em" style="background: blue"/> + <mspace width="3em" height="1em" style="background: black"/> + </mroot> + </math> + </p> + <hr/> + <p> + <math style="font-family: extraascender3000-rulethickness1000;"> + <msqrt style="background: green" id="radical0031"> + <mspace id="base0031" width="3em" height="1em" style="background: blue"/> + </msqrt> + <mroot style="background: green" id="radical0032"> + <mspace id="base0032" width="3em" height="1em" style="background: blue"/> + <mspace width="3em" height="1em" style="background: black"/> + </mroot> + </math> + </p> + <hr/> + <p> + <math style="font-family: kernafterdegreeminus5000-rulethickness1000;"> + <mroot> + <mspace id="base004" width="3em" height="2em" style="background: blue"/> + <mspace id="index004" width="7em" height="1em" style="background: green"/> + </mroot> + </math> + </p> + <hr/> + <p> + <math style="font-family: kernbeforedegree4000-rulethickness1000;"> + <mroot id="radical005" style="background: blue"> + <mspace width="3em" height="1em"/> + <mspace id="index005" width="3em" height="1em" style="background: green"/> + </mroot> + </math> + </p> + <hr/> + <p> + <math style="font-family: rulethickness8000;"> + <msqrt style="background: green" id="radical0061"> + <mspace id="base0061" width="3em" height="1em" style="background: blue"/> + </msqrt> + <mroot style="background: green" id="radical0062"> + <mspace id="base0062" width="3em" height="1em" style="background: blue"/> + <mspace width="3em" height="1em" style="background: black"/> + </mroot> + </math> + </p> + <p> + <math style="font-family: verticalgap6000-rulethickness1000;"> + <msqrt style="background: green" id="radical0071"> + <mspace id="base0071" width="3em" height="1em" style="background: blue"/> + </msqrt> + <mroot style="background: green" id="radical0072"> + <mspace id="base0072" width="3em" height="1em" style="background: blue"/> + <mspace width="3em" height="1em" style="background: black"/> + </mroot> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/radicals/root-parameters-2.html b/testing/web-platform/tests/mathml/presentation-markup/radicals/root-parameters-2.html new file mode 100644 index 0000000000..01d636b522 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/radicals/root-parameters-2.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Radical parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<meta name="assert" content="Test edge kerning values for radicals."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + @font-face { + font-family: radical-negativekernbeforedegree1000-rulethickness1000; + src: url("/fonts/math/radical-negativekernbeforedegree1000-rulethickness1000.woff"); + } + @font-face { + font-family: radical-kernafterdegreeminus5000-rulethickness1000; + src: url("/fonts/math/radical-kernafterdegreeminus5000-rulethickness1000.woff"); + } + math, mspace { + font-size: 10px; + } + mspace { + opacity: .5; + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(getBox("index001").left - getBox("mroot001").left, + 0, epsilon, "should be clamped to 0"); + }, "RadicalKernBeforeDegree = -1em < 0"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var radicalSymbolWidth = 1000 * emToPx; + var radicalLeft = getBox("base002").left - radicalSymbolWidth; + assert_approx_equals(getBox("index002").right - radicalLeft, + 30, epsilon, "should be clamped to 3em"); + }, "RadicalKernBeforeAfterDegree = -5em < -3em = -degree's inline size"); + + done(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: radical-negativekernbeforedegree1000-rulethickness1000"> + <mroot id="mroot001"> + <mspace id="base001" height="6em" width="6em" style="background: blue"/> + <mspace id="index001" height="6em" width="6em" style="background: green"/> + </mroot> + </math> + </p> + <hr/> + <p> + <math style="font-family: radical-kernafterdegreeminus5000-rulethickness1000"> + <mroot id="mroot002"> + <mspace id="base002" height="3em" width="3em" style="background: blue"/> + <mspace id="index002" height="3em" width="3em" style="background: green"/> + </mroot> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/cramped-001.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/cramped-001.html new file mode 100644 index 0000000000..e03b4d968d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/cramped-001.html @@ -0,0 +1,627 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Cramped elements</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<link rel="help" href="https://w3c.github.io/mathml-core/#displaystyle-and-scriptlevel-in-scripts"> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<meta name="assert" content="Verify default calculation of math-shift on MathML elements"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script src="/mathml/support/box-navigation.js"></script> +<style> + math { + font-family: superscriptshiftupcramped5000; + } + math, math * { + font-size: 10px; + background: lightyellow; + } + @font-face { + font-family: superscriptshiftupcramped5000; + src: url("/fonts/math/scripts-superscriptshiftupcramped5000.woff"); + } + .testedElement *:first-child { + background: lightblue; + } + .testedElement *:last-child { + background: pink; + } +</style> +<script> + function assert_cramped(id, expected, name) { + const emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + const superscriptshiftupcramped = 5000 * emToPx; + var container = document.getElementById(id); + var msup = container.getElementsByClassName("testedElement")[0]; + var base = firstInFlowChild(msup); + var script = nextInFlowSibling(base); + var shift = base.getBoundingClientRect().bottom - script.getBoundingClientRect().bottom; + if (expected) + assert_greater_than(shift, superscriptshiftupcramped / 2, `${name || id} should be cramped`); + else + assert_less_than(shift, superscriptshiftupcramped / 2, `${name || id} should not be cramped`); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("math-001", false); + assert_cramped("mrow-001", false, "mrow"); + }, "child of non-cramped element"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("mrow-002", true); + }, "child of cramped element"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("msqrt-001", true); + }, "child of msqrt"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("mroot-001", true); + }, "child of mroot"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("mfrac-001", false, "numerator"); + assert_cramped("mfrac-002", true, "denominator"); + }, "child of mfrac"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("msub-001", false, "base"); + assert_cramped("msub-002", true, "subscript"); + }, "child of msub"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("msup-001", false, "base"); + assert_cramped("msup-002", false, "superscript"); + }, "child of msup"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("msubsup-001", false, "base"); + assert_cramped("msubsup-002", true, "subscript"); + assert_cramped("msubsup-003", false, "superscript"); + }, "child of msubsup"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("munder-001", false, "base"); + assert_cramped("munder-002", false, "underscript"); + }, "child of munder"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("mover-001", false, "base"); + assert_cramped("mover-002", false, "overscript"); + }, "child of mover (non-accent overscript)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("munderover-001", false, "base"); + assert_cramped("munderover-002", false, "underscript"); + assert_cramped("munderover-003", false, "overscript"); + }, "child of munderover (non-accent overscript)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("mover-003", true, "base"); + assert_cramped("mover-004", false, "overscript"); + }, "accent child of mover (accent overscript)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("munderover-004", true, "base"); + assert_cramped("munderover-005", false, "underscript"); + assert_cramped("munderover-006", false, "overscript"); + }, "accent child of munderover (accent overscript)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("mmultiscripts-001", false, "base"); + assert_cramped("mmultiscripts-002", true, "post-subscript"); + assert_cramped("mmultiscripts-003", false, "post-superscript"); + assert_cramped("mmultiscripts-004", true, "pre-subscript"); + assert_cramped("mmultiscripts-005", false, "post-superscript"); + }, "mmultiscripts"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_cramped("css-001", false); + assert_cramped("css-002", true); + assert_cramped("css-003", true); + assert_cramped("css-004", false); + }, "element with specified CSS math-style"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math id="math-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </math> + <math> + <mrow id="mrow-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </mrow> + </math> + </p> + <p> + <math> + <msqrt> + <!-- This is a child of a msqrt so it is cramped. As a consequence, + all its descendants are cramped too. --> + <munderover> + <mover> + <munder> + <msubsup> + <msup> + <msub> + <mfrac> + <mrow id="mrow-002"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </mrow> + <mspace/> + </mfrac> + <mspace/> + </msub> + <mspace/> + </msup> + <mspace/> + <mspace/> + </msubsup> + <mspace/> + </munder> + <mspace/> + </mover> + <mspace/> + <mspace/> + </munderover> + </msqrt> + </math> + </p> + <p> + <math> + <msqrt id="msqrt-001"> + <mn>0</mn> + <mn>1</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>3</mn> + <mn>4</mn> + </msqrt> + </math> + </p> + <p> + <math> + <mroot id="mroot-001"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </mroot> + </math> + </p> + <p> + <math> + <mroot id="mroot-002"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + </mroot> + </math> + </p> + <p> + <math> + <mfrac id="mfrac-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + </mfrac> + </math> + </p> + <p> + <math> + <mfrac id="mfrac-002"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </mfrac> + </math> + </p> + <p> + <math> + <msub id="msub-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + </msub> + </math> + </p> + <p> + <math> + <msub id="msub-002"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </msub> + </math> + </p> + <p> + <math> + <msup id="msup-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + </msup> + </math> + </p> + <p> + <math> + <msup id="msup-002"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </msup> + </math> + </p> + <p> + <math> + <msubsup id="msubsup-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + <mn>2</mn> + </msubsup> + </math> + </p> + <p> + <math> + <msubsup id="msubsup-002"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>2</mn> + </msubsup> + </math> + </p> + <p> + <math> + <msubsup id="msubsup-003"> + <mn>0</mn> + <mn>1</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </msubsup> + </math> + </p> + <p> + <math> + <munder id="munder-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + </munder> + </math> + </p> + <p> + <math> + <munder id="munder-002"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </munder> + </math> + </p> + <p> + <math> + <mover id="mover-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + </mover> + </math> + </p> + <p> + <math> + <mover id="mover-002"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </mover> + </math> + </p> + <p> + <math> + <mover accent="true" id="mover-003"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + </mover> + </math> + </p> + <p> + <math> + <mover accent="true" id="mover-004"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </mover> + </math> + </p> + <p> + <math> + <munderover id="munderover-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + <mn>2</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover id="munderover-002"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>2</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover id="munderover-003"> + <mn>0</mn> + <mn>1</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </munderover> + </math> + </p> + <p> + <math> + <munderover accent="true" id="munderover-004"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + <mn>2</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover accent="true" id="munderover-005"> + <mn>0</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>2</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover accent="true" id="munderover-006"> + <mn>0</mn> + <mn>1</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </munderover> + </math> + </p> + <p> + <math> + <mmultiscripts id="mmultiscripts-001"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>1</mn> + <mn>2</mn> + <mn>3</mn> + <mn>4</mn> + <mn>5</mn> + <mn>6</mn> + <mprescripts/> + <mn>7</mn> + <mn>8</mn> + <mn>9</mn> + <mn>10</mn> + <mn>11</mn> + <mn>12</mn> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts id="mmultiscripts-002"> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>4</mn> + <mn>5</mn> + <mn>6</mn> + <mprescripts/> + <mn>7</mn> + <mn>8</mn> + <mn>9</mn> + <mn>10</mn> + <mn>11</mn> + <mn>12</mn> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts id="mmultiscripts-003"> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + <mn>3</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>5</mn> + <mn>6</mn> + <mprescripts/> + <mn>7</mn> + <mn>8</mn> + <mn>9</mn> + <mn>10</mn> + <mn>11</mn> + <mn>12</mn> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts id="mmultiscripts-004"> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + <mn>3</mn> + <mn>4</mn> + <mn>5</mn> + <mn>6</mn> + <mprescripts/> + <mn>7</mn> + <mn>8</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>10</mn> + <mn>11</mn> + <mn>12</mn> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts id="mmultiscripts-005"> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + <mn>3</mn> + <mn>4</mn> + <mn>5</mn> + <mn>6</mn> + <mprescripts/> + <mn>7</mn> + <mn>8</mn> + <mn>9</mn> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + <mn>11</mn> + <mn>12</mn> + </mmultiscripts> + </math> + </p> + <p> + <math id="css-001" style="math-shift: normal"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </math> + <math id="css-002" style="math-shift: compact"> + <msup class="testedElement"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </math> + <math id="css-003" style="math-shift: normal"> + <msup class="testedElement" style="math-shift: compact"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </math> + <math id="css-004" style="math-shift: compact"> + <msup class="testedElement" style="math-shift: normal"> + <mspace height="2em" width="2em"/> + <mspace height="1em" width="1em"/> + </msup> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/empty-underover.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/empty-underover.html new file mode 100644 index 0000000000..b5fcc9c4ca --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/empty-underover.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test Script and Limit Schemata</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#script-and-limit-schemata"> +<meta name="assert" content="Script and Limit Schemata should not render anything when empty."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script> + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + ["over", "under", "underover", "sub", "sup", "subsup", "multiscripts"].forEach(function(name) { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(getBox(name).width, 0, epsilon, "width of empty " + name); + assert_approx_equals(getBox(name).height, 0, epsilon, "height of empty " + name); + }); + }, "Size of empty script elements"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <munderover id="underover"> + </munderover> + </math> + <math> + <munder id="under"> + </munder> + </math> + <math> + <mover id="over"> + </mover> + </math> + <math> + <msub id="sub"> + </msub> + </math> + <math> + <msup id="sup"> + </msup> + </math> + <math> + <msubsup id="subsup"> + </msubsup> + </math> + <math> + <mmultiscripts id="multiscripts"> + </mmultiscripts> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/mover-accent-dynamic-change-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/mover-accent-dynamic-change-ref.html new file mode 100644 index 0000000000..a4f16aa07f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/mover-accent-dynamic-change-ref.html @@ -0,0 +1,9 @@ +<!doctype html> +<title>MathML Reference</title> +<p>The 1's below should have the same size</p> +<math> + <mover accent="true"> + <mn>1</mn> + <mn>1</mn> + </mover> +</math> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/mover-accent-dynamic-change.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/mover-accent-dynamic-change.html new file mode 100644 index 0000000000..a744149e60 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/mover-accent-dynamic-change.html @@ -0,0 +1,16 @@ +<!doctype html> +<title>MathML: Dynamically change accent on mover</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#displaystyle-and-scriptlevel-in-scripts"> +<link rel="match" href="mover-accent-dynamic-change-ref.html"> +<meta name="assert" content="Test that setting the accent attribute on mover takes effect"> +<p>The 1's below should have the same size</p> +<math> + <mover id="m"> + <mn>1</mn> + <mn>1</mn> + </mover> +</math> +<script> + document.body.offsetTop; + m.setAttribute("accent", "true"); +</script> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/mprescripts-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/mprescripts-001-ref.html new file mode 100644 index 0000000000..f8631539c0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/mprescripts-001-ref.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mprescripts should render as an mrow (reference)</title> + </head> + <body> + <math> + <mrow> + <mspace width="10px" height="20px" style="background: cyan;"></mspace> + <mspace width="30px" height="10px" depth="5px" style="background: blue;"></mspace> + <mspace width="20px" height="15px" depth="30px" style="background: lightblue;"></mspace> + <mspace width="25px" depth="20px" style="background: cyan;"></mspace> + <mspace width="40px" height="5px" depth="15px" style="background: blue;"></mspace> + <mspace width="20px" height="35px" depth="5px" style="background: lightblue;"></mspace> + </mrow> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/mprescripts-001.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/mprescripts-001.html new file mode 100644 index 0000000000..2435b6291d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/mprescripts-001.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mprescripts should render as an mrow</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> + <meta name="assert" content="Verify that mprescripts uses mrow layout"> + <link rel="match" href="mprescripts-001-ref.html"> + </head> + <body> + <math> + <mprescripts> + <mspace width="10px" height="20px" style="background: cyan;"></mspace> + <mspace width="30px" height="10px" depth="5px" style="background: blue;"></mspace> + <mspace width="20px" height="15px" depth="30px" style="background: lightblue;"></mspace> + <mspace width="25px" depth="20px" style="background: cyan;"></mspace> + <mspace width="40px" height="5px" depth="15px" style="background: blue;"></mspace> + <mspace width="20px" height="35px" depth="5px" style="background: lightblue;"></mspace> + </mprescripts> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/none-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/none-001-ref.html new file mode 100644 index 0000000000..55add01415 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/none-001-ref.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>none should render as an mrow (reference)</title> + </head> + <body> + <math> + <mrow> + <mspace width="10px" height="20px" style="background: cyan;"></mspace> + <mspace width="30px" height="10px" depth="5px" style="background: blue;"></mspace> + <mspace width="20px" height="15px" depth="30px" style="background: lightblue;"></mspace> + <mspace width="25px" depth="20px" style="background: cyan;"></mspace> + <mspace width="40px" height="5px" depth="15px" style="background: blue;"></mspace> + <mspace width="20px" height="35px" depth="5px" style="background: lightblue;"></mspace> + </mrow> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/none-001.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/none-001.html new file mode 100644 index 0000000000..f1bfb442f7 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/none-001.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>none should render as an mrow</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> + <meta name="assert" content="Verify that none uses mrow layout"> + <link rel="match" href="none-001-ref.html"> + </head> + <body> + <math> + <none> + <mspace width="10px" height="20px" style="background: cyan;"></mspace> + <mspace width="30px" height="10px" depth="5px" style="background: blue;"></mspace> + <mspace width="20px" height="15px" depth="30px" style="background: lightblue;"></mspace> + <mspace width="25px" depth="20px" style="background: cyan;"></mspace> + <mspace width="40px" height="5px" depth="15px" style="background: blue;"></mspace> + <mspace width="20px" height="35px" depth="5px" style="background: lightblue;"></mspace> + </none> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/none-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/none-002-ref.html new file mode 100644 index 0000000000..dac4dab553 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/none-002-ref.html @@ -0,0 +1,73 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>none used at other places than mmultiscripts' script (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { font: 25px/1 Ahem; } + </style> + </head> + <body> + <p> + <math> + <msub> + <mrow></mrow> + <mn>2</mn> + </msub> + </math> + <math> + <msub> + <mn>1</mn> + <mrow></mrow> + </msub> + </math> + </p> + <p> + <math> + <msup> + <mrow></mrow> + <mn>2</mn> + </msup> + </math> + <math> + <msup> + <mn>1</mn> + <mrow></mrow> + </msup> + </math> + </p> + <p> + <math> + <msubsup> + <mrow></mrow> + <mn>2</mn> + <mn>3</mn> + </msubsup> + </math> + <math> + <msubsup> + <mn>1</mn> + <mrow></mrow> + <mn>3</mn> + </msubsup> + </math> + <math> + <msubsup> + <mn>1</mn> + <mn>2</mn> + <mrow></mrow> + </msubsup> + </math> + </p> + <p> + <math> + <mmultiscripts> + <mrow></mrow> + <mn>2</mn> + <mn>3</mn> + </mmultiscripts> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/none-002.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/none-002.html new file mode 100644 index 0000000000..d1f3a3a0e1 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/none-002.html @@ -0,0 +1,76 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>none used at other places than mmultiscripts' script</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> + <meta name="assert" content="none can be used at other places than mmultiscripts' script, without triggering 'invalid markup'"> + <link rel="match" href="none-002-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { font: 25px/1 Ahem; } + </style> + </head> + <body> + <p> + <math> + <msub> + <none/> + <mn>2</mn> + </msub> + </math> + <math> + <msub> + <mn>1</mn> + <none/> + </msub> + </math> + </p> + <p> + <math> + <msup> + <none/> + <mn>2</mn> + </msup> + </math> + <math> + <msup> + <mn>1</mn> + <none/> + </msup> + </math> + </p> + <p> + <math> + <msubsup> + <none/> + <mn>2</mn> + <mn>3</mn> + </msubsup> + </math> + <math> + <msubsup> + <mn>1</mn> + <none/> + <mn>3</mn> + </msubsup> + </math> + <math> + <msubsup> + <mn>1</mn> + <mn>2</mn> + <none/> + </msubsup> + </math> + </p> + <p> + <math> + <mmultiscripts> + <none/> + <mn>2</mn> + <mn>3</mn> + </mmultiscripts> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-1.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-1.html new file mode 100644 index 0000000000..1117e1008e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-1.html @@ -0,0 +1,114 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Subscripts and Superscripts metrics</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<meta name="assert" content="Basic metrics for elements msub, msup and msubsup."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math, mspace { + font: 25px/1 Ahem; + } +</style> +<script> + /* This test does not use a font with a MATH table and does not verify layout + rules in a very strict way. */ + + function getBox(aId) { + var box = document.getElementById(aId).getBoundingClientRect(); + box.middle = (box.bottom + box.top) / 2; + return box; + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + assert_less_than_equal(getBox("msubBase").right, getBox("msubSub").left, e, "msub: subscript is after base"); + assert_less_than_equal(getBox("msupBase").right, getBox("msupSup").left, e, "msup: superscript is after base"); + assert_less_than_equal(getBox("msubsupBase").right, getBox("msubsupSub").left, e, "msubsup: subscript is after base"); + assert_less_than_equal(getBox("msubsupBase").right, getBox("msubsupSup").left, e, "msubsup: superscript is after base"); + + e = 3; + assert_approx_equals(getBox("msubBase").right, getBox("msubSub").left, e, "msub: space between base and subscript is small"); + assert_approx_equals(getBox("msubBase").right, getBox("msubSub").left, e, "msub: subscript is after base"); + assert_approx_equals(getBox("msupBase").right, getBox("msupSup").left, e, "msup: superscript is after base"); + assert_approx_equals(getBox("msubsupBase").right, getBox("msubsupSub").left, e, "msubsup: subscript is after base"); + assert_approx_equals(getBox("msubsupBase").right, getBox("msubsupSup").left, e, "msubsup: superscript is after base"); + }, "Respective horizontal positions"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + assert_approx_equals(getBox("msubBase").middle, getBox("baseline").bottom, e, "msub: base is placed on the baseline"); + assert_approx_equals(getBox("msupBase").middle, getBox("baseline").bottom, e, "msup: base is placed on the baseline"); + assert_approx_equals(getBox("msubsupBase").middle, getBox("baseline").bottom, e, "msubsup: base is placed on the baseline"); + }, "Alignment of the base on the baseline"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + assert_greater_than(getBox("msubSub").middle, getBox("msubBase").middle, "msub: script is placed at the bottom of the base"); + assert_less_than(getBox("msupSup").middle, getBox("msupBase").middle, "msup: script is placed at the top of the base"); + assert_greater_than(getBox("msubsupSub").middle, getBox("msubsupBase").middle, "msubsup: script is placed at the bottom of the base"); + assert_less_than(getBox("msubsupSup").middle, getBox("msubsupBase").middle, "msubsup: script is placed at the top of the base"); + }, "Vertical position of scripts"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 5; + assert_approx_equals(getBox("msub").width, getBox("msubSub").right - getBox("msubBase").left, e, "msub: width is determined by the left/right sides of base/script (+ some space after script)"); + assert_approx_equals(getBox("msup").width, getBox("msupSup").right - getBox("msupBase").left, e, "msup: width is determined by the left/right sides of base/script (+ some space after script)"); + assert_approx_equals(getBox("msubsup").width, Math.max(getBox("msubsupSub").right, getBox("msubsupSup").right) - getBox("msubsupBase").left, e, "msubsup: width is determined by the left/right sides of base/scripts (+ some space after script)"); + }, "Width of scripted elements"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + assert_greater_than_equal(getBox("msub").height, getBox("msubBase").height, e, "msub: height is at least the one of the base"); + assert_greater_than_equal(getBox("msup").height, getBox("msupBase").height, e, "msup: height is at least the one of the base"); + assert_greater_than_equal(getBox("msubsup").height, getBox("msubsupBase").height, e, "msubsup: height is at least the one of the base"); + + assert_approx_equals(getBox("msub").height, Math.max(getBox("msubSub").bottom, getBox("msubBase").bottom) - getBox("msubBase").top, e, "msub: height is determined by the top/bottom sides of base/scripts"); + assert_approx_equals(getBox("msup").height, getBox("msupBase").bottom - Math.min(getBox("msupSup").top, getBox("msupBase").top), e, "msup: height is determined by the top/bottom sides of base/scripts"); + assert_approx_equals(getBox("msubsup").height, Math.max(getBox("msubSub").bottom, getBox("msubBase").bottom) - Math.min(getBox("msupSup").top, getBox("msupBase").top), e, "msubsup: height is determined by the top/bottom sides of base/scripts"); + }, "Height of scripted elements"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <msub id="msub" style="background: green"> + <mspace id="msubBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubSub" width="10px" height="5px" depth="5px" style="background: black"/> + </msub> + <msup id="msup" style="background: blue"> + <mspace id="msupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msupSup" width="10px" height="5px" depth="5px" style="background: black"/> + </msup> + <msubsup id="msubsup" style="background: green"> + <mspace id="msubsupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubsupSub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsupSup" width="10px" height="5px" depth="5px" style="background: black"/> + </msubsup> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-2.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-2.html new file mode 100644 index 0000000000..9c89dd3727 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-2.html @@ -0,0 +1,173 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Subscripts and Superscripts metrics</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<meta name="assert" content="Basic metrics for the mmultiscript element."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math, mspace { + font: 25px/1 Ahem; + } +</style> +<script> + /* This test does not use a font with a MATH table and does not verify layout + rules in a very strict way. */ + + function getBox(aId) { + var box = document.getElementById(aId).getBoundingClientRect(); + box.middle = (box.bottom + box.top) / 2; + return box; + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + assert_less_than_equal(getBox("msubBase").right, getBox("msubSub").left, e, "subscript is after base"); + assert_less_than_equal(getBox("msupBase").right, getBox("msupSup").left, e, "superscript is after base"); + assert_less_than_equal(getBox("msubsupBase").right, getBox("msubsupSub").left, e, "subscript is after base"); + assert_less_than_equal(getBox("msubsupBase").right, getBox("msubsupSup").left, e, "superscript is after base"); + + assert_greater_than_equal(getBox("premsubBase").right, getBox("premsubSub").left, e, "subscript is before base"); + assert_greater_than_equal(getBox("premsupBase").right, getBox("premsupSup").left, e, "superscript is before base"); + assert_greater_than_equal(getBox("premsubsupBase").right, getBox("premsubsupSub").left, e, "subscript is before base"); + assert_greater_than_equal(getBox("premsubsupBase").right, getBox("premsubsupSup").left, e, "superscript is before base"); + + e = 3; + assert_approx_equals(getBox("msubBase").right, getBox("msubSub").left, e, "msub: space between base and subscript is small"); + assert_approx_equals(getBox("msubBase").right, getBox("msubSub").left, e, "msub: subscript is after base"); + assert_approx_equals(getBox("msupBase").right, getBox("msupSup").left, e, "msup: superscript is after base"); + assert_approx_equals(getBox("msubsupBase").right, getBox("msubsupSub").left, e, "msubsup: subscript is after base"); + assert_approx_equals(getBox("msubsupBase").right, getBox("msubsupSup").left, e, "msubsup: superscript is after base"); + + assert_approx_equals(getBox("premsubBase").left, getBox("premsubSub").right, e, "msub: space between base and subscript is small"); + assert_approx_equals(getBox("premsubBase").left, getBox("premsubSub").right, e, "msub: subscript is after base"); + assert_approx_equals(getBox("premsupBase").left, getBox("premsupSup").right, e, "msup: superscript is after base"); + assert_approx_equals(getBox("premsubsupBase").left, getBox("premsubsupSub").right, e, "msubsup: subscript is after base"); + assert_approx_equals(getBox("premsubsupBase").left, getBox("premsubsupSup").right, e, "msubsup: superscript is after base"); + }, "Respective horizontal positions"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + assert_approx_equals(getBox("msubBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline"); + assert_approx_equals(getBox("msupBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline"); + assert_approx_equals(getBox("msubsupBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline"); + assert_approx_equals(getBox("premsubBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline"); + assert_approx_equals(getBox("premsupBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline"); + assert_approx_equals(getBox("premsubsupBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline"); + }, "Alignment of the base on the baseline"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + assert_greater_than(getBox("msubSub").middle, getBox("msubBase").middle, "script is placed at the bottom of the base"); + assert_less_than(getBox("msupSup").middle, getBox("msupBase").middle, "script is placed at the top of the base"); + assert_greater_than(getBox("msubsupSub").middle, getBox("msubsupBase").middle, "script is placed at the bottom of the base"); + assert_less_than(getBox("msubsupSup").middle, getBox("msubsupBase").middle, "script is placed at the top of the base"); + + assert_greater_than(getBox("premsubSub").middle, getBox("premsubBase").middle, "script is placed at the bottom of the base"); + assert_less_than(getBox("premsupSup").middle, getBox("premsupBase").middle, "script is placed at the top of the base"); + assert_greater_than(getBox("premsubsupSub").middle, getBox("premsubsupBase").middle, "script is placed at the bottom of the base"); + assert_less_than(getBox("premsubsupSup").middle, getBox("premsubsupBase").middle, "script is placed at the top of the base"); + }, "Vertical position of scripts"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 3; + assert_approx_equals(getBox("msub").width, getBox("msubSub").right - getBox("msubBase").left, e, "width is determined by the left/right sides of base/script (+ some space after script)"); + assert_approx_equals(getBox("msup").width, getBox("msupSup").right - getBox("msupBase").left, e, "width is determined by the left/right sides of base/script (+ some space after script)"); + assert_approx_equals(getBox("msubsup").width, Math.max(getBox("msubsupSub").right, getBox("msubsupSup").right) - getBox("msubsupBase").left, e, "width is determined by the left/right sides of base/scripts (+ some space after script)"); + + assert_approx_equals(getBox("premsub").width, getBox("premsubBase").right - getBox("premsubSub").left, e, "width is determined by the right/left sides of base/script (+ some space after script)"); + assert_approx_equals(getBox("premsup").width, getBox("premsupBase").right - getBox("premsupSup").left, e, "width is determined by the right/left sides of base/script (+ some space after script)"); + assert_approx_equals(getBox("premsubsup").width, getBox("premsubsupBase").right - Math.min(getBox("premsubsupSub").left, getBox("premsubsupSup").left), e, "width is determined by the right/left sides of base/scripts (+ some space after script)"); + }, "Width of scripted elements"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 5; + assert_greater_than_equal(getBox("msub").height, getBox("msubBase").height, e, "height is at least the one of the base"); + assert_greater_than_equal(getBox("msup").height, getBox("msupBase").height, e, "height is at least the one of the base"); + assert_greater_than_equal(getBox("msubsup").height, getBox("msubsupBase").height, e, "height is at least the one of the base"); + assert_greater_than_equal(getBox("premsub").height, getBox("premsubBase").height, e, "height is at least the one of the base"); + assert_greater_than_equal(getBox("premsup").height, getBox("premsupBase").height, e, "height is at least the one of the base"); + assert_greater_than_equal(getBox("premsubsup").height, getBox("premsubsupBase").height, e, "height is at least the one of the base"); + + assert_approx_equals(getBox("msub").height, Math.max(getBox("msubSub").bottom, getBox("msubBase").bottom) - getBox("msubBase").top, e, "msub height is determined by the top/bottom sides of base/scripts"); + assert_approx_equals(getBox("msup").height, getBox("msupBase").bottom - Math.min(getBox("msupSup").top, getBox("msupBase").top), e, "msup height is determined by the top/bottom sides of base/scripts"); + assert_approx_equals(getBox("msubsup").height, Math.max(getBox("msubSub").bottom, getBox("msubBase").bottom) - Math.min(getBox("msupSup").top, getBox("msupBase").top), e, "msubsup height is determined by the top/bottom sides of base/scripts"); + assert_approx_equals(getBox("premsub").height, Math.max(getBox("premsubSub").bottom, getBox("premsubBase").bottom) - getBox("premsubBase").top, e, "msub height is determined by the top/bottom sides of base/scripts"); + assert_approx_equals(getBox("premsup").height, getBox("premsupBase").bottom - Math.min(getBox("premsupSup").top, getBox("premsupBase").top), e, "msup height is determined by the top/bottom sides of base/scripts"); + assert_approx_equals(getBox("premsubsup").height, Math.max(getBox("premsubSub").bottom, getBox("premsubBase").bottom) - Math.min(getBox("premsupSup").top, getBox("premsupBase").top), e, "msubsup height is determined by the top/bottom sides of base/scripts"); + }, "Height of scripted elements"); + + test(function() { + ["none", "mprescripts"].forEach(function(name) { + var elements = document.getElementsByTagName(name); + for (var i = 0; i < elements.length; i++) { + var box = elements[i].getBoundingClientRect(); + assert_equals(box.height * box.width, 0, "<" + name + "> " + i + " has zero is empty"); + } + }); + }, "Size of empty elements"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <mmultiscripts id="msub" style="background: green"> + <mspace id="msubBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubSub" width="10px" height="5px" depth="5px" style="background: black"/> + <none/> + </mmultiscripts> + <mmultiscripts id="msup" style="background: green"> + <mspace id="msupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <none/> + <mspace id="msupSup" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + <mmultiscripts id="msubsup" style="background: green"> + <mspace id="msubsupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubsupSub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsupSup" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + <mmultiscripts id="premsub" style="background: green"> + <mspace id="premsubBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts/> + <mspace id="premsubSub" width="10px" height="5px" depth="5px" style="background: black"/> + <none/> + </mmultiscripts> + <mmultiscripts id="premsup" style="background: green"> + <mspace id="premsupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts/> + <none/> + <mspace id="premsupSup" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + <mmultiscripts id="premsubsup" style="background: green"> + <mspace id="premsubsupBase" width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts/> + <mspace id="premsubsupSub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="premsubsupSup" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-3.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-3.html new file mode 100644 index 0000000000..28db9b70cc --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-3.html @@ -0,0 +1,192 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Subscripts and Superscripts metrics</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<meta name="assert" content="Basic metrics for the mmultiscript element with many scripts."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math, mspace { + font: 25px/1 Ahem; + } +</style> +<script> + /* This test does not use a font with a MATH table and does not verify layout + rules in a very strict way. */ + + function getBox(aId) { + var box = document.getElementById(aId).getBoundingClientRect(); + box.middle = (box.bottom + box.top) / 2; + return box; + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + for (var i = 0; i < 5; i++) + assert_approx_equals(getBox("multi" + i + "base").middle, getBox("baseline").bottom, e, "base " + i + "is placed on the baseline"); + }, "Alignment of the base on the baseline"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 5; + assert_approx_equals(getBox("multi0").width, 30, e, "width of multi0"); + assert_approx_equals(getBox("multi0").height, 30, e, "height of multi0"); + assert_approx_equals(getBox("multi1").width, 30, e, "width of multi1"); + assert_approx_equals(getBox("multi1").height, 30, e, "height of multi1"); + for (i = 2; i <= 4; i++) { + var scriptedBox = getBox("multi" + i); + var lastPostScript = getBox("multi" + i + "postsup" + (i - 1)); + var firstPreScript = getBox("multi" + i + "presub1"); + assert_approx_equals(scriptedBox.height, firstPreScript.bottom - lastPostScript.top, e, "height of multiscript" + i); + assert_approx_equals(scriptedBox.width, lastPostScript.right - firstPreScript.left, e, "width of multiscript" + i); + } + }, "Dimensions of the scripted elements"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 3; + for (var i = 2; i <= 4; i++) { + var base = getBox("multi" + i + "base"); + for (var j = 1; j < i; j++) { + var presup = getBox("multi" + i + "presup" + j); + var postsup = getBox("multi" + i + "postsup" + j); + var presub = getBox("multi" + i + "presub" + j); + var postsub = getBox("multi" + i + "postsub" + j); + assert_approx_equals(base.top, presup.middle, e, "multi" + i + " " + j + " presup script"); + assert_approx_equals(base.top, postsup.middle, e, "multi" + i + " " + j + " postsup script"); + assert_approx_equals(base.bottom, presub.middle, e, "multi" + i + " " + j + " presub script"); + assert_approx_equals(base.bottom, postsub.middle, e, "multi" + i + " " + j + " postsub script"); + } + } + }, "Vertical positions of scripts"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + for (var i = 2; i <= 4; i++) { + var base = getBox("multi" + i + "base"); + for (var j = 1; j < i; j++) { + var presup = getBox("multi" + i + "presup" + j); + var postsup = getBox("multi" + i + "postsup" + j); + var presub = getBox("multi" + i + "presub" + j); + var postsub = getBox("multi" + i + "postsub" + j); + assert_approx_equals(presup.right, presub.right, e, "multi" + i + "pre"); + assert_approx_equals(postsup.left, postsub.left, e, "multi" + i + "post"); + } + } + }, "Horizontal alignment of scripts"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + for (var i = 2; i <= 4; i++) { + var base = getBox("multi" + i + "base"); + var firstPostScript = getBox("multi" + i + "postsub1"); + var lastPreScript = getBox("multi" + i + "presup" + (i - 1)); + assert_less_than_equal(base.right, firstPostScript.left, 1, "postcripts are after base"); + assert_less_than_equal(lastPreScript.right, base.left, 1, "prescripts are before base"); + assert_approx_equals(base.right, firstPostScript.left, 5, "spacing after base is not too large"); + assert_approx_equals(lastPreScript.right, base.left, 5, "spacing before base is not too large"); + for (var j = 1; j < i - 1; j++) { + var post = getBox("multi" + i + "postsub" + j); + var postNext = getBox("multi" + i + "postsub" + (j + 1)); + var pre = getBox("multi" + i + "presup" + j); + var preNext = getBox("multi" + i + "presup" + (j + 1)); + assert_less_than_equal(post.right, postNext.left, 1, "multi" + i + "order post" + j + " is before its successor"); + assert_less_than_equal(pre.right, preNext.left, 1, "multi" + i + "order pre" + j + " is before its successor"); + assert_approx_equals(post.right, postNext.left, 5, "multi" + i + "space after post" + j + " is not too large"); + assert_approx_equals(pre.right, preNext.left, 5, "multi" + i + "space after pre" + j + " is not too large"); + } + } + }, "Horizontal positions of scripts"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <mmultiscripts id="multi0" style="background: green"> + <mspace id="multi0base" width="30px" height="15px" depth="15px" style="background: black"/> + </mmultiscripts> + <mmultiscripts id="multi1" style="background: green"> + <mspace id="multi1base" width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts/> + </mmultiscripts> + <mmultiscripts id="multi2" style="background: green"> + <mspace id="multi2base" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multi2postsub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi2postsup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mprescripts/> + <mspace id="multi2presub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi2presup1" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + <mmultiscripts id="multi3" style="background: green"> + <mspace id="multi3base" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multi3postsub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3postsup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3postsub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3postsup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mprescripts/> + <mspace id="multi3presub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3presup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3presub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi3presup2" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + <mmultiscripts id="multi4" style="background: green"> + <mspace id="multi4base" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multi4postsub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsub3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4postsup3" width="10px" height="5px" depth="5px" style="background: black"/> + <mprescripts/> + <mspace id="multi4presub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presub3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi4presup3" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + <mmultiscripts id="multi5" style="background: green"> + <mspace id="multi5base" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multi5postsub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsub3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsup3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsub4" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5postsup4" width="10px" height="5px" depth="5px" style="background: black"/> + <mprescripts/> + <mspace id="multi5presub1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presup1" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presub2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presup2" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presub3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presup3" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presub4" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi5presup4" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-4.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-4.html new file mode 100644 index 0000000000..cdf6cbe20e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-4.html @@ -0,0 +1,129 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Subscripts and Superscripts metrics</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<meta name="assert" content="Verify metrics of scripted elements for bases of different heights."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<style> + math, mspace { + font-size: 10px; + } +</style> +<script> + /* This test does not use any specific fonts and so the exact rules are not + specified precisely. We assume reasonable values for script shifts and + spacing. */ + + function getBox(aId) { + var box = document.getElementById(aId).getBoundingClientRect(); + box.middle = (box.bottom + box.top) / 2; + return box; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + var sizeArray = [50, 75, 100]; + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + sizeArray.forEach(function(size) { + assert_approx_equals(getBox("msub" + size + "base").middle, getBox("baseline").bottom, e, "msub base " + size + "is placed on the baseline"); + assert_approx_equals(getBox("msup" + size + "base").middle, getBox("baseline").bottom, e, "msup base " + size + "is placed on the baseline"); + assert_approx_equals(getBox("msubsup" + size + "base").middle, getBox("baseline").bottom, e, "msubsup base " + size + "is placed on the baseline"); + assert_approx_equals(getBox("multi" + size + "base").middle, getBox("baseline").bottom, e, "mmultiscripts base " + size + "is placed on the baseline"); + }); + }, "Alignment on the baseline for bases of different heights"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 5; + sizeArray.forEach(function(size) { + assert_approx_equals(getBox("msub" + size + "sub").middle, getBox("msub" + size + "base").bottom, e, "msub script " + size + "is placed at the top of of the base"); + }); + }, "Vertical position of the scripts for bases of different heights"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <msub id="msub50"> + <mspace id="msub50base" width="30px" height="50px" depth="50px" style="background: black"/> + <mspace id="msub50sub" width="10px" height="5px" depth="5px" style="background: black"/> + </msub> + <msup id="msup50"> + <mspace id="msup50base" width="30px" height="50px" depth="50px" style="background: black"/> + <mspace id="msup50sup" width="10px" height="5px" depth="5px" style="background: black"/> + </msup> + <msubsup id="msubsup50"> + <mspace id="msubsup50base" width="30px" height="50px" depth="50px" style="background: black"/> + <mspace id="msubsup50sub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsup50sup" width="10px" height="5px" depth="5px" style="background: black"/> + </msubsup> + <mmultiscripts id="multi50"> + <mspace id="multi50base" width="30px" height="50px" depth="50px" style="background: black"/> + <mspace id="multi50postsub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi50postsup" width="10px" height="5px" depth="5px" style="background: black"/> + <mprescripts/> + <mspace id="multi50presub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi50presup" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + <msub id="msub75"> + <mspace id="msub75base" width="30px" height="75px" depth="75px" style="background: black"/> + <mspace id="msub75sub" width="10px" height="5px" depth="5px" style="background: black"/> + </msub> + <msup id="msup75"> + <mspace id="msup75base" width="30px" height="75px" depth="75px" style="background: black"/> + <mspace id="msup75sup" width="10px" height="5px" depth="5px" style="background: black"/> + </msup> + <msubsup id="msubsup75"> + <mspace id="msubsup75base" width="30px" height="75px" depth="75px" style="background: black"/> + <mspace id="msubsup75sub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsup75sup" width="10px" height="5px" depth="5px" style="background: black"/> + </msubsup> + <mmultiscripts id="multi75"> + <mspace id="multi75base" width="30px" height="75px" depth="75px" style="background: black"/> + <mspace id="multi75postsub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi75postsup" width="10px" height="5px" depth="5px" style="background: black"/> + <mprescripts/> + <mspace id="multi75presub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi75presub" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + <msub id="msub100"> + <mspace id="msub100base" width="30px" height="100px" depth="100px" style="background: black"/> + <mspace id="msub100sub" width="10px" height="5px" depth="5px" style="background: black"/> + </msub> + <msup id="msup100"> + <mspace id="msup100base" width="30px" height="100px" depth="100px" style="background: black"/> + <mspace id="msup100sup" width="10px" height="5px" depth="5px" style="background: black"/> + </msup> + <msubsup id="msubsup100"> + <mspace id="msubsup100base" width="30px" height="100px" depth="100px" style="background: black"/> + <mspace id="msubsup100sub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="msubsup100sup" width="10px" height="5px" depth="5px" style="background: black"/> + </msubsup> + <mmultiscripts id="multi100"> + <mspace id="multi100base" width="30px" height="100px" depth="100px" style="background: black"/> + <mspace id="multi100postsub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi100postsup" width="10px" height="5px" depth="5px" style="background: black"/> + <mprescripts/> + <mspace id="multi100presub" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="multi100presup" width="10px" height="5px" depth="5px" style="background: black"/> + </mmultiscripts> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-5.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-5.html new file mode 100644 index 0000000000..1743c2e499 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-5.html @@ -0,0 +1,97 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Subscripts and Superscripts metrics</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<meta name="assert" content="Verify metrics of scripted elements with tall scripts."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<style> + math, mspace { + font-size: 10px; + } +</style> +<script> + /* This test does not use any specific fonts and so the exact rules are not + specified precisely. We assume reasonable values for script shifts and + spacing. */ + + function getBox(aId) { + var box = document.getElementById(aId).getBoundingClientRect(); + box.middle = (box.bottom + box.top) / 2; + return box; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + var sizeArray = [50, 75, 100]; + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + assert_approx_equals(getBox("msubbase").middle, getBox("baseline").bottom, e, "msub base is placed on the baseline"); + assert_approx_equals(getBox("msupbase").middle, getBox("baseline").bottom, e, "msup base is placed on the baseline"); + assert_approx_equals(getBox("msubsupbase").middle, getBox("baseline").bottom, e, "msubsup base is placed on the baseline"); + assert_approx_equals(getBox("multibase").middle, getBox("baseline").bottom, e, "mmultiscripts baseis placed on the baseline"); + }, "Alignment on the baseline with different and large script heights"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + assert_greater_than(getBox("msubsub").top, getBox("msubbase").top, "msub: subscript is below the top of the base"); + assert_less_than(getBox("msupsup").bottom, getBox("msupbase").bottom, "msup: supscript is above the bottom of the base"); + assert_greater_than(getBox("msubsupsub").top, getBox("msubsupbase").top, "msubsup: subscript is below the top of the base"); + assert_less_than(getBox("msubsupsup").bottom, getBox("msubsupbase").bottom, "msubsup: supscript is above the bottom of the base"); + assert_greater_than(getBox("multipostsub").top, getBox("multibase").top, "mmultiscripts: postsubscript is below the top of the base"); + assert_less_than(getBox("multipostsup").bottom, getBox("multibase").bottom, "mmultiscripts: postsupscript is above the bottom of the base"); + assert_greater_than(getBox("multipresub").top, getBox("multibase").top, "mmultiscripts: presubscript is below the top of the base"); + assert_less_than(getBox("multipresup").bottom, getBox("multibase").bottom, "mmultiscripts: presupscript is above the bottom of the base"); + }, "Tall subscripts/superscripts are not placed too high/low"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + assert_greater_than(getBox("msubsupsub").top, getBox("msubsupsup").bottom, "msubsup: subscript is below the superscript"); + assert_greater_than(getBox("multipresub").top, getBox("multipresup").bottom, "mmultiscripts: presubscript is below the presuperscript"); + assert_greater_than(getBox("multipostsub").top, getBox("multipostsup").bottom, "mmultiscripts: postsubscript is below the postsuperscript"); + }, "No collisions for tall subscripts and superscripts"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <msub id="msub"> + <mspace id="msubbase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubsub" width="10px" height="50px" depth="50px" style="background: black"/> + </msub> + <msup id="msup"> + <mspace id="msupbase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msupsup" width="10px" height="75px" depth="75px" style="background: black"/> + </msup> + <msubsup id="msubsup"> + <mspace id="msubsupbase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="msubsupsub" width="10px" height="50px" depth="50px" style="background: black"/> + <mspace id="msubsupsup" width="10px" height="75px" depth="75px" style="background: black"/> + </msubsup> + <mmultiscripts id="multi"> + <mspace id="multibase" width="30px" height="15px" depth="15px" style="background: black"/> + <mspace id="multipostsub" width="10px" height="50px" depth="50px" style="background: black"/> + <mspace id="multipostsup" width="10px" height="75px" depth="75px" style="background: black"/> + <mprescripts/> + <mspace id="multipresub" width="10px" height="50px" depth="50px" style="background: black"/> + <mspace id="multipresup" width="10px" height="75px" depth="75px" style="background: black"/> + </mmultiscripts> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-6.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-6.html new file mode 100644 index 0000000000..9666c80f9f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-6.html @@ -0,0 +1,120 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>mprescripts</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<meta name="assert" content="Position and size of mprescripts in mmultiscript element."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math, mspace { + font: 25px/1 Ahem; + } +</style> +<script> + /* This test does not use a font with a MATH table and does not verify layout + rules in a very strict way. */ + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + Array.from(document.getElementsByTagName("mprescripts")). + forEach(prescript => { + let prescript_box = prescript.getBoundingClientRect(); + let mmultiscripts = prescript.parentNode; + let name = mmultiscripts.getAttribute("data-name"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var e = 1; + let base_box = mmultiscripts.firstElementChild.getBoundingClientRect(); + assert_approx_equals(prescript_box.left, base_box.left, e, `${name}, left`); + assert_approx_equals((prescript_box.top + prescript_box.bottom) / 2, (base_box.top + base_box.bottom) / 2, e, `${name}, top`); + + if (name == "prescripts with padding/border/margin") { + assert_approx_equals(prescript_box.width, 2*(15 + 25), e, `${name}, width`); + assert_approx_equals(prescript_box.height, 2*(10 + 20), e, `${name}, height`); + } else { + assert_approx_equals(prescript_box.width, 0, e, `${name}, width`); + assert_approx_equals(prescript_box.height, 0, e, `${name}, height`); + } + }, `mprescripts coordinates and sizes (${name})`); + }); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mmultiscripts data-name="2 postscripts"> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-name="2 prescripts"> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-name="2 prescripts, 4 postscripts"> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-name="4 prescripts, 2 postscripts"> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-name="prescripts with padding/border/margin"> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mprescripts style="background: blue; + padding-top: 10px; border-top: 20px solid green; + padding-bottom: 10px; border-bottom: 20px solid green; + padding-left: 15px; border-left: 25px solid green; + padding-right: 15px; border-right: 25px solid green; + margin-top: 50px;"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + <mspace width="30px" height="15px" depth="15px" style="background: black"/> + </mmultiscripts> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-legacy-scriptshift-attributes-001.tentative-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-legacy-scriptshift-attributes-001.tentative-ref.html new file mode 100644 index 0000000000..c1bf2e4695 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-legacy-scriptshift-attributes-001.tentative-ref.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>msub/msup/msubsup/mmultiscripts subscriptshift and superscriptshift attributes (reference)</title> + </head> + <body> + <p>Test passes if the green squares are not about 300px away from the blue squares.</p> + <p> + <math> + <mmultiscripts> + <mspace width="30px" height="30px" style="background: blue;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + <mprescripts/> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + </mmultiscripts> + <msub> + <mspace width="30px" height="30px" style="background: blue;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + </msub> + <msup> + <mspace width="30px" height="30px" style="background: blue;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + </msup> + <msubsup> + <mspace width="30px" height="30px" style="background: blue;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + </msubsup> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-legacy-scriptshift-attributes-001.tentative.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-legacy-scriptshift-attributes-001.tentative.html new file mode 100644 index 0000000000..2f29db401d --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-legacy-scriptshift-attributes-001.tentative.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>msub/msup/msubsup/mmultiscripts subscriptshift and superscriptshift attributes</title> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.msub"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.msup"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.msunsup"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mmultiscripts"> + <link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> + <link rel="help" href="https://w3c.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts"> + <link rel="match" href="subsup-legacy-scriptshift-attributes-001.tentative-ref.html"> + </head> + <body> + <p>Test passes if the green squares are not about 300px away from the blue squares.</p> + <p> + <math> + <mmultiscripts subscriptshift="300px" superscriptshift="300px"> + <mspace width="30px" height="30px" style="background: blue;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + <mprescripts/> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + </mmultiscripts> + <msub subscriptshift="300px"> + <mspace width="30px" height="30px" style="background: blue;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + </msub> + <msup superscriptshift="300px"> + <mspace width="30px" height="30px" style="background: blue;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + </msup> + <msubsup subscriptshift="300px" superscriptshift="300px"> + <mspace width="30px" height="30px" style="background: blue;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + <mspace width="10px" height="10px" style="background: lightgreen;"></mspace> + </msubsup> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_msubsup"); + MathMLFeatureDetection.ensure_for_match_reftest("has_mmultiscripts"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-parameters-1.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-parameters-1.html new file mode 100644 index 0000000000..3f49b1d53b --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-parameters-1.html @@ -0,0 +1,354 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Subscripts and Superscripts parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<meta name="assert" content="Elements msub, msup, subsup and msubsup correctly use the subscript and superscript parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace { + font-size: 10px; + } + @font-face { + font-family: spaceafterscript3000; + src: url("/fonts/math/scripts-spaceafterscript3000.woff"); + } + @font-face { + font-family: superscriptshiftup7000; + src: url("/fonts/math/scripts-superscriptshiftup7000.woff"); + } + @font-face { + font-family: superscriptshiftupcramped5000; + src: url("/fonts/math/scripts-superscriptshiftupcramped5000.woff"); + } + @font-face { + font-family: subscriptshiftdown6000; + src: url("/fonts/math/scripts-subscriptshiftdown6000.woff"); + } + @font-face { + font-family: subsuperscriptgapmin11000; + src: url("/fonts/math/scripts-subsuperscriptgapmin11000.woff"); + } + @font-face { + font-family: subsuperscriptgapmin11000superscriptbottommaxwithsubscript3000; + src: url("/fonts/math/scripts-subsuperscriptgapmin11000-superscriptbottommaxwithsubscript3000.woff"); + } + @font-face { + font-family: subscripttopmax4000; + src: url("/fonts/math/scripts-subscripttopmax4000.woff"); + } + @font-face { + font-family: superscriptbottommin8000; + src: url("/fonts/math/scripts-superscriptbottommin8000.woff"); + } + @font-face { + font-family: subscriptbaselinedropmin9000; + src: url("/fonts/math/scripts-subscriptbaselinedropmin9000.woff"); + } + @font-face { + font-family: superscriptbaselinedropmax10000; + src: url("/fonts/math/scripts-superscriptbaselinedropmax10000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("ref001").left - getBox("sub001").right, v, epsilon, "msub: Space after subscript"); + assert_approx_equals(getBox("ref002").left - getBox("sup002").right, v, epsilon, "msup: Space after superscript"); + assert_approx_equals(getBox("ref003").left - getBox("sup003").right, v, epsilon, "msubsup: Space after superscript"); + assert_approx_equals(getBox("sup0042").left - getBox("sup0041").right, v, epsilon, "mmultiscripts: Space after first superscript"); + assert_approx_equals(getBox("sup0043").left - getBox("sup0042").right, v, epsilon, "mmultiscripts: Space after second superscript"); + assert_approx_equals(getBox("ref004").left - getBox("sup0043").right, v, epsilon, "mmultiscripts: Space after last superscript"); + }, "SpaceAfterScript"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 7000 * emToPx; + assert_approx_equals(getBox("ref101").bottom - getBox("sup102").bottom, v, epsilon, "msup: Superscript shift"); + assert_approx_equals(getBox("ref101").bottom - getBox("sup103").bottom, v, epsilon, "msubsup: Superscript shift"); + assert_approx_equals(getBox("ref101").bottom - getBox("sup1041").bottom, v, epsilon, "mmultiscripts: First superscript shift"); + assert_approx_equals(getBox("ref101").bottom - getBox("sup1042").bottom, v, epsilon, "mmultiscripts: Second superscript shift"); + assert_approx_equals(getBox("ref101").bottom - getBox("sup1043").bottom, v, epsilon, "mmultiscripts: Last superscript shift"); + }, "SuperscriptShiftUp"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("ref201").bottom - getBox("sup202").bottom, v, epsilon, "msup: Superscript shift"); + assert_approx_equals(getBox("ref201").bottom - getBox("sup203").bottom, v, epsilon, "msubsup: Superscript shift"); + assert_approx_equals(getBox("ref201").bottom - getBox("sup2041").bottom, v, epsilon, "mmultiscripts: First superscript shift"); + assert_approx_equals(getBox("ref201").bottom - getBox("sup2042").bottom, v, epsilon, "mmultiscripts: Second superscript shift"); + assert_approx_equals(getBox("ref201").bottom - getBox("sup2043").bottom, v, epsilon, "mmultiscripts: Last superscript shift"); + }, "SuperscriptShiftUpCramped"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 6000 * emToPx; + assert_approx_equals(getBox("sub301").bottom - getBox("ref300").bottom, v, epsilon, "msup: Subscript shift"); + assert_approx_equals(getBox("sub302").bottom - getBox("ref300").bottom, v, epsilon, "msubsup: Subscript shift"); + assert_approx_equals(getBox("sub303").bottom - getBox("ref300").bottom, v, epsilon, "mmultiscripts: First subscript shift"); + assert_approx_equals(getBox("sub304").bottom - getBox("ref300").bottom, v, epsilon, "mmultiscripts: Second subscript shift"); + }, "SubscriptShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 11000 * emToPx; + assert_approx_equals(getBox("sub4011").top - getBox("sup4012").bottom, v, epsilon, "msubsup: SubSuperscript gap"); + assert_approx_equals(getBox("sub4021").top - getBox("sup4022").bottom, v, epsilon, "mmultiscripts: SubSuperscript gap"); + }, "SubSuperscriptGapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 11000 * emToPx; + var v2 = 3000 * emToPx; + assert_approx_equals(getBox("sub501").top - getBox("sup501").bottom, v1, epsilon, "msubsup: SubSuperscript gap"); + assert_approx_equals(getBox("ref500").bottom - getBox("sup501").bottom, v2, epsilon, "msubsup: Superscript bottom"); + assert_approx_equals(getBox("sub502").top - getBox("sup502").bottom, v1, epsilon, "mmultiscripts: SubSuperscript gap"); + assert_approx_equals(getBox("ref500").bottom - getBox("sup502").bottom, v2, epsilon, "mmultiscripts: Superscript bottom"); + }, "SuperscriptBottomMaxWithSubscript"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 4000 * emToPx; + assert_approx_equals(getBox("ref600").bottom - getBox("sub601").top, v, epsilon, "msub: Subscript top"); + }, "SubscriptTopMax"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 8000 * emToPx; + assert_approx_equals(getBox("ref700").bottom - getBox("sub701").bottom, v, epsilon, "msub: Superscript bottom"); + }, "SuperscriptBottomMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 9000 * emToPx; + assert_approx_equals(getBox("sub801").bottom - getBox("base801").bottom, v, epsilon, "msub: Superscript drop"); + }, "SubscriptBaselineDrop"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 10000 * emToPx; + assert_approx_equals(getBox("sup901").bottom - getBox("base901").top, v, epsilon, "msup: Superscript drop"); + }, "SuperscriptBaselineDrop"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: spaceafterscript3000;"> + <msub> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub001" height="1em" width="1em" style="background: red"/> + </msub> + <mspace id="ref001" height="1em" width="1em" style="background: green"/> + </math> + <math style="font-family: spaceafterscript3000;"> + <msup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sup002" height="1em" width="1em" style="background: red"/> + </msup> + <mspace id="ref002" height="1em" width="1em" style="background: green"/> + </math> + <math style="font-family: spaceafterscript3000;"> + <msubsup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace/> + <mspace id="sup003" height="1em" width="1em" style="background: red"/> + </msubsup> + <mspace id="ref003" height="1em" width="1em" style="background: green"/> + </math> + <math style="font-family: spaceafterscript3000;"> + <mmultiscripts> + <mspace height="2em" width="2em" style="background: blue"/> + <none/> + <mspace id="sup0041" height="1em" width="1em" style="background: red"/> + <none/> + <mspace id="sup0042" height="1em" width="1em" style="background: red"/> + <none/> + <mspace id="sup0043" height="1em" width="1em" style="background: red"/> + </mmultiscripts> + <mspace id="ref004" height="1em" width="1em" style="background: green"/> + </math> + </p> + <hr/> + <p> + <math style="font-family: superscriptshiftup7000;"> + <mspace id="ref101" height="1em" width="1em" style="background: green"/> + <msup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sup102" height="1em" width="1em" style="background: red"/> + </msup> + <msubsup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace height="1em" width="1em" style="background: red"/> + <mspace id="sup103" height="1em" width="1em" style="background: red"/> + </msubsup> + <mmultiscripts> + <mspace height="2em" width="2em" style="background: blue"/> + <none/> + <mspace id="sup1041" height="1em" width="1em" style="background: red"/> + <none/> + <mspace id="sup1042" height="1em" width="1em" style="background: red"/> + <none/> + <mspace id="sup1043" height="1em" width="1em" style="background: red"/> + </mmultiscripts> + </math> + </p> + <hr/> + <p> + <math style="font-family: superscriptshiftupcramped5000;"> + <msqrt> + <mspace id="ref201" height="1em" width="1em" style="background: green"/> + <msup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sup202" height="1em" width="1em" style="background: red"/> + </msup> + <msubsup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace height="1em" width="1em" style="background: blue"/> + <mspace id="sup203" height="1em" width="1em" style="background: red"/> + </msubsup> + <mmultiscripts> + <mspace height="2em" width="2em" style="background: blue"/> + <none/> + <mspace id="sup2041" height="1em" width="1em" style="background: red"/> + <none/> + <mspace id="sup2042" height="1em" width="1em" style="background: red"/> + <none/> + <mspace id="sup2043" height="1em" width="1em" style="background: red"/> + </mmultiscripts> + </msqrt> + </math> + </p> + <hr/> + <p> + <math style="font-family: subscriptshiftdown6000;"> + <mspace id="ref300" height="1em" width="1em" style="background: green"/> + <msub> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub301" height="1em" width="1em" style="background: red"/> + </msub> + <msubsup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub302" height="1em" width="1em" style="background: red"/> + <mspace height="1em" width="1em" style="background: blue"/> + </msubsup> + <mmultiscripts> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub303" height="1em" width="1em" style="background: red"/> + <none/> + <mspace id="sub304" height="1em" width="1em" style="background: red"/> + <none/> + </mmultiscripts> + </math> + </p> + <hr/> + <p> + <math style="font-family: subsuperscriptgapmin11000;"> + <msubsup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub4011" height="1em" width="1em" style="background: red"/> + <mspace id="sup4012" height="1em" width="1em" style="background: red"/> + </msubsup> + <mmultiscripts> + <mspace height="2em" width="2em" style="background: blue"/> + <none/> + <none/> + <mspace id="sub4021" height="1em" width="1em" style="background: red"/> + <mspace id="sup4022" height="1em" width="1em" style="background: red"/> + </mmultiscripts> + </math> + </p> + <hr/> + <p> + <math style="font-family: subsuperscriptgapmin11000superscriptbottommaxwithsubscript3000;"> + <mspace id="ref500" height="1em" width="1em" style="background: green"/> + <msubsup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub501" height="1em" width="1em" style="background: red"/> + <mspace id="sup501" height="1em" width="1em" style="background: red"/> + </msubsup> + <mmultiscripts> + <mspace height="2em" width="2em" style="background: blue"/> + <none/> + <none/> + <mspace id="sub502" height="1em" width="1em" style="background: red"/> + <mspace id="sup502" height="1em" width="1em" style="background: red"/> + </mmultiscripts> + </math> + </p> + <hr/> + <p> + <math style="font-family: subscripttopmax4000;"> + <mspace id="ref600" height="1em" + width="1em" style="background: green"/> + <msub> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub601" height="10em" + width="1em" style="background: red"/> + </msub> + </math> + </p> + <hr/> + <p> + <math style="font-family: superscriptbottommin8000;"> + <mspace id="ref700" height="1em" + width="1em" style="background: green"/> + <msup> + <mspace height="2em" width="2em" style="background: blue"/> + <mspace id="sub701" depth="1em" + width="1em" style="background: red"/> + </msup> + </math> + </p> + <hr/> + <p> + <math style="font-family: subscriptbaselinedropmin9000;"> + <msub> + <mspace id="base801" height="2em" width="2em" style="background: blue"/> + <mspace id="sub801" height="1em" + width="1em" style="background: red"/> + </msub> + </math> + </p> + <hr/> + <p> + <math style="font-family: superscriptbaselinedropmax10000;"> + <msup> + <mspace id="base901" height="15em" width="2em" style="background: blue"/> + <mspace id="sup901" height="1em" + width="1em" style="background: red"/> + </msup> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-parameters-2.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-parameters-2.html new file mode 100644 index 0000000000..205697f4e4 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/subsup-parameters-2.html @@ -0,0 +1,181 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Subscripts and Superscripts parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<meta name="assert" content="Elements msub, msup, subsup and msubsup correctly use the italic correction from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace { + font-size: 10px; + } + @font-face { + font-family: largeop-displayoperatorminheight5000; + src: url("/fonts/math/largeop-displayoperatorminheight5000.woff"); + } + @font-face { + font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000; + src: url("/fonts/math/largeop-displayoperatorminheight2000-2AFF-italiccorrection3000.woff"); + } + @font-face { + font-family: largeop-displayoperatorminheight7000-2AFF-italiccorrection5000; + src: url("/fonts/math/largeop-displayoperatorminheight7000-2AFF-italiccorrection5000.woff"); + } +</style> +<script> + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + /* + These two tests verify that: + - In msub, the script is at the right of the base minus the italic correction. + - In msup, the script is just at the right of the base. + - In msubsup, the scripts are shifted by the italic correction. + - In mmultiscripts, postscript pairs are shifted by the italic correction. + - In mmultiscripts, prescript pairs are vertically aligned. + */ + var epsilon = 1; + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 0; + assert_approx_equals(getBox("base001").right - getBox("sub001").left, v, epsilon, "msub"); + assert_approx_equals(getBox("sup002").left, getBox("base002").right, epsilon, "msup"); + assert_approx_equals(getBox("sup003").left - getBox("sub003").left, v, epsilon, "msubsup"); + assert_approx_equals(getBox("sup004").left - getBox("sub004").left, v, epsilon, "mmultiscripts postscripts"); + assert_approx_equals(getBox("sup005").left - getBox("sub005").left, 0, epsilon, "mmultiscripts prescripts"); + }, "Null Italic Correction"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("base011").right - getBox("sub011").left, v, epsilon, "msub"); + assert_approx_equals(getBox("sup012").left, getBox("base012").right, epsilon, "msup"); + assert_approx_equals(getBox("sup013").left - getBox("sub013").left, v, epsilon, "msubsup"); + assert_approx_equals(getBox("sup014").left - getBox("sub014").left, v, epsilon, "mmultiscripts postscripts"); + assert_approx_equals(getBox("sup015").left - getBox("sub015").left, 0, epsilon, "mmultiscripts prescripts"); + }, "NonNull Italic Correction (MathGlyphVariantRecord)"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("base021").right - getBox("sub021").left, v, epsilon, "msub"); + assert_approx_equals(getBox("sup022").left, getBox("base022").right, epsilon, "msup"); + assert_approx_equals(getBox("sup023").left - getBox("sub023").left, v, epsilon, "msubsup"); + assert_approx_equals(getBox("sup024").left - getBox("sub024").left, v, epsilon, "mmultiscripts postscripts"); + assert_approx_equals(getBox("sup025").left - getBox("sub025").left, 0, epsilon, "mmultiscripts prescripts"); + }, "NonNull Italic Correction (GlyphAssembly)"); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <h2>Null Italic Correction</h2> + <p> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight5000;"> + <msub> + <mo id="base001" lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub001" height="1em" width="1em" style="background: blue"/> + </msub> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight5000;"> + <msup> + <mo id="base002" lspace="0px" rspace="0px">⫿</mo> + <mspace id="sup002" height="1em" width="1em" style="background: blue"/> + </msup> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight5000;"> + <msubsup> + <mo lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub003" height="1em" width="1em" style="background: blue"/> + <mspace id="sup003" height="1em" width="1em" style="background: green"/> + </msubsup> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight5000;"> + <mmultiscripts> + <mo lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub004" height="1em" width="1em" style="background: blue"/> + <mspace id="sup004" height="1em" width="1em" style="background: green"/> + <mprescripts/> + <mspace id="sub005" height="1em" width="1em" style="background: magenta"/> + <mspace id="sup005" height="1em" width="1em" style="background: cyan"/> + </mmultiscripts> + </math> + </p> + <h2>NonNull Italic Correction (MathGlyphVariantRecord)</h2> + <p> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000;"> + <msub> + <mo id="base011" lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub011" height="1em" width="1em" style="background: blue"/> + </msub> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000;"> + <msup> + <mo id="base012" lspace="0px" rspace="0px">⫿</mo> + <mspace id="sup012" height="1em" width="1em" style="background: blue"/> + </msup> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000;"> + <msubsup> + <mo lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub013" height="1em" width="1em" style="background: blue"/> + <mspace id="sup013" height="1em" width="1em" style="background: green"/> + </msubsup> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight2000-2AFF-italiccorrection3000;"> + <mmultiscripts> + <mo lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub014" height="1em" width="1em" style="background: blue"/> + <mspace id="sup014" height="1em" width="1em" style="background: green"/> + <mprescripts/> + <mspace id="sub015" height="1em" width="1em" style="background: magenta"/> + <mspace id="sup015" height="1em" width="1em" style="background: cyan"/> + </mmultiscripts> + </math> + </p> + <h2>NonNull Italic Correction (GlyphAssembly)</h2> + <p> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight7000-2AFF-italiccorrection5000;"> + <msub> + <mo id="base021" lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub021" height="1em" width="1em" style="background: blue"/> + </msub> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight7000-2AFF-italiccorrection5000;"> + <msup> + <mo id="base022" lspace="0px" rspace="0px">⫿</mo> + <mspace id="sup022" height="1em" width="1em" style="background: blue"/> + </msup> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight7000-2AFF-italiccorrection5000;"> + <msubsup> + <mo lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub023" height="1em" width="1em" style="background: blue"/> + <mspace id="sup023" height="1em" width="1em" style="background: green"/> + </msubsup> + </math> + <math displaystyle="true" style="font-family: largeop-displayoperatorminheight7000-2AFF-italiccorrection5000;"> + <mmultiscripts> + <mo lspace="0px" rspace="0px">⫿</mo> + <mspace id="sub024" height="1em" width="1em" style="background: blue"/> + <mspace id="sup024" height="1em" width="1em" style="background: green"/> + <mprescripts/> + <mspace id="sub025" height="1em" width="1em" style="background: magenta"/> + <mspace id="sup025" height="1em" width="1em" style="background: cyan"/> + </mmultiscripts> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-1.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-1.html new file mode 100644 index 0000000000..ae4a945404 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-1.html @@ -0,0 +1,175 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Underscripts and Overscripts parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Elements munder, mover, munderover correctly ."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math, mspace, mo { + font-family: Ahem; + font-size: 10px; + } +</style> +<script> + /* This test does not use any specific fonts and so the exact rules are not + specified precisely. We assume reasonable values for script shifts and + spacing. */ + + function getBox(aId) { + var box = document.getElementById(aId).getBoundingClientRect(); + box.middle = (box.bottom + box.top) / 2; + box.center = (box.left + box.right) / 2; + return box; + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + for (var i = 0; i <= 3; i++) { + assert_approx_equals(getBox("under" + i + "base").middle, getBox("baseline").bottom, e, "munder " + i + ": base is placed on the baseline"); + assert_approx_equals(getBox("over" + i + "base").middle, getBox("baseline").bottom, e, "mover " + i + ": base is placed on the baseline"); + } + for (var i = 0; i <= 5; i++) { + assert_approx_equals(getBox("underover" + i + "base").middle, getBox("baseline").bottom, e, "munderover " + i + ": base is placed on the baseline"); + } + }, "Alignment of the base on the baseline"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + for (var i = 0; i <= 3; i++) { + assert_approx_equals(getBox("under" + i + "under").center, getBox("under" + i + "base").center, e, "munder " + i + ": base and script are horizontally centered"); + assert_approx_equals(getBox("over" + i + "over").center, getBox("over" + i + "base").center, e, "mover " + i + ": base and script are horizontally centered"); + } + for (var i = 0; i <= 5; i++) { + assert_approx_equals(getBox("underover" + i + "under").center, getBox("underover" + i + "base").center, e, "munderover " + i + ": base and underscript are horizontally centered"); + assert_approx_equals(getBox("underover" + i + "over").center, getBox("underover" + i + "base").center, e, "munderover " + i + ": base and overscript are horizontally centered"); + } + }, "Horizontal alignments of base and scripts"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + for (var i = 0; i <= 3; i++) { + assert_greater_than_equal(getBox("under" + i + "under").top, getBox("under" + i + "base").bottom, "munder " + i + ": script is under base"); + assert_less_than_equal(getBox("over" + i + "over").bottom, getBox("over" + i + "base").top, "mover " + i + ": script is over base"); + } + for (var i = 0; i <= 5; i++) { + assert_greater_than_equal(getBox("underover" + i + "under").top, getBox("underover" + i + "base").bottom, "munderover " + i + ": underscript is under base"); + assert_less_than_equal(getBox("underover" + i + "over").bottom, getBox("underover" + i + "base").top, "munderover " + i + ": overscript is over base"); + } + }, "Relative vertical positions of base and scripts"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 1; + for (var i = 0; i <= 3; i++) { + assert_approx_equals(getBox("under" + i).width, Math.max(getBox("under" + i + "base").width, getBox("under" + i + "under").width), e, "munder " + i + ": width is determined by the maximum of width of base and script"); + assert_approx_equals(getBox("over" + i).width, Math.max(getBox("over" + i + "base").width, getBox("over" + i + "over").width), e, "mover " + i + ": width is determined by the maximum of width of base and script"); + } + for (var i = 0; i <= 5; i++) { + assert_approx_equals(getBox("underover" + i).width, Math.max(getBox("underover" + i + "base").width, getBox("underover" + i + "under").width, getBox("underover" + i + "over").width), e, "munderover " + i + ": width is determined by the maximum of width of base and scripts"); + } + }, "Width of scripted elements"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var e = 4; + for (var i = 0; i <= 3; i++) { + assert_approx_equals(getBox("under" + i).height, getBox("under" + i + "base").height + getBox("under" + i + "under").height, e, "munder " + i + ": height is determined by the sum of heights of base and script plus some spacing."); + assert_approx_equals(getBox("over" + i).height, getBox("over" + i + "base").height + getBox("over" + i + "over").height, e, "mover " + i + ": height is determined by the sum of heights of base and script plus some spacing."); + } + for (var i = 0; i <= 5; i++) { + assert_approx_equals(getBox("underover" + i).height, getBox("underover" + i + "base").height + getBox("underover" + i + "under").height + getBox("underover" + i + "over").height, e, "munderover " + i + ": height is determined by the sum heights of base and scripts"); + } + }, "Height of scripted elements"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="baseline" width="30px" height="2px" depth="0px" style="background: blue"/> + <munder id="under0"> + <mspace id="under0base" width="30px" height="5px" depth="5px" style="background: black"/> + <mspace id="under0under" width="10px" height="5px" depth="5px" style="background: black"/> + </munder> + <munder id="under1"> + <mspace id="under1base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="under1under" width="30px" height="5px" depth="5px" style="background: black"/> + </munder> + <munder id="under2"> + <mspace id="under2base" width="10px" height="15px" depth="15px" style="background: black"/> + <mspace id="under2under" width="10px" height="5px" depth="5px" style="background: black"/> + </munder> + <munder id="under3"> + <mspace id="under3base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="under3under" width="10px" height="15px" depth="15px" style="background: black"/> + </munder> + <mover id="over0"> + <mspace id="over0base" width="30px" height="5px" depth="5px" style="background: black"/> + <mspace id="over0over" width="10px" height="5px" depth="5px" style="background: black"/> + </mover> + <mover id="over1"> + <mspace id="over1base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="over1over" width="30px" height="5px" depth="5px" style="background: black"/> + </mover> + <mover id="over2"> + <mspace id="over2base" width="10px" height="15px" depth="15px" style="background: black"/> + <mspace id="over2over" width="10px" height="5px" depth="5px" style="background: black"/> + </mover> + <mover id="over3"> + <mspace id="over3base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="over3over" width="10px" height="15px" depth="15px" style="background: black"/> + </mover> + <munderover id="underover0"> + <mspace id="underover0base" width="30px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover0under" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover0over" width="10px" height="5px" depth="5px" style="background: black"/> + </munderover> + <munderover id="underover1"> + <mspace id="underover1base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover1under" width="30px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover1over" width="10px" height="5px" depth="5px" style="background: black"/> + </munderover> + <munderover id="underover2"> + <mspace id="underover2base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover2under" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover2over" width="30px" height="5px" depth="5px" style="background: black"/> + </munderover> + <munderover id="underover3"> + <mspace id="underover3base" width="10px" height="15px" depth="15px" style="background: black"/> + <mspace id="underover3under" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover3over" width="10px" height="5px" depth="5px" style="background: black"/> + </munderover> + <munderover id="underover4"> + <mspace id="underover4base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover4under" width="10px" height="15px" depth="15px" style="background: black"/> + <mspace id="underover4over" width="10px" height="5px" depth="5px" style="background: black"/> + </munderover> + <munderover id="underover5"> + <mspace id="underover5base" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover5under" width="10px" height="5px" depth="5px" style="background: black"/> + <mspace id="underover5over" width="10px" height="15px" depth="15px" style="background: black"/> + </munderover> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html new file mode 100644 index 0000000000..a9545c60f4 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>munder/mover/munderover align (reference)</title> + </head> + <body> + <p>Test passes if the center of the following rectangles is aligned + on the same vertical axis.</p> + <p> + <math> + <munder> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munder> + </math> + </p> + <p> + <math> + <munder> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munder> + </math> + </p> + <p> + <math> + <mover> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mover> + </math> + </p> + <p> + <math> + <mover> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mover> + </math> + </p> + <p> + <math> + <munderover> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munderover> + </math> + </p> + <p> + <math> + <munderover> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munderover> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html new file mode 100644 index 0000000000..aa2460e062 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>munder/mover/munderover align</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.munder"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mover"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.munderover"> + <meta name="assert" content="Check that the legacy align attribute is ignored."> + <link rel="match" href="underover-legacy-align-attribute-001-ref.html"> + </head> + <body> + <p>Test passes if the center of the following rectangles is aligned + on the same vertical axis.</p> + <p> + <math> + <munder align="left"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munder> + </math> + </p> + <p> + <math> + <munder align="right"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munder> + </math> + </p> + <p> + <math> + <mover align="left"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mover> + </math> + </p> + <p> + <math> + <mover align="right"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mover> + </math> + </p> + <p> + <math> + <munderover align="left"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munderover> + </math> + </p> + <p> + <math> + <munderover align="right"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munderover> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_munderover"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-1.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-1.html new file mode 100644 index 0000000000..eb2e0512e0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-1.html @@ -0,0 +1,151 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Underscripts and Overscripts parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Elements munder, mover, munderover correctly use the limit parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace, mo { + font-size: 10px; + } + @font-face { + font-family: lowerlimitbaselinedropmin3000; + src: url("/fonts/math/limits-lowerlimitbaselinedropmin3000.woff"); + } + @font-face { + font-family: lowerlimitgapmin11000; + src: url("/fonts/math/limits-lowerlimitgapmin11000.woff"); + } + @font-face { + font-family: upperlimitbaselinerisemin5000; + src: url("/fonts/math/limits-upperlimitbaselinerisemin5000.woff"); + } + @font-face { + font-family: upperlimitgapmin7000; + src: url("/fonts/math/limits-upperlimitgapmin7000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("under00011").top - getBox("ref0001").bottom, + v, epsilon, "munder: under shift"); + assert_approx_equals(getBox("under00012").top - getBox("ref0001").bottom, + v, epsilon, "munderover: under shift"); + }, "LowerLimitBaselineDropMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 11000 * emToPx; + assert_approx_equals(getBox("under00021").top - getBox("ref0002").bottom, + v, epsilon, "munder: under gap"); + assert_approx_equals(getBox("under00022").top - getBox("ref0002").bottom, + v, epsilon, "munderover: under gap"); + }, "LowerLimitGapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("ref0003").top - getBox("over00031").bottom, + v, epsilon, "mover: over shift"); + assert_approx_equals(getBox("ref0003").top - getBox("over00032").bottom, + v, epsilon, "munderover: over shift"); + }, "UpperLimitBaselineRiseMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 7000 * emToPx; + assert_approx_equals(getBox("ref0004").top - getBox("over00041").bottom, + v, epsilon, "mover: over shift"); + assert_approx_equals(getBox("ref0004").top - getBox("over00042").bottom, + v, epsilon, "munderover: over shift"); + }, "UpperLimitGapMin"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: lowerlimitbaselinedropmin3000;"> + <mspace id="ref0001" height="1em" width="3em" style="background: green"/> + <munder> + <mo movablelimits="false">∑</mo> + <mspace id="under00011" depth="1em" width="3em" style="background: blue"/> + </munder> + <munderover> + <mo movablelimits="false">∑</mo> + <mspace id="under00012" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: lowerlimitgapmin11000;"> + <mspace id="ref0002" height="1em" width="3em" style="background: green"/> + <munder> + <mo movablelimits="false">∑</mo> + <mspace id="under00021" depth="1em" width="3em" style="background: blue"/> + </munder> + <munderover> + <mo movablelimits="false">∑</mo> + <mspace id="under00022" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: upperlimitbaselinerisemin5000;"> + <mspace id="ref0003" height="1em" width="3em" style="background: green"/> + <mover> + <mo movablelimits="false">∑</mo> + <mspace id="over00031" height="1em" width="3em" style="background: blue"/> + </mover> + <munderover> + <mo movablelimits="false">∑</mo> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00032" height="1em" width="3em" style="background: blue"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: upperlimitgapmin7000;"> + <mspace id="ref0004" height="1em" width="3em" style="background: green"/> + <mover> + <mo movablelimits="false">∑</mo> + <mspace id="over00041" depth="1em" width="3em" style="background: blue"/> + </mover> + <munderover> + <mo movablelimits="false">∑</mo> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00042" depth="1em" width="3em" style="background: blue"/> + </munderover> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-2.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-2.html new file mode 100644 index 0000000000..aad03a3863 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-2.html @@ -0,0 +1,151 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Underscripts and Overscripts parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Elements munder, mover, munderover correctly use the stretch stack parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace, mo { + font-size: 10px; + } + @font-face { + font-family: bottomshiftdown3000; + src: url("/fonts/math/stretchstack-bottomshiftdown3000.woff"); + } + @font-face { + font-family: gapbelowmin11000; + src: url("/fonts/math/stretchstack-gapbelowmin11000.woff"); + } + @font-face { + font-family: topshiftup5000; + src: url("/fonts/math/stretchstack-topshiftup5000.woff"); + } + @font-face { + font-family: gapabovemin7000; + src: url("/fonts/math/stretchstack-gapabovemin7000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("under00011").top - getBox("ref0001").bottom, + v, epsilon, "munder: under shift"); + assert_approx_equals(getBox("under00012").top - getBox("ref0001").bottom, + v, epsilon, "munderover: under shift"); + }, "StretchStackBottomShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 11000 * emToPx; + assert_approx_equals(getBox("under00021").top - getBox("ref0002").bottom, + v, epsilon, "munder: under gap"); + assert_approx_equals(getBox("under00022").top - getBox("ref0002").bottom, + v, epsilon, "munderover: under gap"); + }, "StretchStackGapBelowMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("ref0003").top - getBox("over00031").bottom, + v, epsilon, "mover: over shift"); + assert_approx_equals(getBox("ref0003").top - getBox("over00032").bottom, + v, epsilon, "munderover: over shift"); + }, "StretchStackTopShiftUp"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 7000 * emToPx; + assert_approx_equals(getBox("ref0004").top - getBox("over00041").bottom, + v, epsilon, "mover: over shift"); + assert_approx_equals(getBox("ref0004").top - getBox("over00042").bottom, + v, epsilon, "munderover: over shift"); + }, "StretchStackGapAboveMin"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: bottomshiftdown3000;"> + <mspace id="ref0001" height="1em" width="3em" style="background: green"/> + <munder> + <mo>→</mo> + <mspace id="under00011" depth="1em" width="3em" style="background: blue"/> + </munder> + <munderover> + <mo>→</mo> + <mspace id="under00012" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: gapbelowmin11000;"> + <mspace id="ref0002" height="1em" width="3em" style="background: green"/> + <munder> + <mo>→</mo> + <mspace id="under00021" depth="1em" width="3em" style="background: blue"/> + </munder> + <munderover> + <mo>→</mo> + <mspace id="under00022" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: topshiftup5000;"> + <mspace id="ref0003" height="1em" width="3em" style="background: green"/> + <mover> + <mo>→</mo> + <mspace id="over00031" height="1em" width="3em" style="background: blue"/> + </mover> + <munderover> + <mo>→</mo> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00032" height="1em" width="3em" style="background: blue"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: gapabovemin7000;"> + <mspace id="ref0004" height="1em" width="3em" style="background: green"/> + <mover> + <mo>→</mo> + <mspace id="over00041" depth="1em" width="3em" style="background: blue"/> + </mover> + <munderover> + <mo>→</mo> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00042" depth="1em" width="3em" style="background: blue"/> + </munderover> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-3.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-3.html new file mode 100644 index 0000000000..9ec9dbf47e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-3.html @@ -0,0 +1,452 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Underscripts and Overscripts parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Elements munder, mover, munderover correctly use underbar/overbar and AccentBaseHeight parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace, mo { + font-size: 10px; + } + @font-face { + font-family: accentbaseheight4000underbarextradescender5000; + src: url("/fonts/math/underover-accentbaseheight4000-underbarextradescender5000.woff"); + } + @font-face { + font-family: accentbaseheight4000underbarverticalgap7000; + src: url("/fonts/math/underover-accentbaseheight4000-underbarverticalgap7000.woff"); + } + @font-face { + font-family: accentbaseheight4000overbarextraascender3000; + src: url("/fonts/math/underover-accentbaseheight4000-overbarextraascender3000.woff"); + } + @font-face { + font-family: accentbaseheight4000overbarverticalgap11000; + src: url("/fonts/math/underover-accentbaseheight4000-overbarverticalgap11000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 2; + var axisBaseHeight = 4000 * emToPx; + var shortBaseHeight = 3000 * emToPx; // shortBaseHeight < axisBaseHeight + var tallBaseHeight = 5000 * emToPx; // tallBaseHeight > axisBaseHeight + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function getBooleanValue(element, name) { + return (element.getAttribute(name) || "").toLowerCase() === "true"; + } + let dynamicBooleanAttributeChanges = { + "Invert boolean value using absent attribute": function(element, name) { + if (getBooleanValue(element, name)) { + element.removeAttribute(name); + } else { + element.setAttribute(name, "true"); + } + }, + + "Invert boolean value using invalid attribute": function(element, name) { + if (getBooleanValue(element, name)) { + element.setAttribute(name, "invalid"); + } else { + element.setAttribute(name, "true"); + } + }, + + "Change case of boolean attribute": function(element, name) { + if (getBooleanValue(element, name)) { + element.setAttribute(name, "TrUe"); + } else { + element.setAttribute(name, "FaLsE"); + } + } + }; + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + for (var i = 1; i <= 4; i++) { + for (var j = 1; j <= 6; j++) { + var baseId = ("base00" + i) + j; + assert_approx_equals(getBox("ref00" + i).bottom, + getBox(baseId).bottom, + epsilon, + "alignment of " + baseId); + } + } + }, "Baseline alignment"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + for (var i = 1; i <= 4; i++) { + for (var j = 1; j <= 6; j++) { + var baseId = ("base00" + i) + j; + assert_approx_equals(getBox(baseId).height, + j == 2 || j == 5 ? + tallBaseHeight :shortBaseHeight, + epsilon, + "height of " + baseId); + } + } + }, "Heights of bases"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("ref001").bottom - getBox("over0014").bottom, + shortBaseHeight, epsilon, + "munderover: nonaccent over short base"); + assert_approx_equals(getBox("ref001").bottom - getBox("over0015").bottom, + tallBaseHeight, epsilon, + "munderover: accent over tall base"); + assert_approx_equals(getBox("ref001").bottom - getBox("over0016").bottom, + axisBaseHeight, epsilon, + "munderover: accent over short base"); + for (var j = 1; j <= 6; j++) { + var elId = "el001" + j; + var baseId = "base001" + j; + var underId = "under001" + j; + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + 0, epsilon, + "gap between " + baseId + " and " + underId); + assert_approx_equals(getBox(elId).bottom - getBox(underId).bottom, + v, epsilon, + "extra descender below " + underId); + } + }, "AccentBaseHeight, UnderbarExtraDescender"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 7000 * emToPx; + assert_approx_equals(getBox("ref002").bottom - getBox("over0024").bottom, + shortBaseHeight, epsilon, + "munderover: nonaccent over short base"); + assert_approx_equals(getBox("ref002").bottom - getBox("over0025").bottom, + tallBaseHeight, epsilon, + "munderover: accent over tall base"); + assert_approx_equals(getBox("ref002").bottom - getBox("over0026").bottom, + axisBaseHeight, epsilon, + "munderover: accent over short base"); + for (var j = 1; j <= 6; j++) { + var elId = "el002" + j; + var baseId = "base002" + j; + var underId = "under002" + j; + var gap = (j == 2 || j == 3 ? 0 : v); + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + gap, epsilon, + "gap between " + baseId + " and " + underId); + } + }, "AccentBaseHeight, UnderbarVerticalGap"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("ref003").bottom - getBox("over0031").bottom, + shortBaseHeight, epsilon, + "mover: nonaccent over short base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0032").bottom, + tallBaseHeight, epsilon, + "mover: accent over tall base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0033").bottom, + axisBaseHeight, epsilon, + "mover: accent over short base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0034").bottom, + shortBaseHeight, epsilon, + "munderover: nonaccent over short base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0035").bottom, + tallBaseHeight, epsilon, + "munderover: accent over tall base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0036").bottom, + axisBaseHeight, epsilon, + "munderover: accent over short base"); + for (var j = 1; j <= 6; j++) { + var elId = "el003" + j; + var baseId = "base003" + j; + if (j >= 4) { + var underId = "under003" + j; + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + 0, epsilon, + "gap between " + baseId + " and " + underId); + } + var overId = "over003" + j; + assert_approx_equals(getBox(overId).top - getBox(elId).top, + v, epsilon, + "extra ascender below " + overId); + } + }, "AccentBaseHeight, OverbarExtraAscender"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + v = 11000 * emToPx; + assert_approx_equals(getBox("ref004").bottom - getBox("over0041").bottom, + shortBaseHeight + v, epsilon, + "mover: nonaccent over short base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0042").bottom, + tallBaseHeight, epsilon, + "mover: accent over tall base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0043").bottom, + axisBaseHeight, epsilon, + "mover: accent over short base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0044").bottom, + shortBaseHeight + v, epsilon, + "munderover: nonaccent over short base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0045").bottom, + tallBaseHeight, epsilon, + "munderover: accent over tall base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0046").bottom, + axisBaseHeight, epsilon, + "munderover: accent over short base"); + for (var j = 4; j <= 6; j++) { + var baseId = "base004" + j; + var underId = "under004" + j; + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + 0, epsilon, + "gap between " + baseId + " and " + underId); + } + }, "AccentBaseHeight, OverbarVerticalGap"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var v = 7000 * emToPx; + + for (var j = 1; j <= 4; j++) { + var elId = `el005${j}`; + var baseId = `base005${j}`; + var underId = `under005${j}`; + + for (name in dynamicBooleanAttributeChanges) { + let element = document.getElementById(elId); + dynamicBooleanAttributeChanges[name](element, "accentunder"); + var value = getBooleanValue(element, "accentunder"); + var gap = value ? 0 : v; + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + gap, epsilon, + `${elId}: gap between base and underscript ; ${name}`); + }; + } + }, "Dynamic change of accentunder attribute"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + v = 11000 * emToPx; + for (var j = 1; j <= 4; j++) { + var elId = `el006${j}`; + var refId = `base006${j}`; + var overId = `over006${j}`; + for (name in dynamicBooleanAttributeChanges) { + let element = document.getElementById(elId); + dynamicBooleanAttributeChanges[name](element, "accent"); + var value = getBooleanValue(element, "accent"); + assert_approx_equals(getBox(refId).bottom - getBox(overId).bottom, + value ? axisBaseHeight : shortBaseHeight + v, + epsilon, + `${elId}: accent=${value} ; short base ; ${name}`); + } + } + }, "Dynamic change of accent attribute"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: accentbaseheight4000underbarextradescender5000;"> + <mspace id="ref001" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0011"> + <mspace id="base0011" height="3em" width="1em" style="background: black"/> + <mspace id="under0011" height="1em" width="3em" style="background: blue"/> + </munder> + <munder style="background: cyan" id="el0012" accentunder="true"> + <mspace id="base0012" height="5em" width="1em" style="background: black"/> + <mspace id="under0012" height="1em" width="3em" style="background: blue"/> + </munder> + <munder style="background: cyan" id="el0013" accentunder="true"> + <mspace id="base0013" height="3em" width="1em" style="background: black"/> + <mspace id="under0013" height="1em" width="3em" style="background: blue"/> + </munder> + <munderover style="background: cyan" id="el0014"> + <mspace id="base0014" height="3em" width="1em" style="background: black"/> + <mspace id="under0014" height="1em" width="3em" style="background: blue"/> + <mspace id="over0014" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0015" accent="true"> + <mspace id="base0015" height="5em" width="1em" style="background: black"/> + <mspace id="under0015" height="1em" width="3em" style="background: blue"/> + <mspace id="over0015" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0016" accent="true"> + <mspace id="base0016" height="3em" width="1em" style="background: black"/> + <mspace id="under0016" height="1em" width="3em" style="background: blue"/> + <mspace id="over0016" height="1em" width="3em" style="background: red"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: accentbaseheight4000underbarverticalgap7000;"> + <mspace id="ref002" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0021"> + <mspace id="base0021" height="3em" width="1em" style="background: black"/> + <mspace id="under0021" height="1em" width="3em" style="background: blue"/> + </munder> + <munder style="background: cyan" id="el0022" accentunder="true"> + <mspace id="base0022" height="5em" width="1em" style="background: black"/> + <mspace id="under0022" height="1em" width="3em" style="background: blue"/> + </munder> + <munder style="background: cyan" id="el0023" accentunder="true"> + <mspace id="base0023" height="3em" width="1em" style="background: black"/> + <mspace id="under0023" height="1em" width="3em" style="background: blue"/> + </munder> + <munderover style="background: cyan" id="el0024"> + <mspace id="base0024" height="3em" width="1em" style="background: black"/> + <mspace id="under0024" height="1em" width="3em" style="background: blue"/> + <mspace id="over0024" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0025" accent="true"> + <mspace id="base0025" height="5em" width="1em" style="background: black"/> + <mspace id="under0025" height="1em" width="3em" style="background: blue"/> + <mspace id="over0025" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0026" accent="true"> + <mspace id="base0026" height="3em" width="1em" style="background: black"/> + <mspace id="under0026" height="1em" width="3em" style="background: blue"/> + <mspace id="over0026" height="1em" width="3em" style="background: red"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: accentbaseheight4000overbarextraascender3000;"> + <mspace id="ref003" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0031"> + <mspace id="base0031" height="3em" width="1em" style="background: black"/> + <mspace id="over0031" height="1em" width="3em" style="background: red"/> + </mover> + <mover style="background: cyan" id="el0032" accent="true"> + <mspace id="base0032" height="5em" width="1em" style="background: black"/> + <mspace id="over0032" height="1em" width="3em" style="background: red"/> + </mover> + <mover style="background: cyan" id="el0033" accent="true"> + <mspace id="base0033" height="3em" width="1em" style="background: black"/> + <mspace id="over0033" height="1em" width="3em" style="background: red"/> + </mover> + <munderover style="background: cyan" id="el0034"> + <mspace id="base0034" height="3em" width="1em" style="background: black"/> + <mspace id="under0034" height="1em" width="3em" style="background: blue"/> + <mspace id="over0034" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0035" accent="true"> + <mspace id="base0035" height="5em" width="1em" style="background: black"/> + <mspace id="under0035" height="1em" width="3em" style="background: blue"/> + <mspace id="over0035" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0036" accent="true"> + <mspace id="base0036" height="3em" width="1em" style="background: black"/> + <mspace id="under0036" height="1em" width="3em" style="background: blue"/> + <mspace id="over0036" height="1em" width="3em" style="background: red"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: accentbaseheight4000overbarverticalgap11000;"> + <mspace id="ref004" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0041"> + <mspace id="base0041" height="3em" width="1em" style="background: black"/> + <mspace id="over0041" height="1em" width="3em" style="background: red"/> + </mover> + <mover style="background: cyan" id="el0042" accent="true"> + <mspace id="base0042" height="5em" width="1em" style="background: black"/> + <mspace id="over0042" height="1em" width="3em" style="background: red"/> + </mover> + <mover style="background: cyan" id="el0043" accent="true"> + <mspace id="base0043" height="3em" width="1em" style="background: black"/> + <mspace id="over0043" height="1em" width="3em" style="background: red"/> + </mover> + <munderover style="background: cyan" id="el0044"> + <mspace id="base0044" height="3em" width="1em" style="background: black"/> + <mspace id="under0044" height="1em" width="3em" style="background: blue"/> + <mspace id="over0044" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0045" accent="true"> + <mspace id="base0045" height="5em" width="1em" style="background: black"/> + <mspace id="under0045" height="1em" width="3em" style="background: blue"/> + <mspace id="over0045" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0046" accent="true"> + <mspace id="base0046" height="3em" width="1em" style="background: black"/> + <mspace id="under0046" height="1em" width="3em" style="background: blue"/> + <mspace id="over0046" height="1em" width="3em" style="background: red"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: accentbaseheight4000underbarverticalgap7000;"> + <mspace id="ref005" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0051"> + <mspace id="base0051" height="5em" width="1em" style="background: black"/> + <mspace id="under0051" height="1em" width="3em" style="background: blue"/> + </munder> + <munder style="background: cyan" id="el0052" accentunder="true"> + <mspace id="base0052" height="5em" width="1em" style="background: black"/> + <mspace id="under0052" height="1em" width="3em" style="background: blue"/> + </munder> + <munderover style="background: cyan" id="el0053"> + <mspace id="base0053" height="5em" width="1em" style="background: black"/> + <mspace id="under0053" height="1em" width="3em" style="background: blue"/> + <mspace id="over0053" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0054" accentunder="true"> + <mspace id="base0054" height="5em" width="1em" style="background: black"/> + <mspace id="under0054" height="1em" width="3em" style="background: blue"/> + <mspace id="over0054" height="1em" width="3em" style="background: red"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: accentbaseheight4000overbarverticalgap11000;"> + <mspace id="ref006" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0061"> + <mspace id="base0061" height="3em" width="1em" style="background: black"/> + <mspace id="over0061" height="1em" width="3em" style="background: red"/> + </mover> + <mover style="background: cyan" id="el0062" accent="true"> + <mspace id="base0062" height="3em" width="1em" style="background: black"/> + <mspace id="over0062" height="1em" width="3em" style="background: red"/> + </mover> + <munderover style="background: cyan" id="el0063"> + <mspace id="base0063" height="3em" width="1em" style="background: black"/> + <mspace id="under0063" height="1em" width="3em" style="background: blue"/> + <mspace id="over0063" height="1em" width="3em" style="background: red"/> + </munderover> + <munderover style="background: cyan" id="el0064" accent="true"> + <mspace id="base0064" height="3em" width="1em" style="background: black"/> + <mspace id="under0064" height="1em" width="3em" style="background: blue"/> + <mspace id="over0064" height="1em" width="3em" style="background: red"/> + </munderover> + </math> + </p> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-4.tentative.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-4.tentative.html new file mode 100644 index 0000000000..5000d24f18 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-4.tentative.html @@ -0,0 +1,335 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Underscripts and Overscripts parameters</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mo.attrs"> +<meta name="assert" content="Elements munder, mover, munderover correctly use underbar/overbar and AccentBaseHeight parameters from the MATH table ; interaction with MathML3 mo@accent."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace, mo { + font-size: 10px; + } + @font-face { + font-family: accentbaseheight4000underbarextradescender5000; + src: url("/fonts/math/underover-accentbaseheight4000-underbarextradescender5000.woff"); + } + @font-face { + font-family: accentbaseheight4000underbarverticalgap7000; + src: url("/fonts/math/underover-accentbaseheight4000-underbarverticalgap7000.woff"); + } + @font-face { + font-family: accentbaseheight4000overbarextraascender3000; + src: url("/fonts/math/underover-accentbaseheight4000-overbarextraascender3000.woff"); + } + @font-face { + font-family: accentbaseheight4000overbarverticalgap11000; + src: url("/fonts/math/underover-accentbaseheight4000-overbarverticalgap11000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 2; + var axisBaseHeight = 4000 * emToPx; + var shortBaseHeight = 3000 * emToPx; // shortBaseHeight < axisBaseHeight + var tallBaseHeight = 5000 * emToPx; // tallBaseHeight > axisBaseHeight + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + for (var i = 1; i <= 4; i++) { + for (var j = 1; j <= 6; j++) { + var baseId = ("base00" + i) + j; + assert_approx_equals(getBox("ref00" + i).bottom, + getBox(baseId).bottom, + epsilon, + "alignment of " + baseId); + } + } + }, "Baseline alignment"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + for (var i = 1; i <= 4; i++) { + for (var j = 1; j <= 6; j++) { + var baseId = ("base00" + i) + j; + assert_approx_equals(getBox(baseId).height, + j == 2 || j == 5 ? + tallBaseHeight :shortBaseHeight, + epsilon, + "height of " + baseId); + } + } + }, "Heights of bases"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("ref001").bottom - getBox("over0014").bottom, + shortBaseHeight, epsilon, + "munderover: nonaccent over short base"); + assert_approx_equals(getBox("ref001").bottom - getBox("over0015").bottom, + tallBaseHeight, epsilon, + "munderover: accent over tall base"); + assert_approx_equals(getBox("ref001").bottom - getBox("over0016").bottom, + axisBaseHeight, epsilon, + "munderover: accent over short base"); + for (var j = 1; j <= 6; j++) { + var elId = "el001" + j; + var baseId = "base001" + j; + var underId = "under001" + j; + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + 0, epsilon, + "gap between " + baseId + " and " + underId); + assert_approx_equals(getBox(elId).bottom - getBox(underId).bottom, + v, epsilon, + "extra descender below " + underId); + } + }, "AccentBaseHeight, UnderbarExtraDescender"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 7000 * emToPx; + assert_approx_equals(getBox("ref002").bottom - getBox("over0024").bottom, + shortBaseHeight, epsilon, + "munderover: nonaccent over short base"); + assert_approx_equals(getBox("ref002").bottom - getBox("over0025").bottom, + tallBaseHeight, epsilon, + "munderover: accent over tall base"); + assert_approx_equals(getBox("ref002").bottom - getBox("over0026").bottom, + axisBaseHeight, epsilon, + "munderover: accent over short base"); + for (var j = 1; j <= 6; j++) { + var elId = "el002" + j; + var baseId = "base002" + j; + var underId = "under002" + j; + var gap = (j == 2 || j == 3 ? 0 : v); + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + gap, epsilon, + "gap between " + baseId + " and " + underId); + } + }, "AccentBaseHeight, UnderbarVerticalGap"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("ref003").bottom - getBox("over0031").bottom, + shortBaseHeight, epsilon, + "mover: nonaccent over short base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0032").bottom, + tallBaseHeight, epsilon, + "mover: accent over tall base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0033").bottom, + axisBaseHeight, epsilon, + "mover: accent over short base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0034").bottom, + shortBaseHeight, epsilon, + "munderover: nonaccent over short base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0035").bottom, + tallBaseHeight, epsilon, + "munderover: accent over tall base"); + assert_approx_equals(getBox("ref003").bottom - getBox("over0036").bottom, + axisBaseHeight, epsilon, + "munderover: accent over short base"); + for (var j = 1; j <= 6; j++) { + var elId = "el003" + j; + var baseId = "base003" + j; + if (j >= 4) { + var underId = "under003" + j; + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + 0, epsilon, + "gap between " + baseId + " and " + underId); + } + var overId = "over003" + j; + assert_approx_equals(getBox(overId).top - getBox(elId).top, + v, epsilon, + "extra ascender below " + overId); + } + }, "AccentBaseHeight, OverbarExtraAscender"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + v = 11000 * emToPx; + assert_approx_equals(getBox("ref004").bottom - getBox("over0041").bottom, + shortBaseHeight + v, epsilon, + "mover: nonaccent over short base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0042").bottom, + tallBaseHeight, epsilon, + "mover: accent over tall base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0043").bottom, + axisBaseHeight, epsilon, + "mover: accent over short base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0044").bottom, + shortBaseHeight + v, epsilon, + "munderover: nonaccent over short base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0045").bottom, + tallBaseHeight, epsilon, + "munderover: accent over tall base"); + assert_approx_equals(getBox("ref004").bottom - getBox("over0046").bottom, + axisBaseHeight, epsilon, + "munderover: accent over short base"); + for (var j = 4; j <= 6; j++) { + var baseId = "base004" + j; + var underId = "under004" + j; + assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, + 0, epsilon, + "gap between " + baseId + " and " + underId); + } + }, "AccentBaseHeight, OverbarVerticalGap"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: accentbaseheight4000underbarextradescender5000;"> + <mspace id="ref001" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0011"> + <mspace id="base0011" height="3em" width="1em" style="background: black"/> + <mo id="under0011" style="color: blue">°</mo> + </munder> + <munder style="background: cyan" id="el0012"> + <mspace id="base0012" height="5em" width="1em" style="background: black"/> + <mo id="under0012" style="color: blue">˘</mo> + </munder> + <munder style="background: cyan" id="el0013"> + <mspace id="base0013" height="3em" width="1em" style="background: black"/> + <mo id="under0013" style="color: blue">˘</mo> + </munder> + <munderover style="background: cyan" id="el0014"> + <mspace id="base0014" height="3em" width="1em" style="background: black"/> + <mo id="under0014" style="color: blue">°</mo> + <mo id="over0014" style="color: red">°</mo> + </munderover> + <munderover style="background: cyan" id="el0015" accent="true"> + <mspace id="base0015" height="5em" width="1em" style="background: black"/> + <mo id="under0015" style="color: blue">˘</mo> + <mo id="over0015" style="color: red">˘</mo> + </munderover> + <munderover style="background: cyan" id="el0016" accent="true"> + <mspace id="base0016" height="3em" width="1em" style="background: black"/> + <mo id="under0016" style="color: blue">˘</mo> + <mo id="over0016" style="color: red">˘</mo> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: accentbaseheight4000underbarverticalgap7000;"> + <mspace id="ref002" height="1em" width="3em" style="background: green"/> + <munder style="background: cyan" id="el0021" accentunder="false"> + <mspace id="base0021" height="3em" width="1em" style="background: black"/> + <mo id="under0021" style="color: blue">˘</mo> + </munder> + <munder style="background: cyan" id="el0022"> + <mspace id="base0022" height="5em" width="1em" style="background: black"/> + <mo id="under0022" style="color: blue" accent="true">˘</mo> + </munder> + <munder style="background: cyan" id="el0023"> + <mspace id="base0023" height="3em" width="1em" style="background: black"/> + <mo id="under0023" style="color: blue" accent="true">°</mo> + </munder> + <munderover style="background: cyan" id="el0024"> + <mspace id="base0024" height="3em" width="1em" style="background: black"/> + <mo id="under0024" style="color: blue" accent="false">˘</mo> + <mo id="over0024" style="color: red" accent="false">˘</mo> + </munderover> + <munderover style="background: cyan" id="el0025"> + <mspace id="base0025" height="5em" width="1em" style="background: black"/> + <mo id="under0025" style="color: blue" accent="false">˘</mo> + <mo id="over0025" style="color: red">˘</mo> + </munderover> + <munderover style="background: cyan" id="el0026"> + <mspace id="base0026" height="3em" width="1em" style="background: black"/> + <mo id="under0026" style="color: blue" accent="false">˘</mo> + <mo id="over0026" style="color: red">˘</mo> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: accentbaseheight4000overbarextraascender3000;"> + <mspace id="ref003" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0031"> + <mspace id="base0031" height="3em" width="1em" style="background: black"/> + <mo id="over0031" style="color: red">°</mo> + </mover> + <mover style="background: cyan" id="el0032" accent="true"> + <mspace id="base0032" height="5em" width="1em" style="background: black"/> + <mo id="over0032" style="color: red">°</mo> + </mover> + <mover style="background: cyan" id="el0033"> + <mspace id="base0033" height="3em" width="1em" style="background: black"/> + <mo id="over0033" style="color: red">˘</mo> + </mover> + <munderover style="background: cyan" id="el0034"> + <mspace id="base0034" height="3em" width="1em" style="background: black"/> + <mo id="under0034" style="color: blue">°</mo> + <mo id="over0034" style="color: red" accent="false">˘</mo> + </munderover> + <munderover style="background: cyan" id="el0035" accent="true"> + <mspace id="base0035" height="5em" width="1em" style="background: black"/> + <mo id="under0035" style="color: blue">˘</mo> + <mo id="over0035" style="color: red">˘</mo> + </munderover> + <munderover style="background: cyan" id="el0036" accent="true"> + <mspace id="base0036" height="3em" width="1em" style="background: black"/> + <mo id="under0036" style="color: blue">˘</mo> + <mo id="over0036" style="color: red">˘</mo> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: accentbaseheight4000overbarverticalgap11000;"> + <mspace id="ref004" height="1em" width="3em" style="background: green"/> + <mover style="background: cyan" id="el0041"> + <mspace id="base0041" height="3em" width="1em" style="background: black"/> + <mo id="over0041" style="color: red">°</mo> + </mover> + <mover style="background: cyan" id="el0042" accent="true"> + <mspace id="base0042" height="5em" width="1em" style="background: black"/> + <mo id="over0042" style="color: red">°</mo> + </mover> + <mover style="background: cyan" id="el0043"> + <mspace id="base0043" height="3em" width="1em" style="background: black"/> + <mo id="over0043" style="color: red">˘</mo> + </mover> + <munderover style="background: cyan" id="el0044"> + <mspace id="base0044" height="3em" width="1em" style="background: black"/> + <mo id="under0044" style="color: blue">°</mo> + <mo id="over0044" style="color: red" accent="false">˘</mo> + </munderover> + <munderover style="background: cyan" id="el0045" accent="true"> + <mspace id="base0045" height="5em" width="1em" style="background: black"/> + <mo id="under0045" style="color: blue">˘</mo> + <mo id="over0045" style="color: red">˘</mo> + </munderover> + <munderover style="background: cyan" id="el0046" accent="true"> + <mspace id="base0046" height="3em" width="1em" style="background: black"/> + <mo id="under0046" style="color: blue">˘</mo> + <mo id="over0046" style="color: red">˘</mo> + </munderover> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-and-embellished-operator-1.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-and-embellished-operator-1.html new file mode 100644 index 0000000000..1c236eabed --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-and-embellished-operator-1.html @@ -0,0 +1,151 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Underscripts and Overscripts parameters (embellished operators)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Elements munder, mover, munderover (with an embelished operator base) correctly use the limit parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace, mo { + font-size: 10px; + } + @font-face { + font-family: lowerlimitbaselinedropmin3000; + src: url("/fonts/math/limits-lowerlimitbaselinedropmin3000.woff"); + } + @font-face { + font-family: lowerlimitgapmin11000; + src: url("/fonts/math/limits-lowerlimitgapmin11000.woff"); + } + @font-face { + font-family: upperlimitbaselinerisemin5000; + src: url("/fonts/math/limits-upperlimitbaselinerisemin5000.woff"); + } + @font-face { + font-family: upperlimitgapmin7000; + src: url("/fonts/math/limits-upperlimitgapmin7000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("under00011").top - getBox("ref0001").bottom, + v, epsilon, "munder: under shift"); + assert_approx_equals(getBox("under00012").top - getBox("ref0001").bottom, + v, epsilon, "munderover: under shift"); + }, "LowerLimitBaselineDropMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 11000 * emToPx; + assert_approx_equals(getBox("under00021").top - getBox("ref0002").bottom, + v, epsilon, "munder: under gap"); + assert_approx_equals(getBox("under00022").top - getBox("ref0002").bottom, + v, epsilon, "munderover: under gap"); + }, "LowerLimitGapMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("ref0003").top - getBox("over00031").bottom, + v, epsilon, "mover: over shift"); + assert_approx_equals(getBox("ref0003").top - getBox("over00032").bottom, + v, epsilon, "munderover: over shift"); + }, "UpperLimitBaselineRiseMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 7000 * emToPx; + assert_approx_equals(getBox("ref0004").top - getBox("over00041").bottom, + v, epsilon, "mover: over shift"); + assert_approx_equals(getBox("ref0004").top - getBox("over00042").bottom, + v, epsilon, "munderover: over shift"); + }, "UpperLimitGapMin"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: lowerlimitbaselinedropmin3000;"> + <mspace id="ref0001" height="1em" width="3em" style="background: green"/> + <munder> + <mrow><mrow><mo movablelimits="false">∑</mo></mrow></mrow> + <mspace id="under00011" depth="1em" width="3em" style="background: blue"/> + </munder> + <munderover> + <mrow><mrow><mo movablelimits="false">∑</mo></mrow></mrow> + <mspace id="under00012" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: lowerlimitgapmin11000;"> + <mspace id="ref0002" height="1em" width="3em" style="background: green"/> + <munder> + <mrow><mrow><mo movablelimits="false">∑</mo></mrow></mrow> + <mspace id="under00021" depth="1em" width="3em" style="background: blue"/> + </munder> + <munderover> + <mrow><mrow><mo movablelimits="false">∑</mo></mrow></mrow> + <mspace id="under00022" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: upperlimitbaselinerisemin5000;"> + <mspace id="ref0003" height="1em" width="3em" style="background: green"/> + <mover> + <mrow><mrow><mo movablelimits="false">∑</mo></mrow></mrow> + <mspace id="over00031" height="1em" width="3em" style="background: blue"/> + </mover> + <munderover> + <mrow><mrow><mo movablelimits="false">∑</mo></mrow></mrow> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00032" height="1em" width="3em" style="background: blue"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: upperlimitgapmin7000;"> + <mspace id="ref0004" height="1em" width="3em" style="background: green"/> + <mover> + <mrow><mrow><mo movablelimits="false">∑</mo></mrow></mrow> + <mspace id="over00041" depth="1em" width="3em" style="background: blue"/> + </mover> + <munderover> + <mrow><mrow><mo movablelimits="false">∑</mo></mrow></mrow> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00042" depth="1em" width="3em" style="background: blue"/> + </munderover> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-and-embellished-operator-2.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-and-embellished-operator-2.html new file mode 100644 index 0000000000..04a97786c4 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-parameters-and-embellished-operator-2.html @@ -0,0 +1,151 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Underscripts and Overscripts parameters (embellished operators)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Elements munder, mover, munderover (with an embelished operator base) correctly use the stretch stack parameters from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace, mo { + font-size: 10px; + } + @font-face { + font-family: bottomshiftdown3000; + src: url("/fonts/math/stretchstack-bottomshiftdown3000.woff"); + } + @font-face { + font-family: gapbelowmin11000; + src: url("/fonts/math/stretchstack-gapbelowmin11000.woff"); + } + @font-face { + font-family: topshiftup5000; + src: url("/fonts/math/stretchstack-topshiftup5000.woff"); + } + @font-face { + font-family: gapabovemin7000; + src: url("/fonts/math/stretchstack-gapabovemin7000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 3000 * emToPx; + assert_approx_equals(getBox("under00011").top - getBox("ref0001").bottom, + v, epsilon, "munder: under shift"); + assert_approx_equals(getBox("under00012").top - getBox("ref0001").bottom, + v, epsilon, "munderover: under shift"); + }, "StretchStackBottomShiftDown"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 11000 * emToPx; + assert_approx_equals(getBox("under00021").top - getBox("ref0002").bottom, + v, epsilon, "munder: under gap"); + assert_approx_equals(getBox("under00022").top - getBox("ref0002").bottom, + v, epsilon, "munderover: under gap"); + }, "StretchStackGapBelowMin"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 5000 * emToPx; + assert_approx_equals(getBox("ref0003").top - getBox("over00031").bottom, + v, epsilon, "mover: over shift"); + assert_approx_equals(getBox("ref0003").top - getBox("over00032").bottom, + v, epsilon, "munderover: over shift"); + }, "StretchStackTopShiftUp"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v = 7000 * emToPx; + assert_approx_equals(getBox("ref0004").top - getBox("over00041").bottom, + v, epsilon, "mover: over shift"); + assert_approx_equals(getBox("ref0004").top - getBox("over00042").bottom, + v, epsilon, "munderover: over shift"); + }, "StretchStackGapAboveMin"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: bottomshiftdown3000;"> + <mspace id="ref0001" height="1em" width="3em" style="background: green"/> + <munder> + <mrow><mrow><mo>→</mo></mrow></mrow> + <mspace id="under00011" depth="1em" width="3em" style="background: blue"/> + </munder> + <munderover> + <mrow><mrow><mo>→</mo></mrow></mrow> + <mspace id="under00012" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: gapbelowmin11000;"> + <mspace id="ref0002" height="1em" width="3em" style="background: green"/> + <munder> + <mrow><mrow><mo>→</mo></mrow></mrow> + <mspace id="under00021" depth="1em" width="3em" style="background: blue"/> + </munder> + <munderover> + <mrow><mrow><mo>→</mo></mrow></mrow> + <mspace id="under00022" depth="1em" width="3em" style="background: blue"/> + <mspace height="1em" width="3em" style="background: black"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: topshiftup5000;"> + <mspace id="ref0003" height="1em" width="3em" style="background: green"/> + <mover> + <mrow><mrow><mo>→</mo></mrow></mrow> + <mspace id="over00031" height="1em" width="3em" style="background: blue"/> + </mover> + <munderover> + <mrow><mrow><mo>→</mo></mrow></mrow> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00032" height="1em" width="3em" style="background: blue"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math style="font-family: gapabovemin7000;"> + <mspace id="ref0004" height="1em" width="3em" style="background: green"/> + <mover> + <mrow><mrow><mo>→</mo></mrow></mrow> + <mspace id="over00041" depth="1em" width="3em" style="background: blue"/> + </mover> + <munderover> + <mrow><mrow><mo>→</mo></mrow></mrow> + <mspace height="1em" width="3em" style="background: black"/> + <mspace id="over00042" depth="1em" width="3em" style="background: blue"/> + </munderover> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-001-ref.html new file mode 100644 index 0000000000..89ac9c6324 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-001-ref.html @@ -0,0 +1,167 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Horizontal stretchy operator (reference)</title> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/stretchy.woff"); + } + math, mo { + font-family: TestFont; + font-size: 50px; + } +</style> +<body> + <p>This test passes if you see green rectangles and no red.</p> + + <div style="position: absolute; left: 3em; top; 3em; + width: 1000px; height: 500px; background: lightgreen;"> + + <div style="position: absolute; top: 1px; left: 1px;"> + <!-- stretchy base in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 251px;"> + <!-- stretchy script in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 1px;"> + <!-- stretchy base in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 251px;"> + <!-- stretchy script in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 1px;"> + <!-- stretchy base in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 251px;"> + <!-- stretchy underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 1px;"> + <!-- stretchy overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 501px;"> + <!-- stretchy base and underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 151px; left: 501px;"> + <!-- stretchy base and overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 501px;"> + <!-- stretchy scripts in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 751px;"> + <!-- Only stretchy operators in munderover. The widest unstretched size + is used as the target size. --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="font-size: 1em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 4em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 2em; color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + </div> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_munderover"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-001.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-001.html new file mode 100644 index 0000000000..6b0f99ec11 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-001.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Horizontal stretchy operator</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dfn-algorithm-for-stretching-operators-along-the-inline-axis"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-operators"> +<link rel="match" href="underover-stretchy-001-ref.html"/> +<meta name="assert" content="Verify visual rendering of padding/border/margin on an operator, stretchy along the inline axis."> +<script src="/mathml/support/feature-detection.js"></script> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/stretchy.woff"); + } + math, mo { + font-family: TestFont; + font-size: 50px; + } +</style> +<body> + <p>This test passes if you see green rectangles and no red.</p> + <!-- The red mspace elements below are expected to be covered by the green + stretchy mo elements. --> + + <div style="position: absolute; left: 3em; top; 3em; + width: 1000px; height: 500px; background: lightgreen;"> + + <div style="position: absolute; top: 1px; left: 1px;"> + <!-- stretchy base in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 251px;"> + <!-- stretchy script in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munder> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 1px;"> + <!-- stretchy base in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 251px;"> + <!-- stretchy script in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </mover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 1px;"> + <!-- stretchy base in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 251px;"> + <!-- stretchy underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 1px;"> + <!-- stretchy overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 501px;"> + <!-- stretchy base and underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 151px; left: 501px;"> + <!-- stretchy base and overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 501px;"> + <!-- stretchy scripts in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 751px;"> + <!-- Only stretchy operators in munderover. The widest unstretched size + is used as the target size. --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="198px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="98px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="font-size: 1em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 4em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 2em; color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + </div> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_munderover"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-002-ref.html new file mode 100644 index 0000000000..c12c74d654 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-002-ref.html @@ -0,0 +1,167 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Horizontal stretchy operator, embellished with two nested mrows (reference)</title> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/stretchy.woff"); + } + math, mo { + font-family: TestFont; + font-size: 50px; + } +</style> +<body> + <p>This test passes if you see green rectangles and no red.</p> + + <div style="position: absolute; left: 3em; top; 3em; + width: 1000px; height: 500px; background: lightgreen;"> + + <div style="position: absolute; top: 1px; left: 1px;"> + <!-- stretchy base in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 251px;"> + <!-- stretchy script in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 1px;"> + <!-- stretchy base in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 251px;"> + <!-- stretchy script in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 1px;"> + <!-- stretchy base in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 251px;"> + <!-- stretchy underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 1px;"> + <!-- stretchy overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 501px;"> + <!-- stretchy base and underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 151px; left: 501px;"> + <!-- stretchy base and overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 501px;"> + <!-- stretchy scripts in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 751px;"> + <!-- Only stretchy operators in munderover. The widest unstretched size + is used as the target size. --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="font-size: 1em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 4em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 2em; color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + </div> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_munderover"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-002.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-002.html new file mode 100644 index 0000000000..a1cfa20bb4 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-002.html @@ -0,0 +1,272 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Horizontal stretchy operator, embellished with two nested mrows</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dfn-algorithm-for-stretching-operators-along-the-inline-axis"> +<link rel="help" href="https://w3c.github.io/mathml-core/#algorithm-for-stretching-operators-along-the-block-axis"> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-operators"> +<link rel="match" href="underover-stretchy-002-ref.html"/> +<meta name="assert" content="Verify visual rendering of padding/border/margin on an embellished operator, stretchy along the inline axis."> +<script src="/mathml/support/feature-detection.js"></script> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/stretchy.woff"); + } + math, mo { + font-family: TestFont; + font-size: 50px; + } +</style> +<body> + <p>This test passes if you see green rectangles and no red.</p> + <!-- The red mspace elements below are expected to be covered by the green + stretchy mo elements. --> + + <div style="position: absolute; left: 3em; top; 3em; + width: 1000px; height: 500px; background: lightgreen;"> + + <div style="position: absolute; top: 1px; left: 1px;"> + <!-- stretchy base in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 251px;"> + <!-- stretchy script in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munder> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 1px;"> + <!-- stretchy base in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 251px;"> + <!-- stretchy script in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </mover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 1px;"> + <!-- stretchy base in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 251px;"> + <!-- stretchy underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 1px;"> + <!-- stretchy overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 501px;"> + <!-- stretchy base and underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + <mspace width="200px" height="0px"/> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 151px; left: 501px;"> + <!-- stretchy base and overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + <mspace width="200px" height="0px"/> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 501px;"> + <!-- stretchy scripts in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + <mrow><mrow><mo lspace="0" rspace="0" style="color: green;">⥚</mo></mrow></mrow> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 751px;"> + <!-- Only stretchy operators in munderover. The widest unstretched size + is used as the target size. --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="198px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="98px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="font-size: 1em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 4em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 2em; color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + </div> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_munderover"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-003-ref.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-003-ref.html new file mode 100644 index 0000000000..02c7ce2efb --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-003-ref.html @@ -0,0 +1,167 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Horizontal stretchy operator, embellished with an munderover (reference)</title> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/stretchy.woff"); + } + math, mo { + font-family: TestFont; + font-size: 50px; + } +</style> +<body> + <p>This test passes if you see green rectangles and no red.</p> + + <div style="position: absolute; left: 3em; top; 3em; + width: 1000px; height: 500px; background: lightgreen;"> + + <div style="position: absolute; top: 1px; left: 1px;"> + <!-- stretchy base in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 251px;"> + <!-- stretchy script in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 1px;"> + <!-- stretchy base in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 251px;"> + <!-- stretchy script in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 1px;"> + <!-- stretchy base in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 251px;"> + <!-- stretchy underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 1px;"> + <!-- stretchy overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 501px;"> + <!-- stretchy base and underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 151px; left: 501px;"> + <!-- stretchy base and overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 501px;"> + <!-- stretchy scripts in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 751px;"> + <!-- Only stretchy operators in munderover. The widest unstretched size + is used as the target size. --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="font-size: 1em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 4em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 2em; color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + </div> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_munderover"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-003.html b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-003.html new file mode 100644 index 0000000000..735fcab63e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/scripts/underover-stretchy-003.html @@ -0,0 +1,272 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Horizontal stretchy operator, embellished with an munderover</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dfn-algorithm-for-stretching-operators-along-the-inline-axis"> +<link rel="help" href="https://w3c.github.io/mathml-core/#algorithm-for-stretching-operators-along-the-block-axis"> +<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-operators"> +<link rel="match" href="underover-stretchy-003-ref.html"/> +<meta name="assert" content="Verify visual rendering of padding/border/margin on an embellished operator, stretchy along the inline axis."> +<script src="/mathml/support/feature-detection.js"></script> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/stretchy.woff"); + } + math, mo { + font-family: TestFont; + font-size: 50px; + } +</style> +<body> + <p>This test passes if you see green rectangles and no red.</p> + <!-- The red mspace elements below are expected to be covered by the green + stretchy mo elements. --> + + <div style="position: absolute; left: 3em; top; 3em; + width: 1000px; height: 500px; background: lightgreen;"> + + <div style="position: absolute; top: 1px; left: 1px;"> + <!-- stretchy base in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + <mspace width="200px" height="0px"/> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 251px;"> + <!-- stretchy script in munder --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munder> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munder> + <mspace width="200px" height="0px"/> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + </munder> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 1px;"> + <!-- stretchy base in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + <mspace width="200px" height="0px"/> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 101px; left: 251px;"> + <!-- stretchy script in mover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </mover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <mover> + <mspace width="200px" height="0px"/> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + </mover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 1px;"> + <!-- stretchy base in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 201px; left: 251px;"> + <!-- stretchy underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + <mspace width="200px" height="0px"/> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 1px;"> + <!-- stretchy overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="200px" height="0px"/> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 501px;"> + <!-- stretchy base and underscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + <mspace width="200px" height="0px"/> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 151px; left: 501px;"> + <!-- stretchy base and overscript in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + <mspace width="200px" height="0px"/> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 301px; left: 501px;"> + <!-- stretchy scripts in munderover --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="200px" height="0px"/> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + <munderover><mo lspace="0" rspace="0" style="color: green;">⥚</mo><mspace/><mspace/></munderover> + </munderover> + </math> + </div> + </div> + + <div style="position: absolute; top: 1px; left: 751px;"> + <!-- Only stretchy operators in munderover. The widest unstretched size + is used as the target size. --> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mspace width="198px" height="48px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="198px" style="background: red; margin: 1px;"/> + <mspace width="198px" height="98px" style="background: red; margin: 1px;"/> + </munderover> + </math> + </div> + <div style="position: absolute; left: 0; top: 0;"> + <math> + <munderover> + <mo lspace="0" rspace="0" style="font-size: 1em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 4em; color: green;">⥚</mo> + <mo lspace="0" rspace="0" style="font-size: 2em; color: green;">⥚</mo> + </munderover> + </math> + </div> + </div> + </div> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_munderover"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-children-ref.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-children-ref.html new file mode 100644 index 0000000000..ae74024c2f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-children-ref.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>space (reference)</title> +</head> +<body> + <p>Test passes if you see a green square and no text.</p> + <math><mspace width="200px" height="200px" style="background: green"></mspace></math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-children.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-children.html new file mode 100644 index 0000000000..8520f83d24 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-children.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<head> +<meta charset="utf-8"> +<title>space</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<link rel="match" href="mspace-children-ref.html"/> +<meta name="assert" content="Verify mspace visual rendering of its children"> +</head> +<body> + <p>Test passes if you see a green square and no text.</p> + <math><mspace width="200px" height="200px" style="background: green">Text Node <mtext>x</mtext></mspace></math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-percentage-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-percentage-001-ref.html new file mode 100644 index 0000000000..da4f1dd397 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-percentage-001-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mspace percentages (reference)</title> + <style> + .red { + background: red; + } + </style> + </head> + <body> + <p>This test passes if there is a green square with no red.</p> + <math display="block" + style="width: 200px; height: 200px; background: green"> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-percentage-001.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-percentage-001.html new file mode 100644 index 0000000000..758429e1db --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-percentage-001.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>mspace percentages</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> + <meta name="assert" content="Verify that percentage values for mspace do not use refer to the containing block"> + <link rel="match" href="mspace-percentage-001-ref.html"> + <style> + .red { + background: red; + } + </style> + </head> + <body> + <p>This test passes if there is a green square with no red.</p> + <math display="block" + style="width: 200px; height: 200px; background: green"> + <mspace width="5%" height="10px" class="red"></mspace> + <mspace width=" 5%" height="10px" class="red"></mspace> + <mspace width="5% " height="10px" class="red"></mspace> + <mspace width="10px" height="5%" class="red"></mspace> + <mspace width="10px" height=" 5%" class="red"></mspace> + <mspace width="10px" height="5% " class="red"></mspace> + <mspace width="10px" depth="5%" class="red"></mspace> + <mspace width="10px" depth=" 5%" class="red"></mspace> + <mspace width="10px" depth="5% " class="red"></mspace> + <mspace width="10px" height="5%" depth="5%" class="red"></mspace> + <mspace width="10px" height=" 5%" depth=" 5%" class="red"></mspace> + <mspace width="10px" height="5% " depth="5% " class="red"></mspace> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-width-height-001.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-width-height-001.html new file mode 100644 index 0000000000..52b3eaa190 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/mspace-width-height-001.html @@ -0,0 +1,113 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Space</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<meta name="assert" content="Verify mspace metrics for different values of height, depth and width"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function getMetrics(aId) { + let baseline = document.getElementById("baseline").getBoundingClientRect(); + let mspace = document.getElementById(aId).getBoundingClientRect(); + return { + width: mspace.width, + height: mspace.height, + line_ascent: (baseline.top + baseline.bottom)/2 - mspace.top + }; + } + + function runTests() { + test(function() { + let metrics = getMetrics("widthAttributePlusWidthProperty"); + assert_approx_equals(metrics.width, 200, epsilon, + "mspace width overridden by inline style"); + assert_approx_equals(metrics.height, 200, epsilon, + "mspace height as specified by height attribute"); + assert_approx_equals(metrics.line_ascent, 200, epsilon, + "mspace line-ascent as specified by height attribute"); + }, "width attribute + width property"); + + test(function() { + let metrics = getMetrics("heightAndDepthAttributesPlusHeightProperty"); + assert_approx_equals(metrics.width, 200, epsilon, + "mspace width as specified by attribute"); + assert_approx_equals(metrics.height, 200, epsilon, + "mspace height overridden by inline style"); + assert_approx_equals(metrics.line_ascent, 100, epsilon, + "mspace line-ascent as specified by height attribute"); + }, "height/depth attributes + height property"); + + test(function() { + let metrics = getMetrics("heightAttributePlusHeightProperty"); + assert_approx_equals(metrics.width, 200, epsilon, + "mspace width as specified by attribute"); + assert_approx_equals(metrics.height, 200, epsilon, + "mspace height overridden by inline style"); + assert_approx_equals(metrics.line_ascent, 300, epsilon, + "mspace line-ascent as specified by height attribute"); + }, "height attribute + height property"); + + test(function() { + let metrics = getMetrics("depthAttributePlusHeightProperty"); + assert_approx_equals(metrics.width, 200, epsilon, + "mspace width as specified by attribute"); + assert_approx_equals(metrics.height, 200, epsilon, + "mspace height overridden by inline style"); + assert_approx_equals(metrics.line_ascent, 0, epsilon, + "mspace line-ascent defaults to 0"); + }, "depth attribute + height property"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + + <math> + <!-- Reference baseline --> + <mspace id="baseline" style="background: black" + width="10px" height="100px" depth="100px"/> + + <!-- width="500px" is a presentational hint + setting the element's width property to the corresponding value, + overridden by the inline style width: 200px. + height="200px" sets the height/line-ascent to 200px. --> + <mspace id="widthAttributePlusWidthProperty" + width="500px" height="200px" + style="width: 200px; background: green"/> + + <!-- height="100px" + depth="200px" are used as a presentational hint + setting the element's height property to calc(100px + 200px), + overridden by inline style height: 200px. + height="100px" sets the line-ascent to 100px. --> + <mspace id="heightAndDepthAttributesPlusHeightProperty" + width="200px" height="100px" depth="200px" + style="height: 200px; background: blue"/> + + <!-- height="300px" is used as a presentational hint + setting the element's height property to the corresponding value, + overridden by inline style height: 200px. + height="300px" sets the line-ascent to 300px. --> + <mspace id="heightAttributePlusHeightProperty" + width="200px" height="300px" + style="height: 200px; background: magenta"/> + + <!-- depth="300px" is used as a presentational hint + setting the element's height property to the corresponding value, + overridden by inline style height: 200px. + The line-ascent defaults to 0. --> + <mspace id="depthAttributePlusHeightProperty" + width="200px" depth="300px" + style="height: 200px; background: yellow"/> + </math> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-1.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-1.html new file mode 100644 index 0000000000..4cb2a58a3c --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-1.html @@ -0,0 +1,150 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Space</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<meta name="assert" content="Verify mspace metrics for different values of height, depth and width"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + var epsilon = 1; + function getBox(aId) { + var box = document.getElementById(aId).getBoundingClientRect(); + box.middle = (box.bottom + box.top) / 2; + box.center = (box.left + box.right) / 2; + return box; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + test(function() { + var empty = getBox("empty"); + assert_equals(empty.width, 0, "zero width"); + assert_approx_equals(getBox("baseline").bottom - empty.top, 0, epsilon, "zero depth"); + assert_approx_equals(empty.bottom - getBox("baseline").bottom, 0, epsilon, "zero depth"); + }, "Empty mspace"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var space = getBox("width" + i); + assert_approx_equals(space.width, 25*(i+1), epsilon, "width " + i); + assert_approx_equals(getBox("baseline").bottom - space.top, 0, epsilon, "height" + i); + assert_approx_equals(space.bottom - getBox("baseline").bottom, 0, epsilon, "depth" + i); + } + }, "Different widths"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var space = getBox("height" + i); + assert_equals(space.width, 0, "width" + i); + assert_approx_equals(getBox("baseline").bottom - space.top, 25*(i+1), epsilon, "height" + i); + assert_approx_equals(space.bottom - getBox("baseline").bottom, 0, epsilon, "depth" + i); + } + }, "Different heights"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var space = getBox("depth" + i); + assert_equals(space.width, 0, "width" + i); + assert_approx_equals(getBox("baseline").bottom - space.top, 0, epsilon, "height" + i); + assert_approx_equals(space.bottom - getBox("baseline").bottom, 25*(i+1), epsilon, "depth" + i); + } + }, "Different depths"); + + test(function() { + for (var i = 0; i <= 2; i++) { + var space = getBox("mspace" + i); + assert_approx_equals(space.width, 25*(1+i%3), epsilon, "width" + i); + assert_approx_equals(getBox("baseline").bottom - space.top, 25*(1+(i+1)%3), epsilon, "height" + i); + assert_approx_equals(space.bottom - getBox("baseline").bottom, 25*(1+(i+2)%3), epsilon, "depth" + i); + } + }, "Various combinations of height, depth and width."); + + test(function() { + var container = document.getElementById("containerForPreferredWidth"); + var mspace = container.getElementsByTagName("mspace")[0]; + var containerWidth = container.getBoundingClientRect().width; + var mspaceWidth = mspace.getBoundingClientRect().width; + assert_approx_equals(containerWidth, mspaceWidth, epsilon); + }, "Preferred width"); + + // Dynamically set attributes. + ["width", "height", "depth"].forEach(function (name, index) { + document.getElementById("dynamic-remove").removeAttribute(name); + let length = `${50 + index * 10}px`; + document.getElementById("dynamic-attach").setAttribute(name, length); + document.getElementById("dynamic-modify").setAttribute(name, length); + }); + let baseline = getBox("baseline2").bottom; + + test(function() { + let remove = getBox("dynamic-remove"); + assert_approx_equals(remove.width, 0, epsilon); + assert_approx_equals(remove.height, 0, epsilon); + assert_approx_equals(remove.top, baseline, epsilon); + }, "dynamic attributes (remove)"); + + test(function() { + let attach = getBox("dynamic-attach"); + assert_approx_equals(attach.width, 50, epsilon); + assert_approx_equals(attach.height, 60 + 70, epsilon); + assert_approx_equals(baseline - attach.top, 60, epsilon); + }, "dynamic attributes (attach)"); + + test(function() { + let modify = getBox("dynamic-modify"); + assert_approx_equals(modify.width, 50, epsilon); + assert_approx_equals(modify.height, 60 + 70, epsilon); + assert_approx_equals(baseline - modify.top, 60, epsilon); + }, "dynamic attributes (modify)"); + + done(); + } +</script> +<style> +div.shrink-wrap { + background: yellow; + display: inline-block; + margin-top: 5px; + padding-top: 5px; +} +</style> +</head> +<body> + <div id="log"></div> + <p> + <span id="baseline" style="display: inline-block; width: 30px; height: 5px; background: blue"></span> + <math> + <mspace id="empty"/> + <mspace id="width0" width="25px"/> + <mspace id="width1" width="50px"/> + <mspace id="width2" width="75px"/> + <mspace id="height0" height="25px"/> + <mspace id="height1" height="50px"/> + <mspace id="height2" height="75px"/> + <mspace id="depth0" depth="25px"/> + <mspace id="depth1" depth="50px"/> + <mspace id="depth2" depth="75px"/> + <mspace id="mspace0" width="25px" height="50px" depth="75px" style="background: green"/> + <mspace id="mspace1" width="50px" height="75px" depth="25px" style="background: blue"/> + <mspace id="mspace2" width="75px" height="25px" depth="50px" style="background: green"/> + </math> + </p> + <div> + <div id="containerForPreferredWidth" class="shrink-wrap"> + <math><mspace width="75px" height="25px" depth="50px" style="background: green"/></math> + </div> + </div> + <p> + <span id="baseline2" style="display: inline-block; width: 30px; height: 5px; background: blue"></span> + <math> + <mspace id="dynamic-attach" style="background: lightgreen"/> + <mspace id="dynamic-remove" width="10px" height="20px" depth="30px" style="background: lightyellow"/> + <mspace id="dynamic-modify" width="100px" height="200px" depth="300px" style="background: pink"/> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-2-ref.html new file mode 100644 index 0000000000..5a8b39e189 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-2-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>space (reference)</title> +</head> +<body> + <p>Test passes if you see a green square and no red.</p> + <div style="position: relative;"> + <div style="position: absolute; top: 0px; left: 0px; + background: green; width: 200px; height: 200px;"> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-2.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-2.html new file mode 100644 index 0000000000..640afb204f --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-2.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>space</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<link rel="match" href="space-2-ref.html"/> +<meta name="assert" content="Verify mspace visual rendering for different values of height, depth and width"> +</head> +<body> + <p>Test passes if you see a green square and no red.</p> + <div style="position: relative;"> + <!-- Some green and red mspaces to draw a square --> + <div style="position: absolute; top: 0px; left: 0px; + width: 200px; height: 200px;"> + <math style="position: absolute; top: 0px; left: 0px"> + <mspace width="50px" height="100px" depth="100px" style="background: green"/> + <mspace width="50px" height="100px" depth="100px" style="background: green"/> + <mspace width="25px" depth="100px" style="background: green"/> + <mspace width="25px" depth="100px" style="background: green"/> + <mspace width="25px" height="100px" style="background: green"/> + <mspace width="25px" height="100px" style="background: green"/> + </math> + <math style="position: absolute; top: 0px; left: 0px"> + <mspace width="100px" height="20px" depth="20px" style="background: red"/> + <mspace width="50px" height="100px" style="background: red"/> + <mspace width="50px" depth="100px" style="background: red"/> + </math> + </div> + <!-- These green divs should cover the red mspace elements --> + <div style="position: absolute; top: 0px; left: 0px; + width: 200px; height: 200px;"> + <div style="position: absolute; top: 80px; left: 0px; + width: 100px; height: 40px; background: green"></div> + <div style="position: absolute; top: 0px; left: 100px; + width: 50px; height: 100px; background: green"></div> + <div style="position: absolute; top: 100px; left: 150px; + width: 50px; height: 100px; background: green"></div> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-001.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-001.html new file mode 100644 index 0000000000..60e81095ad --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-001.html @@ -0,0 +1,340 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Space-like elements</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<meta name="assert" content="Verify definition of space-like elements"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<style> + /* Default spacing of operator 'X' is 0.2777777777777778em so quite different + from the measured/specified 0em and 1em. */ + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + mo { + color: yellow; + } + .testedElement, .testedElement * { + color: blue !important; + background: blue !important; + } +</style> +<script> + function spaceBefore(id) { + var element = document.getElementById(id); + var mnBeforeParent = element.parentNode.previousElementSibling; + return element.getBoundingClientRect().left - mnBeforeParent.getBoundingClientRect().right; + } + + function spaceAfter(id) { + var element = document.getElementById(id); + var mnAfterParent = element.parentNode.nextElementSibling; + return mnAfterParent.getBoundingClientRect().left - element.getBoundingClientRect().right; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mtext"), emToPx, epsilon); + assert_approx_equals(spaceAfter("mtext"), emToPx, epsilon); + }, "mtext is space-like"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mspace"), emToPx, epsilon); + assert_approx_equals(spaceAfter("mspace"), emToPx, epsilon); + }, "mspace is space-like"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mrow1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("mrow1"), emToPx, epsilon); + }, "space-like mrow"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mrow2"), 0, epsilon); + assert_approx_equals(spaceAfter("mrow2"), 2 * emToPx, epsilon); + }, "non-space-like mrow"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mstyle1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("mstyle1"), emToPx, epsilon); + }, "space-like mstyle"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mstyle2"), 0, epsilon); + assert_approx_equals(spaceAfter("mstyle2"), 2 * emToPx, epsilon); + }, "non-space-like mstyle"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mphantom1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("mphantom1"), emToPx, epsilon); + }, "space-like mphantom"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mphantom2"), 0, epsilon); + assert_approx_equals(spaceAfter("mphantom2"), 2 * emToPx, epsilon); + }, "non-space-like mphantom"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mpadded1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("mpadded1"), emToPx, epsilon); + }, "space-like mpadded"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("mpadded2"), 0, epsilon); + assert_approx_equals(spaceAfter("mpadded2"), 2 * emToPx, epsilon); + }, "non-space-like mpadded"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("merror1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("merror1"), emToPx, epsilon); + }, "space-like merror"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("merror2"), 0, epsilon); + assert_approx_equals(spaceAfter("merror2"), 2 * emToPx, epsilon); + }, "non-space-like merror"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("menclose1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("menclose1"), emToPx, epsilon); + }, "space-like menclose"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("menclose2"), 0, epsilon); + assert_approx_equals(spaceAfter("menclose2"), 2 * emToPx, epsilon); + }, "non-space-like menclose"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mtext is space-like. --> + <mtext class="testedElement" id="mtext">X</mtext> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mspace is space-like. --> + <mspace class="testedElement" id="mspace" width="25px" height="10px"></mspace> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mrow is space-like when it contains only space-like elements. --> + <mrow id="mrow1" class="testedElement"> + <mtext>X</mtext> + <mspace width="25px" height="10px"></mspace> + </mrow> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mrow is not space-like when it contains a non space-like element + such as "mn". --> + <mrow id="mrow2" class="testedElement"> + <mn>X</mn> + <mspace width="25px" height="10px"></mspace> + </mrow> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mstyle is space-like when it contains only space-like elements. --> + <mstyle id="mstyle1" class="testedElement"> + <mtext>X</mtext> + <mspace width="25px" height="10px"></mspace> + </mstyle> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mstyle is not space-like when it contains a non space-like element + such as "mn". --> + <mstyle id="mstyle2" class="testedElement"> + <mn>X</mn> + <mspace width="25px" height="10px"></mspace> + </mstyle> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mphantom is space-like when it contains only space-like elements. + --> + <mphantom id="mphantom1" class="testedElement"> + <mtext>X</mtext> + <mspace width="25px" height="10px"></mspace> + </mphantom> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mphantom is not space-like when it contains a non space-like + element such as "mn". --> + <mphantom id="mphantom2" class="testedElement"> + <mn>X</mn> + <mspace width="25px" height="10px"></mspace> + </mphantom> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mpadded is space-like when it contains only space-like elements. --> + <mpadded id="mpadded1" class="testedElement"> + <mtext>X</mtext> + <mspace width="25px" height="10px"></mspace> + </mpadded> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- mpadded is not space-like when it contains a non space-like element + such as "mn". --> + <mpadded id="mpadded2" class="testedElement"> + <mn>X</mn> + <mspace width="25px" height="10px"></mspace> + </mpadded> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- merror is space-like when it contains only space-like elements. --> + <merror id="merror1" class="testedElement"> + <mtext>X</mtext> + <mspace width="25px" height="10px"></mspace> + </merror> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- merror is not space-like when it contains a non space-like element + such as "mn". --> + <merror id="merror2" class="testedElement"> + <mn>X</mn> + <mspace width="25px" height="10px"></mspace> + </merror> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- menclose is space-like when it contains only space-like + elements. --> + <menclose id="menclose1" class="testedElement"> + <mtext>X</mtext> + <mspace width="25px" height="10px"></mspace> + </menclose> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- menclose is not space-like when it contains a non space-like + element such as "mn". --> + <menclose id="menclose2" class="testedElement"> + <mn>X</mn> + <mspace width="25px" height="10px"></mspace> + </menclose> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-002.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-002.html new file mode 100644 index 0000000000..fba92adf23 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-002.html @@ -0,0 +1,174 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Space-like elements</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<meta name="assert" content="Verify definition of space-like elements"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<style> + /* Default spacing of operator 'X' is 0.2777777777777778em so quite different + from the measured/specified 0em and 1em. */ + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + mo { + color: yellow; + } + .testedElement, .testedElement * { + color: blue !important; + background: blue !important; + } +</style> +<script> + function spaceBefore(id) { + var element = document.getElementById(id); + var mnBeforeParent = element.parentNode.previousElementSibling; + return element.getBoundingClientRect().left - mnBeforeParent.getBoundingClientRect().right; + } + + function spaceAfter(id) { + var element = document.getElementById(id); + var mnAfterParent = element.parentNode.nextElementSibling; + return mnAfterParent.getBoundingClientRect().left - element.getBoundingClientRect().right; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("maction1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("maction1"), emToPx, epsilon); + }, "space-like maction"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("maction2"), emToPx, epsilon); + assert_approx_equals(spaceAfter("maction2"), emToPx, epsilon); + }, "space-like maction (no first child)"); + + test(function() { + assert_approx_equals(spaceBefore("maction3"), 0, epsilon); + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceAfter("maction3"), 2 * emToPx, epsilon); + }, "non-space like maction (first child not space-like)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("semantics1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("semantics1"), emToPx, epsilon); + }, "space-like semantics"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("semantics2"), emToPx, epsilon); + assert_approx_equals(spaceAfter("semantics2"), emToPx, epsilon); + }, "space-like semantics (no first child)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("semantics3"), 0, epsilon); + assert_approx_equals(spaceAfter("semantics3"), 2 * emToPx, epsilon); + }, "non-space like semantics (first child not space-like)"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- maction is space-like when its first child exists and is space-like --> + <maction id="maction1" class="testedElement" actiontype="statusline"> + <mtext>X</mtext> + <mtext>STATUS MESSAGE</mtext> + </maction> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- maction is not space-like when its first does not exist-like --> + <maction id="maction2" class="testedElement" actiontype="statusline"> + </maction> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- maction is not space-like when its first is not space-like --> + <maction id="maction3" class="testedElement" actiontype="statusline"> + <mn>1</mn> + <mtext>STATUS MESSAGE</mtext> + </maction> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- semantics is space-like when its first child exists and is space-like --> + <semantics id="semantics1" class="testedElement" actiontype="statusline"> + <mtext>X</mtext> + <annotation>TEXT ANNOTATION</annotation> + </semantics> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- semantics is not space-like when its first does not exist-like --> + <semantics id="semantics2" class="testedElement" actiontype="statusline"> + </semantics> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- semantics is not space-like when its first is not space-like --> + <semantics id="semantics3" class="testedElement" actiontype="statusline"> + <mn>1</mn> + <annotation>TEXT ANNOTATION</annotation> + </semantics> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-003.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-003.html new file mode 100644 index 0000000000..5b693fb3c9 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-003.html @@ -0,0 +1,252 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Non space-like elements</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<meta name="assert" content="Verify definition of space-like elements"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<style> + /* Default spacing of operator 'X' is 0.2777777777777778em so quite different + from the measured/specified 0em and 1em. */ + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + mo { + color: yellow; + } + .testedElement, .testedElement * { + color: blue !important; + background: blue !important; + } +</style> +<script> + function spaceBefore(element) { + var mnBeforeParent = element.parentNode.previousElementSibling; + return element.getBoundingClientRect().left - mnBeforeParent.getBoundingClientRect().right; + } + + function spaceAfter(element) { + var mnAfterParent = element.parentNode.nextElementSibling; + return mnAfterParent.getBoundingClientRect().left - element.getBoundingClientRect().right; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + + Array.from(document.querySelectorAll(".testedElement")).forEach(el => { + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore(el), 0, epsilon); + assert_approx_equals(spaceAfter(el), 2 * emToPx, epsilon); + }, `${el.tagName} is not space-like`); + }); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mn>X</mn> + <mrow> + <mroot class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + </mroot> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <mfrac class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <mi class="testedElement">X</mi> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <mmultiscripts class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mmultiscripts> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <mn class="testedElement">X</mn> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <mo class="testedElement" lspace="0" rspace="0">X</mo> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <mover class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + </mover> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <munder class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + </munder> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <ms class="testedElement">X</ms> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <munderover class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <msup class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + </msup> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <msub class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + </msub> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <msubsup class="testedElement"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </msubsup> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <msqrt class="testedElement"> + <mtext>X</mtext> + </msqrt> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <mtable class="testedElement"> + <mtr> + <mtd> + <mtext>X</mtext> + </mtd> + </mtr> + </mtable> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-004.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-004.html new file mode 100644 index 0000000000..1e8cfaaaca --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-like-004.html @@ -0,0 +1,446 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Space-like elements</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<meta name="assert" content="Verify definition of space-like elements"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/box-navigation.js"></script> +<style> + /* Default spacing of operator 'X' is 0.2777777777777778em so quite different + from the measured/specified 0em and 1em. */ + math, math * { + font: 25px/1 Ahem; + } + mn { + color: black; + } + mo { + color: yellow; + } + .testedElement, .testedElement * { + color: blue !important; + background: blue !important; + } + .oof1 { + position: absolute; + } + .oof2 { + position: fixed; + } + .nobox { + display: none; + } +</style> +<script> + function spaceBefore(id) { + var element = document.getElementById(id); + var mnBeforeParent = previousInFlowSibling(element.parentNode); + return element.getBoundingClientRect().left - mnBeforeParent.getBoundingClientRect().right; + } + + function spaceAfter(id) { + var element = document.getElementById(id); + var mnAfterParent = nextInFlowSibling(element.parentNode); + return mnAfterParent.getBoundingClientRect().left - element.getBoundingClientRect().right; + } + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + var epsilon = 1; + var emToPx = 25; + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("complex1"), emToPx, epsilon); + assert_approx_equals(spaceAfter("complex1"), emToPx, epsilon); + }, "complex space-like subtree"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("complex1-bis"), emToPx, epsilon); + assert_approx_equals(spaceAfter("complex1-bis"), emToPx, epsilon); + }, "complex space-like subtree, from in-flow children"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("complex2"), 0, epsilon); + assert_approx_equals(spaceAfter("complex2"), 2 * emToPx, epsilon); + }, "complex non-space-like subtree"); + + test(function() { + assert_true(MathMLFeatureDetection.has_operator_spacing()); + assert_approx_equals(spaceBefore("complex2-bis"), 0, epsilon); + assert_approx_equals(spaceAfter("complex2-bis"), 2 * emToPx, epsilon); + }, "complex non-space-like subtree, from in-flow children"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- This element is space-like because it is made of nested + mrow, mstyle, mpadded, mphantom, mtext, mspace + --> + <mrow class="testedElement" id="complex1"> + <mtext>X</mtext> + <mstyle> + <mstyle> + <mtext>X</mtext> + <mtext>X</mtext> + </mstyle> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mpadded> + <mtext>X</mtext> + <mrow></mrow> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mphantom> + <mtext>X</mtext> + <mspace width="25px"></mspace> + </mphantom> + <mrow> + <mtext>X</mtext> + <mtext>X</mtext> + </mrow> + <mspace width="25px"></mspace> + </mpadded> + <mspace width="25px"></mspace> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mpadded> + <mphantom> + <mtext>X</mtext> + <mspace width="25px"></mspace> + </mphantom> + <mtext>X</mtext> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mtext>X</mtext> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mphantom> + <mtext>X</mtext> + <mspace width="25px"></mspace> + </mphantom> + <mtext>X</mtext> + <mtext>X</mtext> + <mspace width="25px"></mspace> + </mpadded> + </mstyle> + <mspace width="25px"></mspace> + </mrow> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mrow> + <!-- This element is space-like because it is made of nested + mrow, mstyle, mpadded, mphantom, mtext, mspace + --> + <mrow class="testedElement" id="complex1-bis"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mrow></mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="1em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> + <p> + <math> + <mn>X</mn> + <mrow> + <!-- This element is not space-like. It is made of nested + mrow, mstyle, mpadded, mphantom, mtext, mspace but contains + one non-space like descendant (an mn element). + --> + <mrow class="testedElement" id="complex2"> + <mtext>X</mtext> + <mstyle> + <mstyle> + <mtext>X</mtext> + <mtext>X</mtext> + </mstyle> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mpadded> + <mtext>X</mtext> + <mrow></mrow> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mphantom> + <mtext>X</mtext> + <mspace width="25px"></mspace> + </mphantom> + <mrow> + <mtext>X</mtext> + <mtext>X</mtext> + </mrow> + <mspace width="25px"></mspace> + </mpadded> + <mspace width="25px"></mspace> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mpadded> + <mphantom> + <mn>X</mn> <!-- mn is not space-like --> + <mspace width="25px"></mspace> + </mphantom> + <mtext>X</mtext> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mtext>X</mtext> + <mtext>X</mtext> + <mspace width="25px"></mspace> + <mphantom> + <mtext>X</mtext> + <mspace width="25px"></mspace> + </mphantom> + <mtext>X</mtext> + <mtext>X</mtext> + <mspace width="25px"></mspace> + </mpadded> + </mstyle> + <mspace width="25px"></mspace> + </mrow> + <mo lspace="1em" rspace="0em">X</mo> + </mrow> + <mn>X</mn> + </math> + </p> + <p> + <math> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mrow> + <!-- This element is not space-like. It is made of nested + mrow, mstyle, mpadded, mphantom, mtext, mspace but contains + one non-space like descendant (an mn element). + --> + <mrow class="testedElement" id="complex2-bis"> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mrow></mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> <!-- mn is not space-like --> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mphantom> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mtext>X</mtext> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mpadded> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mstyle> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mspace width="25px"></mspace> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mo lspace="1em" rspace="0em">X</mo> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </mrow> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + <mn>X</mn> + <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-vertical-align.tentative-ref.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-vertical-align.tentative-ref.html new file mode 100644 index 0000000000..ed30edde96 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-vertical-align.tentative-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>space and vertical-align (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="position: relative;"> + <div style="position: absolute; top: 0px; left: 0px; + background: green; width: 100px; height: 100px;"> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/spaces/space-vertical-align.tentative.html b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-vertical-align.tentative.html new file mode 100644 index 0000000000..359b12aa34 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/spaces/space-vertical-align.tentative.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>space and vertical-align</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<link rel="match" href="space-vertical-align.tentative-ref.html"/> +<meta name="assert" content="Verify that vertical-align property has no effect on mspace"> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="position: relative;"> + <div style="position: absolute; top: 0px; left: 0px; + width: 200px; height: 200px;"> + <math style="position: absolute; top: 0px; left: 0px"> + <mspace width="50px" height="100px" style="background: green;vertical-align:50px"/> + <mspace width="50px" height="100px" style="background: green;vertical-align:50%"/> + </math> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tables/dynamic-table-001.html b/testing/web-platform/tests/mathml/presentation-markup/tables/dynamic-table-001.html new file mode 100644 index 0000000000..a07ef94d27 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tables/dynamic-table-001.html @@ -0,0 +1,301 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Dynamic tabular elements</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<script src="/mathml/support/mathml-fragments.js"></script> +<link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<meta name="assert" content="Dynamically modify DOM tree of mtables"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script> + function forceCells(mtable, rows, cols) { + while (mtable.children.length > rows) + mtable.removeChild(mtable.lastElementChild); + while (mtable.children.length < rows) + mtable.appendChild(FragmentHelper.createElement("mtr")); + for (let i = 0; i < rows; i++) { + let mtr = mtable.children[i]; + while (mtr.children.length > cols) + mtr.removeChild(mtr.lastElementChild); + while (mtr.children.length < cols) + mtr.appendChild(FragmentHelper.createElement("mtd")); + + for (let j = 0; j < cols; j++) { + let mtd = mtr.children[j]; + while (mtd.children.length > 0) + mtd.removeChild(mtd.lastElementChild); + let mspace = FragmentHelper.createElement("mspace"); + mspace.setAttribute("height", `${10*(i+1)}px`); + mspace.setAttribute("width", `${10*(j+1)}px`); + mspace.setAttribute("style", `background: black;`); + mtd.appendChild(mspace); + } + } + } + + setup({ explicit_done: true }); + window.addEventListener("load", function() { + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + let reference = document.getElementById("reference"); + + Array.from(document.querySelectorAll("[data-title]")).forEach(mtable => { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + forceCells(mtable, 4, 3); + const epsilon = 1; + compareLayout(mtable, reference, epsilon); + }, `${mtable.getAttribute("data-title")}`); + }); + done(); + }); +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mtable id="reference"> + <mtr> + <mtd><mspace height="10px" width="10px" style="background: blue;"/></mtd> + <mtd><mspace height="10px" width="20px" style="background: blue;"/></mtd> + <mtd><mspace height="10px" width="30px" style="background: blue;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="20px" width="10px" style="background: blue;"/></mtd> + <mtd><mspace height="20px" width="20px" style="background: blue;"/></mtd> + <mtd><mspace height="20px" width="30px" style="background: blue;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="30px" width="10px" style="background: blue;"/></mtd> + <mtd><mspace height="30px" width="20px" style="background: blue;"/></mtd> + <mtd><mspace height="30px" width="30px" style="background: blue;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="40px" width="10px" style="background: blue;"/></mtd> + <mtd><mspace height="40px" width="20px" style="background: blue;"/></mtd> + <mtd><mspace height="40px" width="30px" style="background: blue;"/></mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Filling an empty mtable element"></mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Filling empty mtr elements"> + <mtr></mtr> + <mtr></mtr> + <mtr></mtr> + <mtr></mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Filling empty mtd elements"> + <mtr> + <mtd></mtd> + <mtd></mtd> + <mtd></mtd> + </mtr> + <mtr> + <mtd></mtd> + <mtd></mtd> + <mtd></mtd> + </mtr> + <mtr> + <mtd></mtd> + <mtd></mtd> + <mtd></mtd> + </mtr> + <mtr> + <mtd></mtd> + <mtd></mtd> + <mtd></mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Filling an empty mtr element"> + <mtr> + <mtd><mspace height="10px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <!-- Empty mtr --> + </mtr> + <mtr> + <mtd><mspace height="30px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="40px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="30px" style="background: black;"/></mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Filling an empty mtd element"> + <mtr> + <mtd><mspace height="10px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="20px" width="10px" style="background: black;"/></mtd> + <mtd><!-- Empty --></mtd> + <mtd><mspace height="20px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="30px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="40px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="30px" style="background: black;"/></mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Adding missing elements"> + <mtr> + <mtd><mspace height="10px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="20px" style="background: black;"/></mtd> + <!-- Cell missing --> + </mtr> + <mtr> + <mtd><mspace height="20px" width="10px" style="background: black;"/></mtd> + <mtd><!-- Empty --></mtd> + <mtd><mspace height="20px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="30px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="30px" style="background: black;"/></mtd> + </mtr> + <!-- Row missing --> + </mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Removing a row"> + <mtr> + <mtd><mspace height="10px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="20px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="20px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="20px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="30px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="40px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="30px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="50px" width="10px" style="background: red;"/></mtd> + <mtd><mspace height="50px" width="20px" style="background: red;"/></mtd> + <mtd><mspace height="50px" width="30px" style="background: red;"/></mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Removing a column"> + <mtr> + <mtd><mspace height="10px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="30px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="40px" style="background: red;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="20px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="20px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="20px" width="30px" style="background: black;"/></mtd> + <mtd><mspace height="20px" width="40px" style="background: red;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="30px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="30px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="40px" style="background: red;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="40px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="30px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="40px" style="background: red;"/></mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable data-title="Removing extra elements"> + <mtr> + <mtd><mspace height="10px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="30px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="40px" style="background: black;"/></mtd> + <mtd><mspace height="10px" width="50px" style="background: red;"/></mtd><!-- extra mtd --> + </mtr> + <mtr> + <mtd><mspace height="20px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="20px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="20px" width="30px" style="background: black;"/></mtd> + <mtd><mspace height="20px" width="40px" style="background: black;"/><mspace height="20px" width="40px" style="background: red;"/><!-- extra child--></mtd> + </mtr> + <mtr> + <mtd><mspace height="30px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="30px" style="background: black;"/></mtd> + <mtd><mspace height="30px" width="40px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="40px" width="10px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="20px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="30px" style="background: black;"/></mtd> + <mtd><mspace height="40px" width="40px" style="background: black;"/></mtd> + </mtr> + <mtr> + <mtd><mspace height="50px" width="10px" style="background: red;"/></mtd> + <mtd><mspace height="50px" width="20px" style="background: red;"/></mtd> + <mtd><mspace height="50px" width="30px" style="background: red;"/></mtd> + <mtd><mspace height="50px" width="40px" style="background: red;"/></mtd> + </mtr> <!-- extra row --> + </mtable> + </math> + </p> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tables/table-001.html b/testing/web-platform/tests/mathml/presentation-markup/tables/table-001.html new file mode 100644 index 0000000000..91e99184df --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tables/table-001.html @@ -0,0 +1,286 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Basic table layout</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable"> +<meta name="assert" content="Verify position of cells in basic 2x2, 4x3 and 3x4 math tables."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() { + Array.from(document.getElementsByTagName("mtable")).forEach(table => { + const id = table.getAttribute("id"); + const rtl = window.getComputedStyle(table).direction === "rtl"; + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + const rows = Array.from(table.getElementsByTagName("mtr")); + for (var j = 0; j < rows.length; j++) { + var cells = Array.from(rows[j].getElementsByTagName("mtd")); + for (var i = 0; i < cells.length - 1; i++) { + var space1 = cells[i].firstElementChild.getBoundingClientRect(); + var space2 = cells[i + 1].firstElementChild.getBoundingClientRect(); + assert_equals(space1.top, space2.top, + `Cells (${i},${j}) and (${i + 1},${j}) should have same vertical position`); + if (rtl) { + assert_greater_than(space1.left, space2.right, + `Cell (${i},${j}) should be on the right of (${i + 1},${j})`); + } else { + assert_less_than(space1.right, space2.left, + `Cell (${i},${j}) should be on the left of (${i + 1},${j})`); + } + } + } + + for (var j = 0; j < rows.length - 1; j++) { + var cells1 = Array.from(rows[j].getElementsByTagName("mtd")); + var cells2 = Array.from(rows[j + 1].getElementsByTagName("mtd")); + for (var i = 0; i < cells1.length; i++) { + var space1 = cells1[i].firstElementChild.getBoundingClientRect(); + var space2 = cells2[i].firstElementChild.getBoundingClientRect(); + assert_equals(space1.left, space2.left, + `Cells (${i},${j}) and (${i},${j + 1}) should have same horizontal position`); + assert_less_than(space1.bottom, space2.top, + `Cell (${i},${j}) should be above (${i},${j + 1})`); + } + } + }, `Layout of ${id}`); + + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mtable id="table-001"> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: lightblue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: lightgreen;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: blue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: green;"></mspace> + </mtd> + </mtr> + </mtable> + <mtable id="table-002"> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: lightblue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: lightgreen;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: cyan;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: purple;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: blue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: green;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: yellow;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: orange;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: black;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: red;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: gray;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: maroon;"></mspace> + </mtd> + </mtr> + </mtable> + <mtable id="table-003"> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: lightblue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: lightgreen;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: cyan;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: blue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: green;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: orange;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: black;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: maroon;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: gray;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: red;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: purple;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: yellow;"></mspace> + </mtd> + + </mtr> + </mtable> + </math> + </p> + <p> + <math dir="rtl"> + <mtable id="table-011"> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: lightblue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: lightgreen;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: blue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: green;"></mspace> + </mtd> + </mtr> + </mtable> + <mtable id="table-012"> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: lightblue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: lightgreen;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: cyan;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: purple;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: blue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: green;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: yellow;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: orange;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: black;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: red;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: gray;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: maroon;"></mspace> + </mtd> + </mtr> + </mtable> + <mtable id="table-013"> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: lightblue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: lightgreen;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: cyan;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: blue;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: green;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: orange;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: black;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: maroon;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: gray;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: red;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: purple;"></mspace> + </mtd> + <mtd> + <mspace width="20px" height="10px" style="background: yellow;"></mspace> + </mtd> + + </mtr> + </mtable> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tables/table-002.html b/testing/web-platform/tests/mathml/presentation-markup/tables/table-002.html new file mode 100644 index 0000000000..b1d75db0c0 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tables/table-002.html @@ -0,0 +1,146 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Basic table alignment</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable"> +<meta name="assert" content="Verify alignment of cells with inline elements in basic 2x2, 4x3 and 3x4 math tables."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() { + var epsilon = 1; + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + const ascents = [40, 0, 20, 30, 10, 80, 0, 40, 70, 30]; + const row = document.getElementById("vertical").firstElementChild; + const cells = Array.from(row.getElementsByTagName("mtd")); + for (var i = 0; i < cells.length - 1; i++) { + var space1 = cells[i].firstElementChild.getBoundingClientRect(); + var space2 = cells[i + 1].firstElementChild.getBoundingClientRect(); + assert_approx_equals(space1.top + ascents[i], + space2.top + ascents[i + 1], + epsilon, + `Baselines of cells ${i} and ${i + 1} should be aligned.`); + } + }, `Vertical alignment of cells`); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + const table = document.getElementById("horizontal"); + const rows = Array.from(table.getElementsByTagName("mtr")); + for (var j = 0; j < rows.length - 1; j++) { + var space1 = rows[j].firstElementChild.firstElementChild.getBoundingClientRect(); + var space2 = rows[j + 1].firstElementChild.firstElementChild.getBoundingClientRect(); + assert_approx_equals((space1.left + space1.right) / 2, + (space2.left + space2.right) / 2, + epsilon, + `Baselines of cells ${j} and ${j + 1} should be aligned.`); + } + }, `Horizontal alignment of cells`); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mtable id="vertical"> + <mtr> + <mtd> + <mspace width="10px" height="40px" depth="0px" style="background: lightblue;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="0px" depth="40px" style="background: lightgreen;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="20px" depth="20px" style="background: cyan;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="30px" depth="10px" style="background: purple;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="10px" depth="30px" style="background: orange;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="80px" depth="0px" style="background: blue;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="0px" depth="80px" style="background: green;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="40px" depth="40px" style="background: yellow;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="70px" depth="30px" style="background: red;"></mspace> + </mtd> + <mtd> + <mspace width="10px" height="30px" depth="70px" style="background: black;"></mspace> + </mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable id="horizontal"> + <mtr> + <mtd> + <mspace width="10px" height="10px" style="background: lightblue;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="40px" height="10px" style="background: lightgreen;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="30px" height="10px" style="background: cyan;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="20px" height="10px" style="background: purple;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="50px" height="10px" style="background: orange;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="100px" height="10px" style="background: blue;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="90px" height="10px" style="background: green;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="70px" height="10px" style="background: yellow;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="80px" height="10px" style="background: red;"></mspace> + </mtd> + </mtr> + <mtr> + <mtd> + <mspace width="40px" height="10px" style="background: black;"></mspace> + </mtd> + </mtr> + </mtable> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tables/table-003.html b/testing/web-platform/tests/mathml/presentation-markup/tables/table-003.html new file mode 100644 index 0000000000..323cb03c8a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tables/table-003.html @@ -0,0 +1,146 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Basic table alignment</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable"> +<meta name="assert" content="Verify alignment of cells with block elements in basic 2x2, 4x3 and 3x4 math tables."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() { + var epsilon = 1; + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + const ascents = [40, 0, 20, 30, 10, 80, 0, 40, 70, 30]; + const row = document.getElementById("vertical").firstElementChild; + const cells = Array.from(row.getElementsByTagName("mtd")); + for (var i = 0; i < cells.length - 1; i++) { + var space1 = cells[i].firstElementChild.firstElementChild.getBoundingClientRect(); + var space2 = cells[i + 1].firstElementChild.firstElementChild.getBoundingClientRect(); + assert_approx_equals(space1.top + ascents[i], + space2.top + ascents[i + 1], + epsilon, + `Baselines of cells ${i} and ${i + 1} should be aligned.`); + } + }, `Vertical alignment of cells`); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + const table = document.getElementById("horizontal"); + const rows = Array.from(table.getElementsByTagName("mtr")); + for (var j = 0; j < rows.length - 1; j++) { + var space1 = rows[j].firstElementChild.firstElementChild.firstElementChild.getBoundingClientRect(); + var space2 = rows[j + 1].firstElementChild.firstElementChild.firstElementChild.getBoundingClientRect(); + assert_approx_equals((space1.left + space1.right) / 2, + (space2.left + space2.right) / 2, + epsilon, + `Baselines of cells ${j} and ${j + 1} should be aligned.`); + } + }, `Horizontal alignment of cells`); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mtable id="vertical"> + <mtr> + <mtd> + <mrow><mspace width="10px" height="40px" depth="0px" style="background: lightblue;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="0px" depth="40px" style="background: lightgreen;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="20px" depth="20px" style="background: cyan;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="30px" depth="10px" style="background: purple;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="10px" depth="30px" style="background: orange;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="80px" depth="0px" style="background: blue;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="0px" depth="80px" style="background: green;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="40px" depth="40px" style="background: yellow;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="70px" depth="30px" style="background: red;"></mspace></mrow> + </mtd> + <mtd> + <mrow><mspace width="10px" height="30px" depth="70px" style="background: black;"></mspace></mrow> + </mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mtable id="horizontal"> + <mtr> + <mtd> + <mrow><mspace width="10px" height="10px" style="background: lightblue;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="40px" height="10px" style="background: lightgreen;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="30px" height="10px" style="background: cyan;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="20px" height="10px" style="background: purple;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="50px" height="10px" style="background: orange;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="100px" height="10px" style="background: blue;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="90px" height="10px" style="background: green;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="70px" height="10px" style="background: yellow;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="80px" height="10px" style="background: red;"></mspace></mrow> + </mtd> + </mtr> + <mtr> + <mtd> + <mrow><mspace width="40px" height="10px" style="background: black;"></mspace></mrow> + </mtd> + </mtr> + </mtable> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tables/table-axis-height.html b/testing/web-platform/tests/mathml/presentation-markup/tables/table-axis-height.html new file mode 100644 index 0000000000..58f9d64c21 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tables/table-axis-height.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>table axis height</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable"> +<meta name="assert" content="Element mtable correctly uses the axis height parameter from the MATH table."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + math, mspace { + font-size: 10px; + } + @font-face { + font-family: axisheight5000-verticalarrow14000; + src: url("/fonts/math/axisheight5000-verticalarrow14000.woff"); + } +</style> +<script> + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 1; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + + var v1 = 5000 * emToPx; + var tableMiddle = (getBox("table").bottom + getBox("table").top) / 2; + assert_approx_equals(getBox("baseline").bottom - tableMiddle, + v1, epsilon, "mtable: axis height"); + }, "AxisHeight"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math style="font-family: axisheight5000-verticalarrow14000"> + <mspace id="baseline" style="background: green" width="50px" height="1px"/> + <mtable id="table" style="background: blue"><mtr><mtd><mspace width="100px" height="1px"/></mtd></mtr></mtable> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tables/table-cell-mrow-layout.html b/testing/web-platform/tests/mathml/presentation-markup/tables/table-cell-mrow-layout.html new file mode 100644 index 0000000000..1e76e3949a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tables/table-cell-mrow-layout.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Table cell mrow layout</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable"> +<meta name="assert" content="Table cell relies on the mrow layout for their children."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<style> + /* Remove default padding, since there is none on reference mrow element. */ + mtd { padding: 0; } +</style> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mtable id="mtable"> + <mtr> + <mtd id="mtd"> + <mspace width="10px" depth="20px" height="20px" style="background: blue"/> + <mspace width="10px" depth="10px" height="30px" style="background: lightblue"/> + <mspace width="10px" depth="30px" height="10px" style="background: black"/> + </mtd> + </mtr> + </mtable> + </math> + </p> + <p> + <math> + <mrow id="mtd-reference"> + <mspace width="10px" depth="20px" height="20px" style="background: blue"/> + <mspace width="10px" depth="10px" height="30px" style="background: lightblue"/> + <mspace width="10px" depth="30px" height="10px" style="background: black"/> + </mrow> + </math> + </p> + <p> + <math> + <mtable id="mtable-reference"> + <mtr> + <mtd> + <mrow> + <mspace width="10px" depth="20px" height="20px" style="background: blue"/> + <mspace width="10px" depth="10px" height="30px" style="background: lightblue"/> + <mspace width="10px" depth="30px" height="10px" style="background: black"/> + </mrow> + </mtd> + </mtr> + </mtable> + </math> + </p> + <script> + const epsilon = 1; + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + let mtd = document.getElementById("mtd"); + let reference = document.getElementById("mtd-reference"); + compareLayout(mtd, reference, epsilon); + }, "<mtd> relies on mrow algorithm to layout its children"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + let mtable = document.getElementById("mtable"); + let reference = document.getElementById("mtable-reference"); + compareLayout(mtable, reference, epsilon); + }, "<mtable> layout does not change if children of <mtd> elements are wrapped in an explicit <mrow>"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tables/table-default-styles-001.html b/testing/web-platform/tests/mathml/presentation-markup/tables/table-default-styles-001.html new file mode 100644 index 0000000000..495cdc000a --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tables/table-default-styles-001.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Tabular math elements default styles</title> +<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com"> +<link rel="help" href="https://w3c.github.io/mathml-core/#tabular-math"> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<meta name="assert" content="Check default styles for mtable, mtr and mtd."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + math { + font: 25px/1 Ahem; + } +</style> +<div id="log"></div> +<div> + <math> + <mrow id="reference"><mspace width="20px" height="10px" style="background: lightblue;"></mrow> + <mtable id="mtable"><mtr id="mtr"><mtd id="mtd"><mspace width="20px" height="10px" style="background: lightblue;"></mtd></mtr></mtable> + </math> +</div> +<script> + test(() => assert_equals(window.getComputedStyle(mtable).mathStyle, "compact"), + "Default math-style value on mtable"); + test(() => assert_equals(window.getComputedStyle(mtable).display, "inline-table"), + "Default display value on mtable"); + test(() => assert_equals(window.getComputedStyle(mtr).display, "table-row"), + "Default display value on mtr"); + test(() => assert_equals(window.getComputedStyle(mtd).display, "table-cell"), + "Default display value on mtd"); + test(() => assert_equals(window.getComputedStyle(mtd).textAlign, "center"), + "Default text-align value on mtd"); + test(() => assert_equals(window.getComputedStyle(mtd).paddingLeft, "10px"), + "Default padding-left value on mtd"); + test(() => assert_equals(window.getComputedStyle(mtd).paddingRight, "10px"), + "Default padding-right value on mtd"); + test(() => assert_equals(window.getComputedStyle(mtd).paddingTop, "10px"), + "Default padding-top value on mtd"); + test(() => assert_equals(window.getComputedStyle(mtd).paddingBottom, "10px"), + "Default padding-bottom value on mtd"); + + test(function () { + var mtableBox = document.getElementById("mtable").getBoundingClientRect(); + var referenceBox = document.getElementById("reference").getBoundingClientRect(); + assert_equals(mtableBox.width, referenceBox.width + 20); + assert_equals(mtableBox.height, referenceBox.height + 20); + }, "Bounding box is the same as mrow + mtd default padding"); +</script> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tokens/dynamic-mtext-like-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/tokens/dynamic-mtext-like-001-ref.html new file mode 100644 index 0000000000..a145a8eb51 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tokens/dynamic-mtext-like-001-ref.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Dynamic mtext-like elements (reference)</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math { + font: 25px/1 Ahem; + background: lightblue; + } + li { + padding: 2px; + } +</style> +</head> +<body> + <ol> + <li><math><mtext class="testedElement">É</mtext></math></li> + <li><math><mtext class="testedElement">pX</mtext></math></li> + <li><math><mtext class="testedElement"><span>Xp</span></mtext></math></li> + <li><math><mi class="testedElement">É</mi></math></li> + <li><math><mi class="testedElement">pX</mi></math></li> + <li><math><mi class="testedElement"><span>Xp</span></mi></math></li> + <li><math><mn class="testedElement">É</mn></math></li> + <li><math><mn class="testedElement">pX</mn></math></li> + <li><math><mn class="testedElement"><span>Xp</span></mn></math></li> + <li><math><mo class="testedElement">É</mo></math></li> + <li><math><mo class="testedElement">pX</mo></math></li> + <li><math><mo class="testedElement"><span>Xp</span></mo></math></li> + <li><math><mo class="testedElement">É</mo></math></li> + <li><math><mo class="testedElement">pX</mo></math></li> + <li><math><mo class="testedElement"><span>Xp</span></mo></math></li> + <li><math><ms class="testedElement">É</ms></math></li> + <li><math><ms class="testedElement">pX</ms></math></li> + <li><math><ms class="testedElement"><span>Xp</span></ms></math></li> + <li><math><annotation class="testedElement">É</annotation></math></li> + <li><math><annotation class="testedElement">pX</annotation></math></li> + <li><math><annotation-xml class="testedElement">É</annotation-xml></math></li> + <li><math><annotation-xml class="testedElement">pX</annotation-xml></math></li> + </ol> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tokens/dynamic-mtext-like-001.html b/testing/web-platform/tests/mathml/presentation-markup/tokens/dynamic-mtext-like-001.html new file mode 100644 index 0000000000..8e42f7fa17 --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tokens/dynamic-mtext-like-001.html @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>Dynamic mtext-like elements</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<script src="/mathml/support/mathml-fragments.js"></script> +<meta name="assert" content="Dynamically set children of mtext-like elements."> +<style> + math { + font: 25px/1 Ahem; + background: lightblue; + } + li { + padding: 2px; + } +</style> +<link rel="match" href="dynamic-mtext-like-001-ref.html"> +<script> + window.addEventListener("load", function() { + + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + Array.from(document.getElementsByClassName("testedElement")).forEach(e => { + if (e.textContent === "") + e.textContent = "É"; + else if (e.textContent === "X") + e.textContent = "pX"; + else if (e.textContent === "p") { + while (e.firstChild) + e.removeChild(e.firstChild); + e.insertAdjacentHTML("beforeend", "<span>Xp</span>") + } + }); + + document.documentElement.classList.remove('reftest-wait'); + }); +</script> +</head> +<body> + <ol> + <li><math><mtext class="testedElement"></mtext></math></li> + <li><math><mtext class="testedElement">X</mtext></math></li> + <li><math><mtext class="testedElement">p</mtext></math></li> + <li><math><mi class="testedElement"></mi></math></li> + <li><math><mi class="testedElement">X</mi></math></li> + <li><math><mi class="testedElement">p</mi></math></li> + <li><math><mn class="testedElement"></mn></math></li> + <li><math><mn class="testedElement">X</mn></math></li> + <li><math><mn class="testedElement">p</mn></math></li> + <li><math><mo class="testedElement"></mo></math></li> + <li><math><mo class="testedElement">X</mo></math></li> + <li><math><mo class="testedElement">p</mo></math></li> + <li><math><mo class="testedElement"></mo></math></li> + <li><math><mo class="testedElement">X</mo></math></li> + <li><math><mo class="testedElement">p</mo></math></li> + <li><math><ms class="testedElement"></ms></math></li> + <li><math><ms class="testedElement">X</ms></math></li> + <li><math><ms class="testedElement">p</ms></math></li> + <!-- HTML parser does not accept span as a child of annotation or + annotation-xml, so we can't test dynamic VS static. --> + <li><math><annotation class="testedElement"></annotation></math></li> + <li><math><annotation class="testedElement">X</annotation></math></li> + <li><math><annotation-xml class="testedElement"></annotation-xml></math></li> + <li><math><annotation-xml class="testedElement">X</annotation-xml></math></li> + </ol> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tokens/ms-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/tokens/ms-001-ref.html new file mode 100644 index 0000000000..bbd42a93ee --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tokens/ms-001-ref.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>ms legacy lquote and rquote attributes (reference)</title> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 25px/1 Ahem; + } + </style> + </head> + <body> + + <p> + <math> + <ms>X</ms> + </math> + </p> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/presentation-markup/tokens/ms-001.html b/testing/web-platform/tests/mathml/presentation-markup/tokens/ms-001.html new file mode 100644 index 0000000000..abac0c8b2e --- /dev/null +++ b/testing/web-platform/tests/mathml/presentation-markup/tokens/ms-001.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>ms legacy lquote and rquote attributes</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#string-literal-ms"> + <meta name="assert" content="Verify that legacy lquote and rquote attributes are ignored on the ms element."> + <link rel="match" href="ms-001-ref.html"> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> + <style> + math { + font: 25px/1 Ahem; + } + </style> + </head> + <body> + + <p> + <math> + <ms lquote="É" rquote="p">X</ms> + </math> + </p> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_ms");</script> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-001.html b/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-001.html new file mode 100644 index 0000000000..e423b16fd7 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-001.html @@ -0,0 +1,111 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Attribute mapping</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<meta name="assert" content="Verify that dir, mathcolor, mathbackground and mathsize are mapped to CSS but that deprecated MathML3 attributes are not."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<style> + #container { + color: blue; + font-size: 50px; + } +</style> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() { + var container = document.getElementById("container"); + for (tag in MathMLFragments) { + container.insertAdjacentHTML("beforeend", `<math>${MathMLFragments[tag]}</math>`); + } + Array.from(document.getElementsByClassName("element")).forEach(element => { + var tag = element.tagName; + var style = window.getComputedStyle(element); + + test(function() { + assert_equals(style.getPropertyValue("direction"), "ltr", "no attribute"); + element.setAttribute("dir", "rtl"); + assert_equals(style.getPropertyValue("direction"), "rtl", "attribute specified"); + element.setAttribute("dir", "RtL"); + assert_equals(style.getPropertyValue("direction"), "rtl", "case insensitive"); + element.setAttribute("dir", "auto"); + assert_equals(style.getPropertyValue("direction"), "ltr", "auto"); + element.setAttribute("dir", "foo"); + assert_equals(style.getPropertyValue("direction"), "ltr", "random value"); + }, `dir on the ${tag} element is mapped to CSS direction`) + + test(function() { + assert_equals(style.getPropertyValue("color"), + "rgb(0, 0, 255)", + "no attribute"); + element.setAttribute("mathcolor", "black"); + assert_equals(style.getPropertyValue("color"), "rgb(0, 0, 0)", "attribute specified"); + // The color names are case-insensitive. + // See https://www.w3.org/TR/css-color-3/#html4 + element.setAttribute("mathcolor", "GrEeN"); + assert_equals(style.getPropertyValue("color"), "rgb(0, 128, 0)", "case insensitive"); + }, `mathcolor on the ${tag} element is mapped to CSS color`); + + test(function() { + assert_equals(style.getPropertyValue("background-color"), + tag === "merror" ? + "rgb(255, 255, 224)" : "rgba(0, 0, 0, 0)", + "no attribute"); + element.setAttribute("mathbackground", "lightblue"); + assert_equals(style.getPropertyValue("background-color"), "rgb(173, 216, 230)", "attribute specified"); + // The color names are case-insensitive. + // See https://www.w3.org/TR/css-color-3/#html4 + element.setAttribute("mathbackground", "YeLlOw"); + assert_equals(style.getPropertyValue("background-color"), "rgb(255, 255, 0)", "case insensitive"); + }, `mathbackground on the ${tag} element is mapped to CSS background-color`); + + test(function() { + // "none" and "mprescripts" can only be used as non-first children of mmultiscripts so font-size + // is incremented and the resulting fraction string is hard to test accurately, skip for now. + if (tag === "none" || tag === "mprescripts") + return; + assert_equals(style.getPropertyValue("font-size"), "50px", "no attribute"); + element.setAttribute("mathsize", "20px"); + assert_equals(style.getPropertyValue("font-size"), "20px", "attribute specified"); + // unit identifiers are ASCII case-insensitive. + // https://www.w3.org/TR/css-values-3/#typedef-dimension + element.setAttribute("mathsize", "30Px"); + assert_equals(style.getPropertyValue("font-size"), "30px", "case insensitive"); + }, `mathsize on the ${tag} element is mapped to CSS font-size`); + + test(function() { + assert_true(MathMLFeatureDetection.has_mathsize(), "Superseding attributes are supported"); + var properties = ["background-color", "color", "fontfamily", "font-size", "font-style", "font-weight"]; + var oldStyle = {}; + properties.forEach(property => { + oldStyle[property] = style.getPropertyValue(property); + }); + element.setAttribute("background", "red"); + element.setAttribute("color", "blue"); + element.setAttribute("fontfamily", "monospace"); + element.setAttribute("fontsize", "50px"); + element.setAttribute("fontstyle", "italic"); + element.setAttribute("fontweight", "bold"); + properties.forEach(property => { + assert_equals(style.getPropertyValue(property), oldStyle[property], `${property}`); + }); + }, `deprecated MathML3 attributes on the ${tag} element are not mapped to CSS`); + }); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <div id="container"> + <math class="element"></math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-002.html b/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-002.html new file mode 100644 index 0000000000..baf136f358 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-002.html @@ -0,0 +1,118 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Attribute mapping</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> +<meta name="assert" content="Verify that mathvariant, scriptlevel, displaystyle are mapped to CSS"> +<link rel="stylesheet" href="/fonts/ahem.css"> +<style> + #container { + /* Ahem font does not have a MATH table so the font-size scale factor + is always 0.71^{computed - inherited math script level} */ + font: 100px/1 Ahem; + } +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function fontSize(style) { + return parseFloat((/(.+)px/).exec(style.getPropertyValue("font-size"))[1]); + } + function runTests() { + var container = document.getElementById("container"); + for (tag in MathMLFragments) { + container.insertAdjacentHTML("beforeend", `<math><mrow>${MathMLFragments[tag]}</mrow></math>`); + } + Array.from(document.getElementsByClassName("element")).forEach(element => { + var tag = element.tagName; + var style = window.getComputedStyle(element); + + test(function() { + assert_equals(style.getPropertyValue("text-transform"), + tag === "mi" ? "math-auto" : "none", + "no attribute"); + element.parentNode.setAttribute("style", "text-transform: uppercase"); + assert_equals(style.getPropertyValue("text-transform"), + tag === "mi" ? "math-auto" : "uppercase", + "text-transform on parent"); + element.setAttribute("mathvariant", "normal"); + assert_equals(style.getPropertyValue("text-transform"), + tag === "mi" ? "none" : "uppercase", "attribute specified"); + element.setAttribute("mathvariant", "NoRmAl"); + assert_equals(style.getPropertyValue("text-transform"), + tag === "mi" ? "none" : "uppercase", "case insensitive"); + }, `mathvariant on the ${tag} element is ${tag === "mi" ? "" : "not"} mapped to CSS text-transform`) + + test(function() { + // none and mprescripts appear as scripts + assert_equals(style.getPropertyValue("math-depth"), tag === "none" || tag === "mprescripts" ? "1" : "0", "no attribute"); + + var absoluteScriptlevel = 2; + element.setAttribute("scriptlevel", absoluteScriptlevel); + assert_equals(style.getPropertyValue("math-depth"), "" + absoluteScriptlevel, "attribute specified <U>"); + + var positiveScriptlevelDelta = 1; + element.setAttribute("scriptlevel", `+${positiveScriptlevelDelta}`); + assert_equals(style.getPropertyValue("math-depth"), "" + positiveScriptlevelDelta, "attribute specified +<U>"); + + var negativeScriptlevelDelta = -3; + element.setAttribute("scriptlevel", `${negativeScriptlevelDelta}`); + assert_equals(style.getPropertyValue("math-depth"), "" + negativeScriptlevelDelta, "attribute specified -<U>"); + + element.setAttribute("scriptlevel", absoluteScriptlevel); + element.setAttribute("mathsize", "42px"); + assert_approx_equals(fontSize(style), 42, 1, "mathsize wins over scriptlevel"); + + }, `scriptlevel on the ${tag} element is mapped to math-depth(...)`); + + test(function() { + // none and mprescripts appear as scripts + let expected = 0; + element.setAttribute("scriptlevel", "" + expected); + assert_equals(style.getPropertyValue("math-depth"), "" + expected, "no attribute"); + + element.setAttribute("scriptlevel", " +1"); + assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value"); + + element.setAttribute("scriptlevel", " + 1"); + assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value"); + + element.setAttribute("scriptlevel", "2.0"); + assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value"); + + element.setAttribute("scriptlevel", "-3\""); + assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value"); + + element.setAttribute("scriptlevel", "200px"); + assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value"); + + element.setAttribute("scriptlevel", "add(2)"); + assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value"); + + }, `invalid scriptlevel values on the ${tag} element are not mapped to math-depth(...)`); + + test(function() { + assert_equals(style.getPropertyValue("math-style"), "compact", "no attribute"); + element.setAttribute("displaystyle", "true"); + assert_equals(style.getPropertyValue("math-style"), "normal", "attribute specified"); + element.setAttribute("displaystyle", "TrUe"); + assert_equals(style.getPropertyValue("math-style"), "normal", "case insensitive"); + }, `displaystyle on the ${tag} element is mapped to CSS math-style`); + }); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <div id="container"> + <div><math class="element"></math></div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/blur-filter-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/blur-filter-ref.html new file mode 100644 index 0000000000..21fc165b7d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/blur-filter-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Blur filter (reference)</title> +</head> +<body> + <p>Rectangles should be blurred.</p> + <div style="background: green; filter: blur(5px); width: 200px; height: 200px;"></div> + <div style="background: green; filter: blur(5px); width: 200px; height: 200px; position: absolute; top: 300px"></div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/blur-filter.html b/testing/web-platform/tests/mathml/relations/css-styling/blur-filter.html new file mode 100644 index 0000000000..92a894bf34 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/blur-filter.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Blur filter</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="blur-filter-ref.html"/> +<meta name="assert" content="Verify that 'filter: blur' works on MathML elements."> +</head> +<body> + <p>Rectangles should be blurred.</p> + <div> + <math><mspace width="200px" height="200px" style="background: green; filter: blur(5px)"/></math> + </div> + <div style="position: absolute; top: 300px"> + <math style="filter: blur(5px)"><mspace width="200px" height="200px" style="background: green"/></math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/clip-path-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/clip-path-ref.html new file mode 100644 index 0000000000..57935564bf --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/clip-path-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Clip property (reference)</title> +</head> +<body> + <p>Rectangles should be clipped to a polygon.</p> + <div style="background: green; width: 200px; height: 200px; clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)"></div> + <div style="background: green; width: 200px; height: 200px; position: absolute; top: 300px; clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)"></div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/clip-path.html b/testing/web-platform/tests/mathml/relations/css-styling/clip-path.html new file mode 100644 index 0000000000..abe58e2261 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/clip-path.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Clip property</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="clip-path-ref.html"/> +<meta name="assert" content="Verify that the clip property works on MathML elements."> +</head> +<body> + <p>Rectangles should be clipped to a polygon.</p> + <div> + <math><mspace width="200px" height="200px" style="background: green; clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)"/></math> + </div> + <div style="position: absolute; top: 300px; width: 200px; height: 200px"> + <math style="position: absolute; clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)"><mspace width="200px" height="200px" style="background: green"/></math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/clip-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/clip-ref.html new file mode 100644 index 0000000000..7882ac8c31 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/clip-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Clip property (reference)</title> +</head> +<body> + <p>Rectangles should be clipped.</p> + <div style="background: green; width: 200px; height: 200px; position: absolute; top: 100px; clip: rect(0px 100px 100px 0px)"></div> + <div style="background: green; width: 200px; height: 200px; position: absolute; top: 300px; clip: rect(0px 100px 100px 0px)"></div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/clip.html b/testing/web-platform/tests/mathml/relations/css-styling/clip.html new file mode 100644 index 0000000000..48b7753fd8 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/clip.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Clip property</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="clip-ref.html"/> +<meta name="assert" content="Verify that the clip property works on MathML elements."> +</head> +<body> + <p>Rectangles should be clipped.</p> + <div> + <math><mspace width="200px" height="200px" style="position:absolute; top:100px; background: green; clip: rect(0px 100px 100px 0px)"/></math> + </div> + <div style="position: absolute; top: 300px; width: 200px; height: 200px"> + <math style="position: absolute; clip: rect(0px 100px 100px 0px)"><mspace width="200px" height="200px" style="background: green"/></math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-001-ref.html new file mode 100644 index 0000000000..0efca480ee --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-001-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>color (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px; padding: 1px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-001.html b/testing/web-platform/tests/mathml/relations/css-styling/color-001.html new file mode 100644 index 0000000000..76d65f579c --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-001.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>color</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="match" href="color-001-ref.html"/> +<meta name="assert" content="Verify that the color is used for the text of token elements."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px; padding: 1px;"> + <math><mi style="color: green">1</mi></math> + <math><mn style="color: green">2</mn></math> + <math><mo style="color: green">3</mo></math> + <math><mtext style="color: green">4</mtext></math> + <math><ms style="color: green">5</ms></math> + <div id="dynamic"> + <math><mi>1</mi></math> + <math><mn>2</mn></math> + <math><mo>3</mo></math> + <math><mtext>4</mtext></math> + <math><ms>5</ms></math> + </div> + </div> + <script> + window.addEventListener("load", () => { + document.getElementById("dynamic").style.color = "green"; + document.documentElement.classList.remove("reftest-wait"); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-002-ref.html new file mode 100644 index 0000000000..0efca480ee --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-002-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>color (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px; padding: 1px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-002.html b/testing/web-platform/tests/mathml/relations/css-styling/color-002.html new file mode 100644 index 0000000000..bce24f54c8 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-002.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>color</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fraction-with-nonzero-line-thickness"> +<link rel="match" href="color-002-ref.html"/> +<meta name="assert" content="Verify that the color is used for text and fraction bar of the mfrac element."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px; padding: 1px;"> + <math><mfrac style="color: green"><mn>1</mn><mn>2</mn></mfrac></math> + <div id="dynamic"> + <math><mfrac><mn>1</mn><mn>2</mn></mfrac></math> + </div> + </div> + <script> + window.addEventListener("load", () => { + document.getElementById("dynamic").style.color = "green"; + document.documentElement.classList.remove("reftest-wait"); + }); + </script> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-003-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-003-ref.html new file mode 100644 index 0000000000..0efca480ee --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-003-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>color (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px; padding: 1px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-003.html b/testing/web-platform/tests/mathml/relations/css-styling/color-003.html new file mode 100644 index 0000000000..dd04b61054 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-003.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>color</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#radical-symbol"> +<link rel="match" href="color-003-ref.html"/> +<meta name="assert" content="Verify that the color is used for text and radical symbol of the msqrt and mroot elements."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px; padding: 1px;"> + <math><msqrt style="color: green"><mn>1</mn></msqrt></math> + <math><mroot style="color: green"><mn>2</mn><mn>2</mn></mroot></math> + <div id="dynamic"> + <math><msqrt><mn>1</mn></msqrt></math> + <math><mroot><mn>2</mn><mn>2</mn></mroot></math> + </div> + </div> + <script> + window.addEventListener("load", () => { + document.getElementById("dynamic").style.color = "green"; + document.documentElement.classList.remove("reftest-wait"); + }); + </script> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_msqrt");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative-ref.html new file mode 100644 index 0000000000..0efca480ee --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>color (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px; padding: 1px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative.html b/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative.html new file mode 100644 index 0000000000..4bd15e62a0 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>color</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://github.com/mathml-refresh/mathml-core/pull/24"> +<link rel="match" href="color-004.tentative-ref.html"/> +<meta name="assert" content="Verify that the color is used for text and graphical elements of the menclose element."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px; padding: 1px;"> + <math><menclose notation="left" style="color: green"><mn>1</mn></menclose></math> + <math><menclose notation="right" style="color: green"><mn>2</mn></menclose></math> + <math><menclose notation="top" style="color: green"><mn>3</mn></menclose></math> + <math><menclose notation="bottom" style="color: green"><mn>4</mn></menclose></math> + <math><menclose notation="box" style="color: green"><mn>5</mn></menclose></math> + <math><menclose notation="roundedbox" style="color: green"><mn>6</mn></menclose></math> + <math><menclose notation="actuarial" style="color: green"><mn>7</mn></menclose></math> + <math><menclose notation="madruwb" style="color: green"><mn>8</mn></menclose></math> + <math><menclose notation="horizontalstrike" style="color: green"><mn>9</mn></menclose></math> + <math><menclose notation="verticalstrike" style="color: green"><mn>10</mn></menclose></math> + <math><menclose notation="updiagonalstrike" style="color: green"><mn>11</mn></menclose></math> + <math><menclose notation="downdiagonalstrike" style="color: green"><mn>12</mn></menclose></math> + <math><menclose notation="longdiv" style="color: green"><mn>13</mn></menclose></math> + <math><menclose notation="circle" style="color: green"><mn>14</mn></menclose></math> + <div id="dynamic"> + <math><menclose notation="left"><mn>1</mn></menclose></math> + <math><menclose notation="right"><mn>2</mn></menclose></math> + <math><menclose notation="top"><mn>3</mn></menclose></math> + <math><menclose notation="bottom"><mn>4</mn></menclose></math> + <math><menclose notation="box"><mn>5</mn></menclose></math> + <math><menclose notation="roundedbox"><mn>6</mn></menclose></math> + <math><menclose notation="actuarial"><mn>7</mn></menclose></math> + <math><menclose notation="madruwb"><mn>8</mn></menclose></math> + <math><menclose notation="horizontalstrike"><mn>9</mn></menclose></math> + <math><menclose notation="verticalstrike"><mn>10</mn></menclose></math> + <math><menclose notation="updiagonalstrike"><mn>11</mn></menclose></math> + <math><menclose notation="downdiagonalstrike"><mn>12</mn></menclose></math> + <math><menclose notation="longdiv"><mn>13</mn></menclose></math> + <math><menclose notation="circle"><mn>14</mn></menclose></math> + </div> + </div> + <script> + window.addEventListener("load", () => { + document.getElementById("dynamic").style.color = "green"; + document.documentElement.classList.remove("reftest-wait"); + }); + </script> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_menclose");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-005-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-005-ref.html new file mode 100644 index 0000000000..0efca480ee --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-005-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>color (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px; padding: 1px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-005.html b/testing/web-platform/tests/mathml/relations/css-styling/color-005.html new file mode 100644 index 0000000000..f2660c9e62 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/color-005.html @@ -0,0 +1,88 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>color</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="match" href="color-005-ref.html"/> +<meta name="assert" content="Verify that the color is used for normal, stretchy and large operators."> +<style> + math { + font: 20px/1 Ahem; + } + @font-face { + font-family: operators; + src: url("/fonts/math/operators.woff"); + } + mo { + font-family: operators; + } +</style> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div id="square" style="background: green; color: red; width: 200px; height: 200px; padding: 1px;"> + <math> + <!-- unstretched operators --> + <mo style="color: green">⥯</mo> + <mo style="color: green">+</mo> + <mo style="color: green">-</mo> + </math> + <math displaystyle="true"> + <!-- large operator --> + <mo largeop="true" style="color: green">⥯</mo> + </math> + <math> + <mrow> + <!-- stretchy, small size --> + <mspace height="2em"/> + <mo style="color: green">⥯</mo> + </mrow> + </math> + <math> + <mrow> + <!-- stretchy, large size --> + <mspace height="4em"/> + <mo style="color: green">⥯</mo> + </mrow> + </math> + <div id="dynamic"> + <math> + <!-- unstretched operators --> + <mo stretchy="false">⥯</mo> + <mo>+</mo> + <mo>-</mo> + </math> + <math displaystyle="true"> + <!-- large operator --> + <mo largeop="true">⥯</mo> + </math> + <math> + <mrow> + <!-- stretchy, small size --> + <mspace height="2em"/> + <mo>⥯</mo> + </mrow> + </math> + <math> + <mrow> + <!-- stretchy, large size --> + <mspace height="4em"/> + <mo>⥯</mo> + </mrow> + </math> + </div> + </div> + <script src="/mathml/support/fonts.js"></script> + <script> + window.addEventListener("load", () => loadAllFonts().then(() => { + document.getElementById("dynamic").style.color = "green"; + document.documentElement.classList.remove("reftest-wait"); + })); + </script> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/default-font-family.html b/testing/web-platform/tests/mathml/relations/css-styling/default-font-family.html new file mode 100644 index 0000000000..c471b0fc9d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/default-font-family.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Default font-family on the <math> root</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<meta name="assert" content="Verify that the default font-family is 'math'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> + <div id="log"></div> + <div style="font-family: BB2F7F3E9FEE11EA96DF67A737751C2F;"> + <div id="inherited-reference"></div> + <math id="math-not-inherited"></math> + </div> + <math id="math-default"></math> + + <script> + function getFontFamily(id) { + return window.getComputedStyle(document.getElementById(id)).fontFamily; + } + + test(function () { + assert_equals(getFontFamily("inherited-reference"), "BB2F7F3E9FEE11EA96DF67A737751C2F"); + assert_not_equals(getFontFamily("math-not-inherited"), getFontFamily("inherited-reference")); + }, "Default font-family on <math> is not inherited"); + + test(function () { + assert_equals(getFontFamily("math-not-inherited"), "math"); + assert_equals(getFontFamily("math-default"), "math"); + }, "Default font-family on <math> is 'math'"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-semantics-and-maction.html b/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-semantics-and-maction.html new file mode 100644 index 0000000000..23f8b62dfa --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-semantics-and-maction.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Default properties on <semantics> and <maction></title> +<link rel="help" href="https://w3c.github.io/mathml-core/#semantics-and-presentation"> +<link rel="help" href="https://w3c.github.io/mathml-core/#enlivening-expressions"> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<meta name="assert" content="Test that only the first children of semantics/maction are displayed."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> + <div id="log"></div> + <div> + <math> + <semantics> + <mn>1</mn> + <mn>2</mn> + <mn>3</mn> + <mn>4</mn> + <mn>5</mn> + </semantics> + <maction> + <mn>1</mn> + <mn>2</mn> + <mn>3</mn> + <mn>4</mn> + <mn>5</mn> + </maction> + </math> + </div> + + <script> + ["semantics", "maction"].forEach(name => { + let element = document.getElementsByTagName(name)[0]; + test(() => { + let child = element.firstElementChild; + assert_not_equals(window.getComputedStyle(child).display, "none", `Child ${child.innerText} does not have display: none`); + for (child = child.nextElementSibling; child; child = child.nextElementSibling) { + assert_equals(window.getComputedStyle(child).display, "none", `Child ${child.innerText} has display: none`); + } + }, `Display value of children of the <${name}> element`); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-the-math-root.html b/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-the-math-root.html new file mode 100644 index 0000000000..c329935f2e --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-the-math-root.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Default properties on the <math> root</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<meta name="assert" content="Test properties on the math root set by the UA stylesheet."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + math { + font-size: 100px; + } + .styled { + direction: rtl; + writing-mode: vertical-lr; + text-indent: .5em; + letter-spacing: .5em; + line-height: .5em; + word-spacing: .5em; + font-style: italic; + font-weight: bold; + } +</style> + +</head> +<body> + <div id="log"></div> + <div class="styled"> + <math id="ua"></math> + <math id="author" class="styled"></math> + </div> + + <script> + function getProperty(id, property) { + return window.getComputedStyle(document.getElementById(id))[property]; + } + [ + // Property name, value when specified from the UA, from the author. + ["direction", "ltr", "rtl"], + ["writing-mode", "horizontal-tb", "horizontal-tb"], // MathML Core level 1 only supports horizontal mode. + ["text-indent", "0px", "50px"], + ["letter-spacing", "normal", "50px"], + ["line-height", "normal", "50px"], + ["word-spacing", "0px", "50px"], + ["font-style", "normal", "italic"], + ["font-weight", "400", "700"] + ].forEach(([name, ua_value, author_value]) => { + test(function () { + assert_equals(getProperty("ua", name), ua_value, "when specified from the UA sheet"); + assert_equals(getProperty("author", name), author_value, "when specified by the author"); + }, `Value of ${name} on the <math> root`); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-1-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/display-1-ref.html new file mode 100644 index 0000000000..ce65aba18c --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/display-1-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>display (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-1.html b/testing/web-platform/tests/mathml/relations/css-styling/display-1.html new file mode 100644 index 0000000000..5a9e4db687 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/display-1.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>display</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="display-1-ref.html"/> +<meta name="assert" content="Verify that the 'display: none' property works on MathML elements."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px;"> + <math style="display: none;"><mspace width="200px" height="200px" style="background: red"/></math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-2.html b/testing/web-platform/tests/mathml/relations/css-styling/display-2.html new file mode 100644 index 0000000000..36a02952eb --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/display-2.html @@ -0,0 +1,139 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Verify that one can override the layout of MathML elements with the CSS display property</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that one can override the display of a MathML element."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/mathml/support/fonts.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math { + font-family: inherit; + } + mfrac { + padding: 0; + } +</style> +<script> + const Xsize = 25; + const templates = { + "block display": `<math style="display: block;">XXX</math>`, + "block display with contrained width": `<math style="display: block; width: ${2*Xsize}px;">XXX</math>`, + "list display inside display block": `<math style="display: block">\ + <mmultiscripts style="display: list-item;">X</mmultiscripts>\ + <maction style="display: list-item;">X</maction>\ + <mpadded style="display: list-item;">X</mpadded>\ +</math>`, + "inline display": `<math style="display: inline;">XXX</math>`, + "inline-block display": `<math style="display: inline-block">XXX</math>`, + "table display (math)": `<math style="display: table">\ + <mfrac style='display: table-row'>\ + <msub style='display: table-cell'>X</msub>\ + <msup style='display: table-cell'>X</msup>\ + <msubsup style='display: table-cell'>X</msubsup>\ + </mfrac>\ + <mtable style='display: table-row'>\ + <munder style='display: table-cell'>X</munder>\ + <mover style='display: table-cell'>X</mover>\ + <munderover style='display: table-cell'>X</munderover>\ + </mtable>\ +</math>`, + "table display (mrow)": `<math display="block">\ +<mrow style="display: table">\ + <mfrac style='display: table-row'>\ + <msub style='display: table-cell'>X</msub>\ + <msup style='display: table-cell'>X</msup>\ + <msubsup style='display: table-cell'>X</msubsup>\ + </mfrac>\ + <mtable style='display: table-row'>\ + <munder style='display: table-cell'>X</munder>\ + <mover style='display: table-cell'>X</mover>\ + <munderover style='display: table-cell'>X</munderover>\ + </mtable>\ +</mrow></math>`, + "inline-table display (math)": `<math style="display: inline-table">\ + <mfrac style='display: table-row'>\ + <msub style='display: table-cell'>X</msub>\ + <msup style='display: table-cell'>X</msup>\ + <msubsup style='display: table-cell'>X</msubsup>\ + </mfrac>\ + <mtable style='display: table-row'>\ + <munder style='display: table-cell'>X</munder>\ + <mover style='display: table-cell'>X</mover>\ + <munderover style='display: table-cell'>X</munderover>\ + </mtable>\ +</math>`, + "inline-table display (mrow)": `<math display="block">\ +<mrow style="display: inline-table">\ + <mfrac style='display: table-row'>\ + <msub style='display: table-cell'>X</msub>\ + <msup style='display: table-cell'>X</msup>\ + <msubsup style='display: table-cell'>X</msubsup>\ + </mfrac>\ + <mtable style='display: table-row'>\ + <munder style='display: table-cell'>X</munder>\ + <mover style='display: table-cell'>X</mover>\ + <munderover style='display: table-cell'>X</munderover>\ + </mtable>\ +</mrow></math>`, + "flexbox display (math)": `<math style="display: flex; flex-direction: column;">XXX</math>`, + "flexbox display (mrow)": `<math display="block"><mrow style="display: flex; flex-direction: column;">XXX</mrow></math>`, + "grid display (math)": `<math style="display: grid; grid-gap: 2px; grid-template-columns: ${Xsize}px ${Xsize}px ${Xsize}px;>">XXXXXXXXX</math>`, + "grid display (mrow)": `<math display="block"><mrow style="display: grid; grid-gap: 2px; grid-template-columns: ${Xsize}px ${Xsize}px ${Xsize}px;>">XXXXXXXXX</mrow></math>`, + "ruby display (math)": `<math style="display: ruby;">\ +<mrow style="display: ruby-base;">X</mrow>\ +<mrow style="display: ruby-text">XX</mrow>\ +</math>`, + "ruby display (mrow)": `<math display="block"><mrow style="display: ruby;">\ +<mrow style="display: ruby-base;">X</mrow>\ +<mrow style="display: ruby-text">XX</mrow>\ +</mrow></math>`, + "block display with column width (math)": `<math style="display: block; column-width: ${2*Xsize}px">\ + <mrow>XXXX</mrow><mrow>XXXX</mrow><mrow>XXXX</mrow>\ +</math>`, + "block display with column width (mrow)": `<math style="display: block"><mrow style="display: block; column-width: ${2*Xsize}px">\ + <mrow>XXXX</mrow><mrow>XXXX</mrow><mrow>XXXX</mrow>\ +</mrow></math>`, + }; + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + + for (let key in templates) { + if (!templates.hasOwnProperty(key)) + continue; + let mathtest = templates[key]. + replace(/X/g, `<mspace style="display: inline-block; width: ${Xsize}px; height: ${Xsize}px; background: black"></mspace>`); + let reference = mathtest. + replace(/maction|math|mfrac|mmultiscripts|mover|mover|mpadded|mrow|mspace|msubsup|msub|msup|mtable|munderover|munder/g, "div"); + document.body.insertAdjacentHTML("beforeend", `<div style="font: 20px/1 Ahem; position: absolute;">\ +<div><span>${key}:</span>${mathtest}</div>\ +<div><span>${key}:</span>${reference}</div>\ +</div>`); + let div = document.body.lastElementChild; + let elementDiv = div.firstElementChild; + let referenceDiv = div.lastElementChild; + + test(function() { + const epsilon = 1; + compareLayout(elementDiv, referenceDiv, epsilon); + }, `${key}`); + + div.style = "display: none;"; // Hide the div after measurement. + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-contents.html b/testing/web-platform/tests/mathml/relations/css-styling/display-contents.html new file mode 100644 index 0000000000..b18fdd6c8b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/display-contents.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>display: contents</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<meta name="assert" content="Verify that display: contents computes to display: none"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function runTests() { + var container = document.getElementById("container"); + for (tag in MathMLFragments) { + container.insertAdjacentHTML("beforeend", `<math>${MathMLFragments[tag]}</math>`); + } + test(function() { + Array.from(document.getElementsByClassName("element")).forEach(element => { + var style = window.getComputedStyle(element); + element.setAttribute("style", "display: contents"); + assert_equals(style.getPropertyValue("display"), "none", `${tag}`); + }); + }, "display: contents computes to display: none"); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <div id="container"> + <math class="element"></math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow-ref.html new file mode 100644 index 0000000000..b359414dc2 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow-ref.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<style> +div { + width: 20px; + padding: 5px; + font-size: 40px; + overflow-x: scroll; + overflow-y: hidden; +} +</style> +<div> + <math display="block" style="width: min-content;"> + <mn>text</mn> + </math> +</div> +<div style="direction: rtl;"> + <math display="block" style="width: min-content;"> + <mn>text</mn> + </math> +</div> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow.html b/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow.html new file mode 100644 index 0000000000..33df26c3ee --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1416539"> +<link rel="match" href="display-with-overflow-ref.html"> +<meta name="assert" content="Use safe centering (so that content is reachable with scroll) for display=block centering."> +<style> +math { + width: 20px; + padding: 5px; + font-size: 40px; + overflow-x: scroll; + overflow-y: hidden; +} +</style> +<math display="block"> + <mn>text</mn> +</math> +<math display="block" style="direction: rtl;"> + <mn>text</mn> +</math> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011-ref.html new file mode 100644 index 0000000000..400c46a245 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011-ref.html @@ -0,0 +1,155 @@ +<!DOCTYPE html> +<html> + <head> + <title>displaystyle</title> + <meta charset="utf-8"> + <link rel="stylesheet" href="/fonts/ahem.css"> + <style> + math { + font: 25px Ahem; + } + </style> + </head> + <body> + + <!-- Test displaystyle on mstyle --> + <math> + <mstyle displaystyle="true"> + <munder><mo>O</mo><mo>O</mo></munder> + </mstyle> + <mstyle displaystyle="false"> + <msub><mo>O</mo><mo>O</mo></munder> + </mstyle> + </math> + + <!-- The mfrac element sets displaystyle to "false", or if it was already + false increments scriptlevel by 1, within numerator and denominator. + --> + <math> + <mstyle displaystyle="true"> + <mfrac> + <msub><mo>O</mo><mo>O</mo></msub> + <msub><mo>O</mo><mo>O</mo></msub> + </mfrac> + </mstyle> + </math> + + <!-- The mroot element increments scriptlevel by 2, and sets + displaystyle to "false", within index, but leaves both attributes + unchanged within base. + The msqrt element leaves both attributes unchanged within its + argument. --> + <math> + <mstyle displaystyle="true"> + <mroot> + <munder><mo>O</mo><mo>O</mo></munder> + <msub><mo>O</mo><mo>O</mo></msub> + </mroot> + <msqrt> + <munder><mo>O</mo><mo>O</mo></munder> + </msqrt> + </mstyle> + </math> + +<!-- + The msub element [...] increments scriptlevel by 1, and sets displaystyle to + "false", within subscript, but leaves both attributes unchanged within base. + + The msup element [...] increments scriptlevel by 1, and sets displaystyle to + "false", within superscript, but leaves both attributes unchanged within + base. + + The msubsup element [...] increments scriptlevel by 1, and sets displaystyle + to "false", within subscript and superscript, but leaves both attributes + unchanged within base. + + The mmultiscripts element increments scriptlevel by 1, and sets displaystyle + to "false", within each of its arguments except base, but leaves both + attributes unchanged within base. + --> + <math> + <mstyle displaystyle="true"> + <msub> + <munder><mo>O</mo><mo>O</mo></munder> + <msub><mo>O</mo><mo>O</mo></msub> + </msub> + <msup> + <munder><mo>O</mo><mo>O</mo></munder> + <msub><mo>O</mo><mo>O</mo></msub> + </msup> + <msubsup> + <munder><mo>O</mo><mo>O</mo></munder> + <msub><mo>O</mo><mo>O</mo></msub> + <msub><mo>O</mo><mo>O</mo></msub> + </msubsup> + <mmultiscripts> + <munder><mo>O</mo><mo>O</mo></munder> + <msub><mo>O</mo><mo>O</mo></msub> + <msub><mo>O</mo><mo>O</mo></msub> + <mprescripts/> + <msub><mo>O</mo><mo>O</mo></msub> + <msub><mo>O</mo><mo>O</mo></msub> + </mmultiscripts> + </mstyle> + </math> + +<!-- + The munder element [...] always sets displaystyle to "false" within the + underscript, but increments scriptlevel by 1 only when accentunder is + "false". Within base, it always leaves both attributes unchanged. + + The mover element [...] always sets displaystyle to "false" within + overscript, but increments scriptlevel by 1 only when accent is "false". + Within base, it always leaves both attributes unchanged. + + The munderover [..] always sets displaystyle to "false" within underscript + and overscript, but increments scriptlevel by 1 only when accentunder or + accent, respectively, are "false". Within base, it always leaves both + attributes unchanged. +--> + <math> + <mstyle displaystyle="true"> + <munder> + <munder><mo>O</mo><mo>O</mo></munder> + <msub><mo>O</mo><mo>O</mo></msub> + </munder> + <mover> + <munder><mo>O</mo><mo>O</mo></munder> + <msub><mo>O</mo><mo>O</mo></msub> + </mover> + <munderover> + <munder><mo>O</mo><mo>O</mo></munder> + <msub><mo>O</mo><mo>O</mo></msub> + <msub><mo>O</mo><mo>O</mo></msub> + </munderover> + </mstyle> + </math> + +<!-- + The displaystyle attribute is allowed on the mtable element to set the + inherited value of the attribute. If the attribute is not present, the + mtable element sets displaystyle to "false" within the table elements. +--> + <math> + <mstyle displaystyle="false"> + <mtable displaystyle="true"> + <mtr> + <mtd> + <munder><mo>O</mo><mo>O</mo></munder> + </mtd> + </mtr> + </mtable> + </mstyle> + <mstyle displaystyle="true"> + <mtable> + <mtr> + <mtd> + <msub><mo>O</mo><mo>O</mo></msub> + </mtd> + </mtr> + </mtable> + </mstyle> + </math> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011.html new file mode 100644 index 0000000000..a0bfc29ae5 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011.html @@ -0,0 +1,168 @@ +<!DOCTYPE html> +<html> + <head> + <title>displaystyle</title> + <meta charset="utf-8"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> + <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> + <link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> + <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> + <link rel="help" href="https://w3c.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts"> + <link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="match" href="displaystyle-011-ref.html"/> + <meta name="assert" content="Test the effect on displaystyle and movablelimits"> + <link rel="stylesheet" href="/fonts/ahem.css"> + <style> + math { + font: 25px Ahem; + } + </style> + </head> + <body> + + <!-- Test displaystyle on mstyle --> + <math> + <mstyle displaystyle="true"> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </mstyle> + <mstyle displaystyle="false"> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </mstyle> + </math> + + <!-- The mfrac element sets displaystyle to "false", or if it was already + false increments scriptlevel by 1, within numerator and denominator. + --> + <math> + <mstyle displaystyle="true"> + <mfrac> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </mfrac> + </mstyle> + </math> + + <!-- The mroot element increments scriptlevel by 2, and sets + displaystyle to "false", within index, but leaves both attributes + unchanged within base. + The msqrt element leaves both attributes unchanged within its + argument. --> + <math> + <mstyle displaystyle="true"> + <mroot> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </mroot> + <msqrt> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </msqrt> + </mstyle> + </math> + +<!-- + The msub element [...] increments scriptlevel by 1, and sets displaystyle to + "false", within subscript, but leaves both attributes unchanged within base. + + The msup element [...] increments scriptlevel by 1, and sets displaystyle to + "false", within superscript, but leaves both attributes unchanged within + base. + + The msubsup element [...] increments scriptlevel by 1, and sets displaystyle + to "false", within subscript and superscript, but leaves both attributes + unchanged within base. + + The mmultiscripts element increments scriptlevel by 1, and sets displaystyle + to "false", within each of its arguments except base, but leaves both + attributes unchanged within base. + --> + <math> + <mstyle displaystyle="true"> + <msub> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </msub> + <msup> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </msup> + <msubsup> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </msubsup> + <mmultiscripts> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mprescripts/> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </mmultiscripts> + </mstyle> + </math> + +<!-- + The munder element [...] always sets displaystyle to "false" within the + underscript, but increments scriptlevel by 1 only when accentunder is + "false". Within base, it always leaves both attributes unchanged. + + The mover element [...] always sets displaystyle to "false" within + overscript, but increments scriptlevel by 1 only when accent is "false". + Within base, it always leaves both attributes unchanged. + + The munderover [..] always sets displaystyle to "false" within underscript + and overscript, but increments scriptlevel by 1 only when accentunder or + accent, respectively, are "false". Within base, it always leaves both + attributes unchanged. +--> + <math> + <mstyle displaystyle="true"> + <munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </munder> + <mover> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </mover> + <munderover> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </munderover> + </mstyle> + </math> + +<!-- + The displaystyle attribute is allowed on the mtable element to set the + inherited value of the attribute. If the attribute is not present, the + mtable element sets displaystyle to "false" within the table elements. +--> + <math> + <mstyle displaystyle="false"> + <mtable displaystyle="true"> + <mtr> + <mtd> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </mtd> + </mtr> + </mtable> + </mstyle> + <mstyle displaystyle="true"> + <mtable> + <mtr> + <mtd> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + </mtd> + </mtr> + </mtable> + </mstyle> + </math> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012-ref.html new file mode 100644 index 0000000000..96042b696f --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012-ref.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + <head> + <title>displaystyle</title> + <meta charset="utf-8"> + <link rel="stylesheet" href="/fonts/ahem.css"> + <style> + math { + font: 25px Ahem; + } + </style> + </head> + <body> + + <!-- Test the effect of displaystyle on munder, mover and munderover --> + <math> + <mstyle displaystyle="true"> + <munder><mo>O</mo><mo>O</mo></munder> + <mover><mo>O</mo><mo>O</mo></mover> + <munderover><mo>O</mo><mo>O</mo><mo>O</mo></munderover> + </mstyle> + <mstyle displaystyle="false"> + <msub><mo>O</mo><mo>O</mo></msub> + <msup><mo>O</mo><mo>O</mo></msup> + <msubsup><mo>O</mo><mo>O</mo><mo>O</mo></msubsup> + </mstyle> + </math> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012.html new file mode 100644 index 0000000000..9fd4c784dd --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> + <head> + <title>displaystyle</title> + <meta charset="utf-8"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> + <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> + <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="match" href="displaystyle-012-ref.html"/> + <meta name="assert" content="Test the effect on displaystyle on munder, mover and munderover"> + <link rel="stylesheet" href="/fonts/ahem.css"> + <style> + math { + font: 25px Ahem; + } + </style> + </head> + <body> + + <math> + <mstyle displaystyle="true"> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mover><mo movablelimits="true">O</mo><mo>O</mo></mover> + <munderover><mo movablelimits="true">O</mo><mo>O</mo><mo>O</mo></munderover> + </mstyle> + <mstyle displaystyle="false"> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mover><mo movablelimits="true">O</mo><mo>O</mo></mover> + <munderover><mo movablelimits="true">O</mo><mo>O</mo><mo>O</mo></munderover> + </mstyle> + </math> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013-ref.html new file mode 100644 index 0000000000..9a580350de --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013-ref.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> + <head> + <title>displaystyle</title> + <meta charset="utf-8"> + <link rel="stylesheet" href="/fonts/ahem.css"> + <style> + math { + font: 25px Ahem; + } + </style> + </head> + <body> + + <!-- Test dynamic change of displaystyle --> + <math id="m1" displaystyle="true"> + <munder><mo>O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </math> + <math> + <mstyle id="m2" displaystyle="true"> + <munder><mo>O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </mstyle> + </math> + <math> + <mtable id="m3" displaystyle="true"> + <mtr> + <mtd> + <munder><mo>O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </mtd> + </mtr> + </mtable> + </math> + <math id="m4" displaystyle="false"> + <msub><mo>O</mo><mo>O</mo></msub> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </math> + <math> + <mstyle id="m5" displaystyle="false"> + <msub><mo>O</mo><mo>O</mo></msub> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </mstyle> + </math> + <math> + <mtable id="m6" displaystyle="false"> + <mtr> + <mtd> + <msub><mo>O</mo><mo>O</mo></msub> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </mtd> + </mtr> + </mtable> + </math> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013.html new file mode 100644 index 0000000000..3ce9fff062 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013.html @@ -0,0 +1,80 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <title>displaystyle</title> + <meta charset="utf-8"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> + <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> + <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable"> + <link rel="match" href="displaystyle-013-ref.html"/> + <meta name="assert" content="Test dynamic change of displaystyle"> + <script src="/mathml/support/fonts.js"></script> + <script type="text/javascript"> + function doTest() { + document.body.offsetTop; // Update layout + document.getElementById("m1").setAttribute("displaystyle", "true"); + document.getElementById("m2").setAttribute("displaystyle", "true"); + document.getElementById("m3").setAttribute("displaystyle", "true"); + document.getElementById("m4").removeAttribute("displaystyle"); + document.getElementById("m5").removeAttribute("displaystyle"); + document.getElementById("m6").removeAttribute("displaystyle"); + document.documentElement.removeAttribute("class"); + } + window.addEventListener("load", () => { loadAllFonts().then(doTest); }); + </script> + <link rel="stylesheet" href="/fonts/ahem.css"> + <style> + math { + font: 25px Ahem; + } + </style> + </head> + <body> + + <math id="m1"> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </math> + <math> + <mstyle id="m2"> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </mstyle> + </math> + <math> + <mtable id="m3"> + <mtr> + <mtd> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </mtd> + </mtr> + </mtable> + </math> + <math id="m4" displaystyle="true"> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </math> + <math> + <mstyle id="m5" displaystyle="true"> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </mstyle> + </math> + <math> + <mtable id="m6" displaystyle="true"> + <mtr> + <mtd> + <munder><mo movablelimits="true">O</mo><mo>O</mo></munder> + <mfrac><mn>1</mn><mn>2</mn></mfrac> + </mtd> + </mtr> + </mtable> + </math> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014-ref.html new file mode 100644 index 0000000000..085e2c429d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014-ref.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html> + <head> + <title>displaystyle</title> + <meta charset="utf-8"> + <link rel="stylesheet" href="/fonts/ahem.css"> + <style> + math { + font: 25px Ahem; + } + </style> + </head> + <body> + + <!-- See https://bugzilla.mozilla.org/show_bug.cgi?id=832800 --> + <math> + <mstyle displaystyle="true"> + <mfrac> + <mrow> + <mn>X</mn> + <mo id="mathOperator" mathbackground="red">+</mo> + <mfrac> + <mrow><mn>X</mn></mrow> + <mrow><mn>X</mn></mrow> + </mfrac> + </mrow> + <mrow> + <mn>X</mn> + </mrow> + </mfrac> + </mstyle> + </math> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014.html new file mode 100644 index 0000000000..a4f1208e35 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <title>displaystyle</title> + <meta charset="utf-8"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> + <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> + <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> + <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> + <link rel="match" href="displaystyle-014-ref.html"/> + <meta name="assert" content="Test dynamic change of mathbackground on an operator does not interfer with its displaystyle"> + <script src="/mathml/support/fonts.js"></script> + <script type="text/javascript"> + function doTest() { + document.body.offsetTop; // Update layout + document.getElementById('mathOperator'). + setAttribute('mathbackground', 'red'); + document.documentElement.removeAttribute("class"); + } + window.addEventListener("load", () => { loadAllFonts().then(doTest); }); + </script> + <link rel="stylesheet" href="/fonts/ahem.css"> + <style> + math { + font: 25px Ahem; + } + </style> + </head> + <body> + + <!-- See https://bugzilla.mozilla.org/show_bug.cgi?id=832800 --> + <math> + <mstyle displaystyle="true"> + <mfrac> + <mrow> + <mn>X</mn> + <mo id="mathOperator">+</mo> + <mfrac> + <mrow><mn>X</mn></mrow> + <mrow><mn>X</mn></mrow> + </mfrac> + </mrow> + <mrow> + <mn>X</mn> + </mrow> + </mfrac> + </mstyle> + </math> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015-ref.html new file mode 100644 index 0000000000..2e375c6886 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015-ref.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>displaystyle and display</title> + </head> + <body> + <math> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </math> + <math displaystyle="true"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </math> + <math display="inline" displaystyle="true"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </math> + <math display="block" displaystyle="true"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </math> + <math displaystyle="false"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </math> + <math display="inline" displaystyle="false"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </math> + <math display="block" displaystyle="false"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015.html new file mode 100644 index 0000000000..e4a747fb20 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>displaystyle and display</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> + <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> + <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> + <link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary"> + <link rel="match" href="displaystyle-015-ref.html"/> + <meta name="assert" content="Test interaction of math@display and displaystyle on an operator with movablelimits"> + </head> + <body> + <math> + <mstyle displaystyle="false"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </mstyle> + </math> + <math> + <mstyle displaystyle="true"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </mstyle> + </math> + <math display="inline"> + <mstyle displaystyle="true"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </mstyle> + </math> + <math display="block"> + <mstyle displaystyle="true"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </mstyle> + </math> + <math> + <mstyle displaystyle="false"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </mstyle> + </math> + <math display="inline"> + <mstyle displaystyle="false"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </mstyle> + </math> + <math display="block"> + <mstyle displaystyle="false"> + <munderover> + <mo>∑</mo> + <mi>b</mi> + <mi>c</mi> + </munderover> + </mstyle> + </math> + + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-1.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-1.html new file mode 100644 index 0000000000..26aed81d03 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-1.html @@ -0,0 +1,136 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>displaystyle</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-math-style-property"> +<meta name="assert" content="Verify that the correct inheritance of the displaystyle value by measuring the size of large operators."> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/largeop-displayoperatorminheight5000.woff"); + } + math { + font-family: TestFont; + font-size: 10px; + } +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/attribute-values.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script> + setup({ explicit_done: true }); + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 5; + function verify_displaystyle(elementId, displaystyle, description) { + var expectedSize = (displaystyle ? 5000 : 1000) * emToPx; + var elementSize = document.getElementById(elementId). + getBoundingClientRect().height; + assert_approx_equals(elementSize, expectedSize, epsilon, description); + } + + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + for (transform in AttributeValueTransforms) { + TransformAttributeValues(transform, ["display", "displaystyle"]); + test(function() { + verify_displaystyle("math_default", false, "default"); + verify_displaystyle("math_false", false, "explicit displaystyle false"); + verify_displaystyle("math_true", true, "explicit displaystyle true"); + }, `math element (${transform})`); + test(function() { + verify_displaystyle("math_inline", false, "explicit display inline"); + verify_displaystyle("math_block", true, "explicit display block"); + verify_displaystyle("math_block_false", false, "explicit display block and displaystyle false"); + verify_displaystyle("math_block_true", true, "explicit display block and displaystyle true"); + verify_displaystyle("math_inline_false", false, "explicit display inline and displaystyle false"); + verify_displaystyle("math_inline_true", true, "explicit display inline and displaystyle true"); + }, `math element (explicit display, ${transform})`); + test(function() { + verify_displaystyle("mstyle_false", false, "explicit displaystyle false"); + verify_displaystyle("mstyle_true", true, "explicit displaystyle true"); + }, `mstyle element (${transform})`); + test(function() { + verify_displaystyle("mtable_default", false, "default"); + verify_displaystyle("mtable_false", false, "explicit displaystyle false"); + verify_displaystyle("mtable_true", true, "explicit displaystyle true"); + }, `mtable element (${transform})`); + test(function() { + verify_displaystyle("mfrac_sibling", true, "sibling"); + verify_displaystyle("mfrac_numerator", false, "numerator"); + verify_displaystyle("mfrac_denominator", false, "denominator"); + }, `mfrac element (${transform})`); + test(function() { + verify_displaystyle("mroot_base", true, "base"); + verify_displaystyle("mroot_index", false, "index"); + }, `mroot element (${transform})`); + test(function() { + verify_displaystyle("msub_base", true, "base"); + verify_displaystyle("msub_subscript", false, "subscript"); + }, `msub element (${transform})`); + test(function() { + verify_displaystyle("msup_base", true, "base"); + verify_displaystyle("msup_supscript", false, "supscript"); + }, `msup element (${transform})`); + test(function() { + verify_displaystyle("msubsup_base", true, "base"); + verify_displaystyle("msubsup_subscript", false, "subscript"); + verify_displaystyle("msubsup_supscript", false, "supscript"); + }, `msubsup element (${transform})`); + test(function() { + verify_displaystyle("munder_base", true, "base"); + verify_displaystyle("munder_underscript", false, "underscript"); + }, `munder element (${transform})`); + test(function() { + verify_displaystyle("mover_base", true, "base"); + verify_displaystyle("mover_overscript", false, "overscript"); + }, `mover element (${transform})`); + test(function() { + verify_displaystyle("munderover_base", true, "base"); + verify_displaystyle("munderover_underscript", false, "underscript"); + verify_displaystyle("munderover_overscript", false, "overscript"); + }, `munderover element (${transform})`); + } + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <math><mo id="math_default">⫿</mo></math> + <math display="inline"><mo id="math_inline">⫿</mo></math> + <math display="block"><mo id="math_block">⫿</mo></math> + <math displaystyle="false"><mo id="math_false">⫿</mo></math> + <math displaystyle="true"><mo id="math_true">⫿</mo></math> + <math display="block" displaystyle="false"> + <mo id="math_block_false">⫿</mo> + </math> + <math display="block" displaystyle="true"> + <mo id="math_block_true">⫿</mo> + </math> + <math display="inline" displaystyle="false"> + <mo id="math_inline_false">⫿</mo> + </math> + <math display="inline" displaystyle="true"> + <mo id="math_inline_true">⫿</mo> + </math> + <math><mstyle displaystyle="false"><mo id="mstyle_false">⫿</mo></mstyle></math> + <math><mstyle displaystyle="true"><mo id="mstyle_true">⫿</mo></mstyle></math> + <math displaystyle="true"><mtable><mtr><mtd><mo id="mtable_default">⫿</mo></mtd></mtr></mtable></math> + <math><mtable displaystyle="true"><mtr><mtd><mo id="mtable_true">⫿</mo></mtd></mtr></mtable></math> + <math displaystyle="true"><mtable displaystyle="false"><mtr><mtd><mo id="mtable_false">⫿</mo></mtd></mtr></mtable></math> + <math displaystyle="true"><mo id="mfrac_sibling">⫿</mo><mfrac><mo id="mfrac_numerator">⫿</mo><mo id="mfrac_denominator">⫿</mo></mfrac></math> + <math displaystyle="true"><mroot><mo id="mroot_base">⫿</mo><mo id="mroot_index">⫿</mo></mroot></math> + <math displaystyle="true"><msub><mo id="msub_base">⫿</mo><mo id="msub_subscript">⫿</mo></msub></math> + <math displaystyle="true"><msup><mo id="msup_base">⫿</mo><mo id="msup_supscript">⫿</mo></msup></math> + <math displaystyle="true"><msubsup><mo id="msubsup_base">⫿</mo><mo id="msubsup_subscript">⫿</mo><mo id="msubsup_supscript">⫿</mo></msubsup></math> + <math displaystyle="true"><mmultiscripts><mo id="mmultiscripts_base">⫿</mo><mo id="mmultiscripts_subscript">⫿</mo><mo id="mmultiscripts_supscript">⫿</mo><mprescripts/><mo id="mmultiscripts_presubscript">⫿</mo><mo id="mmultiscripts_presupscript">⫿</mo></mmultiscripts></math> + <math displaystyle="true"><munder><mo id="munder_base">⫿</mo><mo id="munder_underscript">⫿</mo></munder></math> + <math displaystyle="true"><mover><mo id="mover_base">⫿</mo><mo id="mover_overscript">⫿</mo></mover></math> + <math displaystyle="true"><munderover><mo id="munderover_base">⫿</mo><mo id="munderover_underscript">⫿</mo><mo id="munderover_overscript">⫿</mo></munderover></math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-2.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-2.html new file mode 100644 index 0000000000..68566cfc25 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-2.html @@ -0,0 +1,208 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>displaystyle</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-math-style-property"> +<meta name="assert" content="Verify interaction between automatic displaystyle and specified displaystyle on descendants."> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/largeop-displayoperatorminheight5000.woff"); + } + math, math * { + font-family: TestFont; + font-size: 10px; + } +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/attribute-values.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script> + setup({ explicit_done: true }); + var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 + var epsilon = 5; + function verify_displaystyle(elementId, displaystyle, description) { + var expectedSize = (displaystyle ? 5000 : 1000) * emToPx; + var elementSize = document.getElementById(elementId). + getBoundingClientRect().height; + assert_approx_equals(elementSize, expectedSize, epsilon, description); + } + + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + for (transform in AttributeValueTransforms) { + TransformAttributeValues(transform, ["display", "displaystyle"]); + test(function() { + verify_displaystyle("cell_false", false, "cell with displaystyle false"); + verify_displaystyle("cell_true", true, "cell with displaystyle true"); + }, `mtable element (${transform})`); + test(function() { + verify_displaystyle("mfrac_numerator", true, "numerator"); + verify_displaystyle("mfrac_denominator", true, "denominator"); + }, `mfrac element (${transform})`); + test(function() { + verify_displaystyle("mroot_base", false, "base"); + verify_displaystyle("mroot_index", true, "index"); + }, `mroot element (${transform})`); + test(function() { + verify_displaystyle("msub_base", false, "base"); + verify_displaystyle("msub_subscript", true, "subscript"); + }, `msub element (${transform})`); + test(function() { + verify_displaystyle("msup_base", false, "base"); + verify_displaystyle("msup_superscript", true, "superscript"); + }, `msup element (${transform})`); + test(function() { + verify_displaystyle("msubsup_base", false, "base"); + verify_displaystyle("msubsup_subscript", true, "subscript"); + verify_displaystyle("msubsup_superscript", true, "superscript"); + }, `msubsup element (${transform})`); + test(function() { + verify_displaystyle("munder_base", false, "base"); + verify_displaystyle("munder_underscript", true, "underscript"); + }, `munder element (${transform})`); + test(function() { + verify_displaystyle("mover_base", false, "base"); + verify_displaystyle("mover_overscript", true, "overscript"); + }, `mover element (${transform})`); + test(function() { + verify_displaystyle("munderover_base", false, "base"); + verify_displaystyle("munderover_underscript", true, "underscript"); + verify_displaystyle("munderover_overscript", true, "overscript"); + }, `munderover element (${transform})`); + } + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <math displaystyle="true"> + <mtable> + <mtr> + <mtd> + <mstyle displaystyle="false"> + <mo id="cell_false">⫿</mo> + </mstyle> + </mtd> + <mtd> + <mstyle displaystyle="true"> + <mo id="cell_true">⫿</mo> + </mstyle> + </mtd> + </mtr> + </mtable> + </math> + <math> + <mfrac> + <mstyle displaystyle="true"> + <mo id="mfrac_numerator">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="mfrac_denominator">⫿</mo> + </mstyle> + </mfrac> + </math> + <math displaystyle="true"> + <mroot> + <mstyle displaystyle="false"> + <mo id="mroot_base">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="mroot_index">⫿</mo> + </mstyle> + </mroot> + </math> + <math displaystyle="true"> + <msub> + <mstyle displaystyle="false"> + <mo id="msub_base">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="msub_subscript">⫿</mo> + </mstyle> + </msub> + </math> + <math displaystyle="true"> + <msup> + <mstyle displaystyle="false"> + <mo id="msup_base">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="msup_superscript">⫿</mo> + </mstyle> + </msup> + </math> + <math displaystyle="true"> + <msubsup> + <mstyle displaystyle="false"> + <mo id="msubsup_base">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="msubsup_subscript">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="msubsup_superscript">⫿</mo> + </mstyle> + </msubsup> + </math> + <math displaystyle="true"> + <mmultiscripts> + <mstyle displaystyle="false"> + <mo id="mmultiscripts_base">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="mmultiscripts_subscript">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="mmultiscripts_superscript">⫿</mo> + </mstyle> + <mprescripts/> + <mstyle displaystyle="true"> + <mo id="mmultiscripts_presubscript">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="mmultiscripts_presuperscript">⫿</mo> + </mstyle> + </mmultiscripts> + </math> + <math displaystyle="true"> + <munder> + <mstyle displaystyle="false"> + <mo id="munder_base">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="munder_underscript">⫿</mo> + </mstyle> + </munder> + </math> + <math displaystyle="true"> + <mover> + <mstyle displaystyle="false"> + <mo id="mover_base">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="mover_overscript">⫿</mo> + </mstyle> + </mover> + </math> + <math displaystyle="true"> + <munderover> + <mstyle displaystyle="false"> + <mo id="munderover_base">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="munderover_underscript">⫿</mo> + </mstyle> + <mstyle displaystyle="true"> + <mo id="munderover_overscript">⫿</mo> + </mstyle> + </munderover> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-3.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-3.html new file mode 100644 index 0000000000..a5bcab2aaa --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-3.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>displaystyle</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-math-style-property"> +<meta name="assert" content="Verify the displaystyle of the underover element is considered (not the one of its base) to determine whether to move limits."> +<link rel="stylesheet" href="/fonts/ahem.css"> +<style> + math, math * { + font-family: Ahem; + font-size: 20px; + } +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + function runTests() { + ["munder", "mover", "munderover"].forEach((tag) => { + Array.from(document.getElementsByTagName(tag)).forEach(e => { + var displaystyle = e.getAttribute('displaystyle') === "true"; + test(function() { + assert_true(MathMLFeatureDetection.has_movablelimits()); + var elementRight = e.getBoundingClientRect().right; + var baseRight = e.firstElementChild.getBoundingClientRect().right; + if (displaystyle) + assert_approx_equals(elementRight, baseRight, 1); + else + assert_greater_than(elementRight, baseRight + 10); + }, `movablelimits for ${tag} element (displaystyle=${displaystyle})`); + }); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <math> + <munder displaystyle="false"> + <mo displaystyle="true" movablelimits="true">XX</mo> + <mtext>X</mtext> + </munder> + </math> + <math> + <mover displaystyle="false"> + <mo displaystyle="true" movablelimits="true">XX</mo> + <mtext>X</mtext> + </mover> + </math> + <math> + <munderover displaystyle="false"> + <mo displaystyle="true" movablelimits="true">XX</mo> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + </math> + <math> + <munder displaystyle="true"> + <mo displaystyle="false" movablelimits="true">XX</mo> + <mtext>X</mtext> + </munder> + </math> + <math> + <mover displaystyle="true"> + <mo displaystyle="false" movablelimits="true">XX</mo> + <mtext>X</mtext> + </mover> + </math> + <math> + <munderover displaystyle="true"> + <mo displaystyle="false" movablelimits="true">XX</mo> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1-ref.html new file mode 100644 index 0000000000..111ea79e24 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1-ref.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Test dynamically changing dir attribute</title> +</head> +<body> + <p> + math: + <math dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </math> + <math dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </math> + <math> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </math> + </p> + <p> + mstyle: + <math> + <mstyle dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mstyle> + </math> + <math> + <mstyle dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mstyle> + </math> + <math> + <mstyle> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mstyle> + </math> + </p> + <p> + mrow: + <math> + <mrow dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mrow> + </math> + <math> + <mrow dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mrow> + </math> + <math> + <mrow> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mrow> + </math> + </p> +</body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1.html b/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1.html new file mode 100644 index 0000000000..d97505eff1 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1.html @@ -0,0 +1,105 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <meta charset="utf-8"> + <title>Test dynamically changing dir attribute</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> + <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> + <meta name="assert" content="The dir attribute should update direction map to css properties dynamically"> + <link rel="match" href="dynamic-dir-1-ref.html"> + <script> + window.addEventListener("load", () => { + + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + ["math", "mstyle", "mrow"].forEach((tag) => { + let elements = document.getElementsByTagName(tag); + + // set an explicit rtl where there was none + elements[0].setAttribute("dir", "rtl"); + + // change explicit ltr to rtl + elements[1].setAttribute("dir", "rtl"); + + // remove an explicitly set dir="rtl" + elements[2].removeAttribute("dir"); + + }) + + document.documentElement.classList.remove('reftest-wait'); + }) + </script> +</head> +<body> + <p> + math: + <math> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </math> + <math dir="ltr"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </math> + <math dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </math> + </p> + <p> + mstyle: + <math> + <mstyle> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mstyle> + </math> + <math> + <mstyle dir="ltr"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mstyle> + </math> + <math> + <mstyle dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mstyle> + </math> + </p> + <p> + mrow: + <math> + <mrow> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mrow> + </math> + <math> + <mrow dir="ltr"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mrow> + </math> + <math> + <mrow dir="rtl"> + <mi>a</mi> + <mi>b</mi> + <mi>c</mi> + </mrow> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_dir");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display-ref.html new file mode 100644 index 0000000000..8f25c9db06 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>floating inside display: block MathML (reference)</title> +</head> +<body> + <p>Test passes if you see a blue square on the left and a smaller magenta square on the right.</p> + <div> + <div style="display: block"> + <div style="display: inline-block; width: 50px; height: 50px; background: magenta"></div><div style="float: left; display: inline-block; width: 100px; height: 100px; background: blue"></div> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display.html new file mode 100644 index 0000000000..f398094e15 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>floating inside display: block MathML</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="floating-inside-mathml-with-block-display-ref.html"/> +<meta name="assert" content="Verify that float works within a display: block MathML element."> +</head> +<body> + <p>Test passes if you see a blue square on the left and a smaller magenta square on the right.</p> + <math> + <mrow style="display: block"> + <mspace style="display: inline-block; width: 50px; height: 50px; background: magenta"/><mspace style="float: left; display: inline-block; width: 100px; height: 100px; background: blue"/> + </mrow> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math-ref.html new file mode 100644 index 0000000000..c82f395644 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>floating math (reference)</title> +</head> +<body> + <p>Test passes if you see a blue square on the left and a smaller magenta square on the right.</p> + <div> + <div style="display: inline-block; width: 50px; height: 50px; background: magenta"></div> + <div style="float: left"><div style="width: 100px; height: 100px; background: blue"></div></div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math.html new file mode 100644 index 0000000000..1de54ccdcf --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>floating math</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="floating-math-ref.html"/> +<meta name="assert" content="Verify that float applies to the <math> element."> +</head> +<body> + <p>Test passes if you see a blue square on the left and a smaller magenta square on the right.</p> + <div> + <div style="display: inline-block; width: 50px; height: 50px; background: magenta"></div> + <math style="float: left"><mspace width="100px" height="100px" style="background: blue"/></math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/not-floating-001.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/not-floating-001.html new file mode 100644 index 0000000000..7166dea5f8 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/not-floating-001.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>float property in math layout</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<meta name="assert" content="Assert that float property is ignored for most math layout"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<style> + /* .element class defined in mathml-fragments.js */ + .element > * { + padding: 10px; + background: black; + } + /* override display: none on children of maction/semantics */ + maction > *, semantics > * { + display: math; + } +</style> +</head> +<body> + <div id="log"></div> + <div id="container"></div> + + <script> + let container = document.getElementById("container"); + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag) || + FragmentHelper.isEmpty(tag)) + continue; + + // Skip mtable since it does not use display: math. + if (tag == "mtable") + continue; + + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ +<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\ +<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\ +</div>`); + let div = document.body.lastElementChild; + let element = + FragmentHelper.element(div.firstElementChild); + let reference = + FragmentHelper.element(div.lastElementChild); + [element, reference].forEach(parent => { + if (parent.classList.contains("mathml-container") || + parent.classList.contains("foreign-container")) { + FragmentHelper.appendChild(parent); + FragmentHelper.appendChild(parent); + FragmentHelper.appendChild(parent); + } + }); + + // Try to use float to invert the order in which children are normally + // laid out. + function layoutChildrenFromLeftToRight(tag) { tag != 'mroot'; } + element.firstElementChild.style = + `float: ${layoutChildrenFromLeftToRight(tag) ? 'right' : 'left'};`; + element.lastElementChild.style = + `float: ${layoutChildrenFromLeftToRight(tag) ? 'left' : 'right'};`; + + test(function () { + let epsilon = 1; + compareLayout(element, reference, epsilon); + }, `float child ignored in ${tag}`); + + div.style = "display: none;"; // Hide the div after measurement. + } + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/ignored-properties-001.html b/testing/web-platform/tests/mathml/relations/css-styling/ignored-properties-001.html new file mode 100644 index 0000000000..34de5836ea --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/ignored-properties-001.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Ignored CSS properties</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<meta name="assert" content="Verify style with ignored properties does not affect MathML layout."> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag)) + continue; + + var ignoredProperties = [ + "writing-mode: vertical-rl;", + "white-space: normal;", + "float: right;", + "align-content: end; justify-content: end;", + "align-self: end; justify-self: end;", + ]; + + ignoredProperties.forEach(ignoredStyle => { + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ +<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\ +<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\ +</div>`); + var div = document.body.lastElementChild; + + // Create MathML structure with ignored style properties. + var elementContainer = div.firstElementChild; + var elementContainerWidth = elementContainer.getBoundingClientRect().width; + var element = FragmentHelper.element(elementContainer); + if (!FragmentHelper.isEmpty(tag)) + FragmentHelper.forceNonEmptyDescendants(element); + element.setAttribute("style", ignoredStyle); + Array.from(element.getElementsByTagNameNS("*", FragmentHelper.mathml_namespace)).forEach(descendant => { + descendant.setAttribute("style", ignoredStyle); + }); + + var referenceContainer = div.lastElementChild; + var referenceContainerWidth = referenceContainer.getBoundingClientRect().width; + var reference = FragmentHelper.element(referenceContainer); + if (!FragmentHelper.isEmpty(tag)) + FragmentHelper.forceNonEmptyDescendants(reference); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + assert_approx_equals(elementContainerWidth, referenceContainerWidth, epsilon); + }, `${tag} preferred width calculation is not affected by ${ignoredStyle}`); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + compareLayout(element, reference, epsilon); + }, `${tag} layout is not affected by ${ignoredStyle}`); + + div.style = "display: none;"; // Hide the div after measurement. + }); + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute-ref.html new file mode 100644 index 0000000000..8e3d7b1c21 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute-ref.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>legacy scriptminsize attribute (reference)</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math { + /* Ahem font does not have a MATH table so the font-size scale factor + is always 0.71^{computed - inherited math script level} */ + font: 100px/1 Ahem; + } +</style> +</head> +<body> + <p>Test passes if you see a square of size 71px.</p> + <div> + <math> + <mstyle> + <mstyle scriptlevel="1"> + <mn>X</mn> + </mstyle> + </mstyle> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute.html b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute.html new file mode 100644 index 0000000000..0ce87b6147 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>legacy scriptminsize attribute</title> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mstyle.attrs"> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="match" href="legacy-scriptminsize-attribute-ref.html"/> +<meta name="assert" content="Verify scriptminsize attribute is no longer parsed."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math { + /* Ahem font does not have a MATH table so the font-size scale factor + is always 0.71^{computed - inherited math script level} */ + font: 100px/1 Ahem; + } +</style> +</head> +<body> + <p>Test passes if you see a square of size 71px.</p> + <div> + <math> + <mstyle scriptminsize="100px"> + <mstyle scriptlevel="1"> + <mn>X</mn> + </mstyle> + </mstyle> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute-ref.html new file mode 100644 index 0000000000..422325da28 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute-ref.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>legacy scriptsizemultiplier attribute (reference)</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math { + /* Ahem font does not have a MATH table so the font-size scale factor + is always 0.71^{computed - inherited math script level} */ + font: 100px/1 Ahem; + } +</style> +</head> +<body> + <p>Test passes if you see a square of size 71px.</p> + <div> + <math> + <mstyle> + <mstyle scriptlevel="1"> + <mn>X</mn> + </mstyle> + </mstyle> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute.html b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute.html new file mode 100644 index 0000000000..9a955612bc --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>legacy scriptsizemultiplier attribute</title> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mstyle.attrs"> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="match" href="legacy-scriptsizemultiplier-attribute-ref.html"/> +<meta name="assert" content="Verify scriptsizemultiplier attribute is no longer parsed."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + math { + /* Ahem font does not have a MATH table so the font-size scale factor + is always 0.71^{computed - inherited math script level} */ + font: 100px/1 Ahem; + } +</style> +</head> +<body> + <p>Test passes if you see a square of size 71px.</p> + <div> + <math> + <mstyle scriptsizemultiplier="1"> + <mstyle scriptlevel="1"> + <mn>X</mn> + </mstyle> + </mstyle> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/lengths-1-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/lengths-1-ref.html new file mode 100644 index 0000000000..9fca6f4963 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/lengths-1-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML lengths (reference)</title> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + <div> + <div id="red" style="position: absolute; width: 200px; height: 200px; background: green;"> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/lengths-1.html b/testing/web-platform/tests/mathml/relations/css-styling/lengths-1.html new file mode 100644 index 0000000000..896f08d111 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/lengths-1.html @@ -0,0 +1,122 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML lengths</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values"> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<link rel="match" href="lengths-1-ref.html"/> +<meta name="assert" content="Verify whether the different units are accepted for MathML lengths."> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/xheight500.woff"); + } + span, math { + font-family: TestFont; + font-size: 10px; /* 1em = 10px, 1ex is about 5px */ + } + span { + position: absolute; + display: inline-block; + height: 10px; + } + #red > span { + background: red; + } + #green > span { + background: green; + } +</style> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + <div> + <div id="red" style="position: absolute; width: 200px; height: 200px; background: green;"> + <!-- px --> + <span style="top: 0px"><math><mspace width="200px"/></math></span> + <span style="top: 10px; width: 200px"></span> + + <!-- cm --> + <span style="top: 20px"><math><mspace width="5.08cm"/></math></span> + <span style="top: 30px; width: 192px"></span> + + <!-- em --> + <span style="top: 40px"><math><mspace width="20em"/></math></span> + <span style="top: 50px; width: 200px"></span> + + <!-- ex --> + <span style="top: 60px"><math><mspace width="30ex"/></math></span> + <span style="top: 70px; width: 30ex"></span> + + <!-- in --> + <span style="top: 80px"><math><mspace width="2in"/></math></span> + <span style="top: 90px; width: 192px"></span> + + <!-- mm --> + <span style="top: 100px"><math><mspace width="50.8mm"/></math></span> + <span style="top: 110px; width: 192px"></span> + + <!-- pc --> + <span style="top: 120px"><math><mspace width="12.5pc"/></math></span> + <span style="top: 130px; width: 200px"></span> + + <!-- pt --> + <span style="top: 140px"><math><mspace width="150pt"/></math></span> + <span style="top: 150px; width: 200px"></span> + + <!-- % --> + <span style="top: 160px"><math><mstyle mathsize="2000%"><mspace width="1em"/></mstyle></math></span> + <span style="top: 170px; width: 200px"></span> + + <!-- unitless nonzero values should be ignored --> + <span style="top: 180px"><math><mstyle mathsize="20.0"><mspace width="1em"/></mstyle></math></span> + <span style="top: 190px; width: 10px"></span> + </div> + + <div id="green" style="position: absolute; width: 200px; height: 200px;"> + <!-- px --> + <span style="top: 10px"><math><mspace width="200px"/></math></span> + <span style="top: 0px; width: 200px"></span> + + <!-- cm --> + <span style="top: 30px"><math><mspace width="5.08cm"/></math></span> + <span style="top: 20px; width: 192px"></span> + + <!-- em --> + <span title="em" style="top: 50px"><math><mspace width="20em"/></math></span> + <span title="em" style="top: 40px; width: 200px"></span> + + <!-- ex --> + <span title="ex" style="top: 70px"><math><mspace width="30ex"/></math></span> + <span title="ex" style="top: 60px; width: 30ex"></span> + + <!-- in --> + <span style="top: 90px"><math><mspace width="2in"/></math></span> + <span style="top: 80px; width: 192px"></span> + + <!-- mm --> + <span style="top: 110px"><math><mspace width="50.8mm"/></math></span> + <span style="top: 100px; width: 192px"></span> + + <!-- pc --> + <span style="top: 130px"><math><mspace width="12.5pc"/></math></span> + <span style="top: 120px; width: 200px"></span> + + <!-- pt --> + <span style="top: 150px"><math><mspace width="150pt"/></math></span> + <span style="top: 140px; width: 200px"></span> + + <!-- % --> + <span style="top: 170px"><math><mstyle mathsize="2000%"><mspace width="1em"/></mstyle></math></span> + <span style="top: 160px; width: 200px"></span> + + <!-- unitless nonzero values should be ignored --> + <span style="top: 190px"><math><mstyle mathsize="20.0"><mspace width="1em"/></mstyle></math></span> + <span style="top: 180px; width: 10px"></span> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/lengths-2.html b/testing/web-platform/tests/mathml/relations/css-styling/lengths-2.html new file mode 100644 index 0000000000..942611a8da --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/lengths-2.html @@ -0,0 +1,266 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>MathML lengths</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values"> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<meta name="assert" content="Verify various cases of the MathML length syntax."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/fonts.js"></script> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/xheight500.woff"); + } + math { + font-family: TestFont; + font-size: 10px; + } +</style> +<script> + var epsilon = .5; + + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_equals(getBox("unitCm").width, 96, "cm"); + assert_equals(getBox("unitEm").width, 120, "em"); + assert_equals(getBox("unitEx").width, 500, "ex"); + assert_equals(getBox("unitIn").width, 288, "in"); + assert_equals(getBox("unitMm").width, 576, "mm"); + assert_equals(getBox("unitPc").width, 96, "pc"); + assert_equals(getBox("unitPercentage").width, 60, "%"); + assert_equals(getBox("unitPt").width, 96, "pt"); + assert_equals(getBox("unitPx").width, 123, "px"); + }, "Units"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_equals(getBox("spaceCm").width, 96, "cm"); + assert_equals(getBox("spaceEm").width, 120, "em"); + assert_equals(getBox("spaceEx").width, 500, "ex"); + assert_equals(getBox("spaceIn").width, 288, "in"); + assert_equals(getBox("spaceMm").width, 576, "mm"); + assert_equals(getBox("spacePc").width, 96, "pc"); + assert_equals(getBox("spacePercentage").width, 60, "%"); + assert_equals(getBox("spacePt").width, 96, "pt"); + assert_equals(getBox("spacePx").width, 123, "px"); + }, "Trimming of space"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(getBox("n0").width, 0, epsilon, "n0"); + assert_approx_equals(getBox("n1").width, 90, epsilon, "n1"); + assert_approx_equals(getBox("n2").width, 8, epsilon, "n2"); + assert_approx_equals(getBox("n4").width, 650, epsilon, "n4"); + assert_approx_equals(getBox("n5").width, 4320, epsilon, "n5"); + assert_approx_equals(getBox("n6").width, 1, epsilon, "n6"); + assert_approx_equals(getBox("n7").width, 8, epsilon, "n7"); + assert_approx_equals(getBox("n8").width, 65, epsilon, "n8"); + assert_approx_equals(getBox("n9").width, 432, epsilon, "n9"); + assert_approx_equals(getBox("n10").width, 123, epsilon, "n10"); + }, "Non-negative numbers"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var topRef = getBox("ref").top; + assert_approx_equals(getBox("N0").top - topRef, -0, epsilon, "N0"); + assert_approx_equals(topRef - getBox("N1").top, -90, epsilon, "N1"); + assert_approx_equals(topRef - getBox("N2").top, -8, epsilon, "N2"); + assert_approx_equals(topRef - getBox("N4").top, -650, epsilon, "N4"); + assert_approx_equals(topRef - getBox("N5").top, -4320, epsilon, "N5"); + assert_approx_equals(topRef - getBox("N6").top, -1, epsilon, "N6"); + assert_approx_equals(topRef - getBox("N7").top, -8, epsilon, "N7"); + assert_approx_equals(topRef - getBox("N8").top, -65, epsilon, "N8"); + assert_approx_equals(topRef - getBox("N9").top, -432, epsilon, "N9"); + assert_approx_equals(topRef - getBox("N10").top, -123, epsilon, "N10"); + }, "Non-positive numbers"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + // Namedspace values are invalid in MathML Core. + ["veryverythinmathspace", + "verythinmathspace", + "thinmathspace", + "mediummathspace", + "thickmathspace", + "verythickmathspace", + "veryverythickmathspace", + "negativeveryverythinmathspace", + "negativeverythinmathspace", + "negativethinmathspace", + "negativemediummathspace", + "negativethickmathspace", + "negativeverythickmathspace", + "negativeveryverythickmathspace" + ].forEach(function(space) { + var mrow = document.getElementById(space); + var boxBefore = mrow.firstElementChild.getBoundingClientRect(); + var boxAfter = mrow.lastElementChild.getBoundingClientRect(); + assert_equals(boxAfter.left - boxBefore.right, 0, space); + }); + }, "Legacy namedspaces"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + // These values are invalid in MathML Core. + assert_equals(getBox("unitNone").width, 30, "Unitless"); + assert_approx_equals(getBox("n3").width, 0, epsilon, "n3"); + var topRef = getBox("ref").top; + assert_approx_equals(topRef - getBox("N3").top, 0, epsilon, "N3"); + }, "Legacy numbers"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mspace id="unitCm" width="2.54cm"/> + <mspace id="unitEm" width="12em"/> + <mspace id="unitEx" width="100ex"/> + <mspace id="unitIn" width="3in"/> + <mspace id="unitMm" width="152.4mm"/> + <mspace id="unitPc" width="6pc"/> + <mstyle mathsize="200%"><mspace id="unitPercentage" width="3em"/></mstyle> + <mspace id="unitPt" width="72pt"/> + <mspace id="unitPx" width="123px"/> + <mstyle mathsize="5"><mspace id="unitNone" width="3em"/></mstyle> + </math> + </p> + <p> + <math> + <mspace id="spaceCm" width=" 	

 	

2.54cm 	

 	

"/> + <mspace id="spaceEm" width=" 	

 	

12em 	

 	

"/> + <mspace id="spaceEx" width=" 	

 	

100ex 	

 	

"/> + <mspace id="spaceIn" width=" 	

 	

3in 	

 	

"/> + <mspace id="spaceMm" width=" 	

 	

152.4mm 	

 	

"/> + <mspace id="spacePc" width=" 	

 	

6pc 	

 	

"/> + <mstyle mathsize="200%"><mspace id="spacePercentage" width=" 	

 	

3em 	

 	

"/></mstyle> + <mspace id="spacePt" width=" 	

 	

72pt 	

 	

"/> + <mspace id="spacePx" width=" 	

 	

123px 	

 	

"/> + </math> + </p> + <p> + <math> + <mspace id="n0" width="0em"/> + <mspace id="n1" width="9em"/> + <mspace id="n2" width=".8em"/> + <mspace id="n3" width="7.em"/> + <mspace id="n4" width="65em"/> + <mspace id="n5" width="432em"/> + <mspace id="n6" width=".10em"/> + <mspace id="n7" width=".789em"/> + <mspace id="n8" width="6.5em"/> + <mspace id="n9" width="43.21em"/> + <mspace id="n10" width="012.345em"/> + </math> + </p> + <p> + <math> + <mspace id="ref"></mspace> + <mpadded voffset="-0em"><mspace id="N0"/></mpadded> + <mpadded voffset="-9em"><mspace id="N1"/></mpadded> + <mpadded voffset="-.8em"><mspace id="N2"/></mpadded> + <mpadded voffset="-7.em"><mspace id="N3"/></mpadded> + <mpadded voffset="-65em"><mspace id="N4"/></mpadded> + <mpadded voffset="-432em"><mspace id="N5"/></mpadded> + <mpadded voffset="-.10em"><mspace id="N6"/></mpadded> + <mpadded voffset="-.789em"><mspace id="N7"/></mpadded> + <mpadded voffset="-6.5em"><mspace id="N8"/></mpadded> + <mpadded voffset="-43.21em"><mspace id="N9"/></mpadded> + <mpadded voffset="-012.345em"><mspace id="N10"/></mpadded> + </math> + </p> + <p> + <math> + <mrow id="veryverythinmathspace"> + <mspace width="1em"/> + <mspace width="veryverythinmathspace"/> + <mspace/> + </mrow> + <mrow id="verythinmathspace"> + <mspace width="1em"/> + <mspace width="verythinmathspace"/> + <mspace/> + </mrow> + <mrow id="thinmathspace"> + <mspace width="1em"/> + <mspace width="thinmathspace"/> + <mspace/> + </mrow> + <mrow id="mediummathspace"> + <mspace width="1em"/> + <mspace width="mediummathspace"/> + <mspace/> + </mrow> + <mrow id="thickmathspace"> + <mspace width="1em"/> + <mspace width="thickmathspace"/> + <mspace/> + </mrow> + <mrow id="verythickmathspace"> + <mspace width="1em"/> + <mspace width="verythickmathspace"/> + <mspace/> + </mrow> + <mrow id="veryverythickmathspace"> + <mspace width="1em"/> + <mspace width="veryverythickmathspace"/> + <mspace/> + </mrow> + </math> + <math> + <mrow id="negativeveryverythinmathspace"> + <mspace width="1em"/> + <mspace width="veryverythinmathspace"/> + <mspace/> + </mrow> + <mrow id="negativeverythinmathspace"> + <mspace width="1em"/> + <mspace width="verythinmathspace"/> + <mspace/> + </mrow> + <mrow id="negativethinmathspace"> + <mspace width="1em"/> + <mspace width="thinmathspace"/> + <mspace/> + </mrow> + <mrow id="negativemediummathspace"> + <mspace width="1em"/> + <mspace width="mediummathspace"/> + <mspace/> + </mrow> + <mrow id="negativethickmathspace"> + <mspace width="1em"/> + <mspace width="thickmathspace"/> + <mspace/> + </mrow> + <mrow id="negativeverythickmathspace"> + <mspace width="1em"/> + <mspace width="verythickmathspace"/> + <mspace/> + </mrow> + <mrow id="negativeveryverythickmathspace"> + <mspace width="1em"/> + <mspace width="veryverythickmathspace"/> + <mspace/> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001-notref.html new file mode 100644 index 0000000000..65e2781c5e --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001-notref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathbackground on mrow (reference)</title> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mrow mathbackground="green"> + <mtext>□■□■□■□</mtext> + </mrow> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001.html new file mode 100644 index 0000000000..e71fc53eaa --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathbackground on mrow</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="mismatch" href="mathbackground-001-notref.html"/> +<meta name="assert" content="mathbackground on a mrow has a visual effect."> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mrow mathbackground="red"> + <mtext>□■□■□■□</mtext> + </mrow> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002-notref.html new file mode 100644 index 0000000000..8c984c2619 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002-notref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathbackground on mstyle (reference)</title> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mstyle mathbackground="green"> + <mtext>□■□■□■□</mtext> + </mstyle> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002.html new file mode 100644 index 0000000000..09407d9269 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathbackground on mstyle</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> +<link rel="mismatch" href="mathbackground-002-notref.html"/> +<meta name="assert" content="mathbackground on a mstyle has a visual effect."> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mstyle mathbackground="red"> + <mtext>□■□■□■□</mtext> + </mstyle> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003-notref.html new file mode 100644 index 0000000000..b6adaa8d4e --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003-notref.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathbackground on mtext (reference)</title> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mtext mathbackground="green">□■□■□■□</mtext> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003.html new file mode 100644 index 0000000000..8cb11889db --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathbackground on mtext</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="mismatch" href="mathbackground-003-notref.html"/> +<meta name="assert" content="mathbackground on a mtext has a visual effect."> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mtext mathbackground="red">□■□■□■□</mtext> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004-notref.html new file mode 100644 index 0000000000..75465a6c38 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004-notref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathbackground on semantics (reference)</title> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <semantics mathbackground="red"> + <mtext>□■□■□■□</mtext> + </semantics> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004.html new file mode 100644 index 0000000000..be174cdbde --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathbackground on semantics</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#semantics-and-presentation"> +<link rel="mismatch" href="mathbackground-004-notref.html"/> +<meta name="assert" content="mathbackground on a semantics has a visual effect."> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <semantics mathbackground="green"> + <mtext>□■□■□■□</mtext> + </semantics> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001-notref.html new file mode 100644 index 0000000000..9bc1ba5436 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001-notref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathcolor on mrow (reference)</title> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mrow mathcolor="green"> + <mtext>□■□■□■□</mtext> + </mrow> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001.html new file mode 100644 index 0000000000..2c463cac87 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathcolor on mrow</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow"> +<link rel="mismatch" href="mathcolor-001-notref.html"/> +<meta name="assert" content="mathcolor on a mrow has a visual effect."> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mrow mathcolor="red"> + <mtext>□■□■□■□</mtext> + </mrow> +</math> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002-notref.html new file mode 100644 index 0000000000..5f9fd2bb9b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002-notref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathcolor on mstyle (reference)</title> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mstyle mathcolor="green"> + <mtext>□■□■□■□</mtext> + </mstyle> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002.html new file mode 100644 index 0000000000..147d41b46d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathcolor on mstyle</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle"> +<link rel="mismatch" href="mathcolor-002-notref.html"/> +<meta name="assert" content="mathcolor on a mstyle has a visual effect."> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mstyle mathcolor="red"> + <mtext>□■□■□■□</mtext> + </mstyle> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003-notref.html new file mode 100644 index 0000000000..11e018ebc1 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003-notref.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathcolor on mtext (reference)</title> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mtext mathcolor="green">□■□■□■□</mtext> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003.html new file mode 100644 index 0000000000..5565b0d837 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathcolor on mtext</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="mismatch" href="mathcolor-003-notref.html"/> +<meta name="assert" content="mathcolor on a mtext has a visual effect."> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <mtext mathcolor="red">□■□■□■□</mtext> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004-notref.html new file mode 100644 index 0000000000..67a45249e5 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004-notref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathcolor on semantics (reference)</title> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <semantics mathcolor="red"> + <mtext>□■□■□■□</mtext> + </semantics> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004.html new file mode 100644 index 0000000000..3ea37fecdb --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>mathcolor on semantics</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#semantics-and-presentation"> +<link rel="mismatch" href="mathcolor-004-notref.html"/> +<meta name="assert" content="mathcolor on a semantics has a visual effect."> +<math xmlns="http://www.w3.org/1998/Math/MathML"> + <semantics mathcolor="green"> + <mtext>□■□■□■□</mtext> + </semantics> +</math> + diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css-ref.html new file mode 100644 index 0000000000..682fa64233 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css-ref.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS color (reference)</title> +<link rel="stylesheet" href="/fonts/ahem.css"> +<style> + math { + font-family: Ahem; + font-size: 20px; + } +</style> +</style> +</head> +<body> + <p>Test passes if you see a green rectangle:</p> + <p> + <math mathbackground="#0f0" mathcolor="#0f0"> + <mtext>X X</mtext> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css.html new file mode 100644 index 0000000000..2f53215346 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS color</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values"> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="match" href="mathcolor-mathbackground-css-ref.html"/> +<link rel="stylesheet" href="/fonts/ahem.css"> +<meta name="assert" content="Verify that the mathcolor and mathbackground attributes use the CSS definition of colors."> +<style> + math { + font-family: Ahem; + font-size: 20px; + } +</style> +</style> +</head> +<body> + <p>Test passes if you see a green rectangle:</p> + <p style="color: red"> + <math mathbackground="rgb(0,255,0)" mathcolor="rgb(0,255,0)"> + <mtext>X X</mtext> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html new file mode 100644 index 0000000000..ebb12a6c6c --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>mathsize and css keywords</title> + </head> + <body> + <p>Test passes if you see 14 "A" of equal size:</p> + <math> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords.html new file mode 100644 index 0000000000..2daed4cdea --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>mathsize and css keywords</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> + <meta name="assert" content="Verify that CSS font-size keywords are invalid for the mathsize attribute."> + <link rel="match" href="mathsize-attribute-css-keywords-ref.html"> + <script src="/mathml/support/feature-detection.js"></script> + </head> + <body> + <p>Test passes if you see 14 "A" of equal size:</p> + <math> + <mtext>A</mtext> + <mtext mathsize="xx-small">A</mtext> + <mtext mathsize="x-small">A</mtext> + <mtext mathsize="small">A</mtext> + <mtext mathsize="medium">A</mtext> + <mtext mathsize="large">A</mtext> + <mtext mathsize="x-large">A</mtext> + <mtext mathsize="xx-large">A</mtext> + <mtext mathsize="larger">A</mtext> + <mtext mathsize="smaller">A</mtext> + <mtext mathsize="xx-ſmall">A</mtext> + <mtext mathsize="x-ſmall">A</mtext> + <mtext mathsize="ſmall">A</mtext> + <mtext mathsize="ſmaller">A</mtext> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mathsize");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values-ref.html new file mode 100644 index 0000000000..687efa49be --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Legacy mathsize values</title> + </head> + <body> + <p>Test passes if you see four "A" of equal size:</p> + <math> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + <mtext>A</mtext> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values.html new file mode 100644 index 0000000000..aebf09f9b8 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Legacy mathsize values</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> + <meta name="assert" content="Verify that legacy values for mathsize have no effect."> + <link rel="match" href="mathsize-attribute-legacy-values-ref.html"> + <script src="/mathml/support/feature-detection.js"></script> + </head> + <body> + <p>Test passes if you see four "A" of equal size:</p> + <math> + <mtext>A</mtext> + <mtext mathsize="small">A</mtext> + <mtext mathsize="medium">A</mtext> + <mtext mathsize="big">A</mtext> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mathsize");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-ref.html new file mode 100644 index 0000000000..7a0450e51e --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-ref.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Verify mathsize attribute</title> + </head> + <body> + + <!-- The style attribute should have the same effect as the mathsize + attribute. --> + <div> + <math> + <mi style="font-size: 200%;">x</mi> + <mi style="font-size: 3em;">x</mi> + </math> + </div> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute.html new file mode 100644 index 0000000000..66bcb6dd25 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Verify mathsize attribute</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> + <meta name="assert" content="Verify mathsize attribute values."> + <link rel="match" href="mathsize-attribute-ref.html"> + </head> + <body> + + <!-- This verifies the effect of the mathsize attribute. --> + <div> + <math> + <mi mathsize="200%">x</mi> + <mi mathsize="3em">x</mi> + </math> + </div> + + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto-ref.html new file mode 100644 index 0000000000..105ba412e6 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto-ref.html @@ -0,0 +1,139 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>mathvariant auto (reference)</title> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/mathvariant-italic.woff"); + } + body > span { + padding: 10px; + } + span > span { + font-family: monospace; + font-size: 10px; + } + .testfont { + font-family: TestFont; + font-size: 10px; + } +</style> +<body> + <!-- Generated by mathml/tools/mathvariant.py; DO NOT EDIT. --> + <p>Test passes if all the equalities below are true.</p> + <span><math class="testfont"><mi>𝐴</mi></math>=<span>1D434</span></span> + <span><math class="testfont"><mi>𝐵</mi></math>=<span>1D435</span></span> + <span><math class="testfont"><mi>𝐶</mi></math>=<span>1D436</span></span> + <span><math class="testfont"><mi>𝐷</mi></math>=<span>1D437</span></span> + <span><math class="testfont"><mi>𝐸</mi></math>=<span>1D438</span></span> + <span><math class="testfont"><mi>𝐹</mi></math>=<span>1D439</span></span> + <span><math class="testfont"><mi>𝐺</mi></math>=<span>1D43A</span></span> + <span><math class="testfont"><mi>𝐻</mi></math>=<span>1D43B</span></span> + <span><math class="testfont"><mi>𝐼</mi></math>=<span>1D43C</span></span> + <span><math class="testfont"><mi>𝐽</mi></math>=<span>1D43D</span></span><br/> + <span><math class="testfont"><mi>𝐾</mi></math>=<span>1D43E</span></span> + <span><math class="testfont"><mi>𝐿</mi></math>=<span>1D43F</span></span> + <span><math class="testfont"><mi>𝑀</mi></math>=<span>1D440</span></span> + <span><math class="testfont"><mi>𝑁</mi></math>=<span>1D441</span></span> + <span><math class="testfont"><mi>𝑂</mi></math>=<span>1D442</span></span> + <span><math class="testfont"><mi>𝑃</mi></math>=<span>1D443</span></span> + <span><math class="testfont"><mi>𝑄</mi></math>=<span>1D444</span></span> + <span><math class="testfont"><mi>𝑅</mi></math>=<span>1D445</span></span> + <span><math class="testfont"><mi>𝑆</mi></math>=<span>1D446</span></span> + <span><math class="testfont"><mi>𝑇</mi></math>=<span>1D447</span></span><br/> + <span><math class="testfont"><mi>𝑈</mi></math>=<span>1D448</span></span> + <span><math class="testfont"><mi>𝑉</mi></math>=<span>1D449</span></span> + <span><math class="testfont"><mi>𝑊</mi></math>=<span>1D44A</span></span> + <span><math class="testfont"><mi>𝑋</mi></math>=<span>1D44B</span></span> + <span><math class="testfont"><mi>𝑌</mi></math>=<span>1D44C</span></span> + <span><math class="testfont"><mi>𝑍</mi></math>=<span>1D44D</span></span> + <span><math class="testfont"><mi>𝑎</mi></math>=<span>1D44E</span></span> + <span><math class="testfont"><mi>𝑏</mi></math>=<span>1D44F</span></span> + <span><math class="testfont"><mi>𝑐</mi></math>=<span>1D450</span></span> + <span><math class="testfont"><mi>𝑑</mi></math>=<span>1D451</span></span><br/> + <span><math class="testfont"><mi>𝑒</mi></math>=<span>1D452</span></span> + <span><math class="testfont"><mi>𝑓</mi></math>=<span>1D453</span></span> + <span><math class="testfont"><mi>𝑔</mi></math>=<span>1D454</span></span> + <span><math class="testfont"><mi>ℎ</mi></math>=<span>0210E</span></span> + <span><math class="testfont"><mi>𝑖</mi></math>=<span>1D456</span></span> + <span><math class="testfont"><mi>𝑗</mi></math>=<span>1D457</span></span> + <span><math class="testfont"><mi>𝑘</mi></math>=<span>1D458</span></span> + <span><math class="testfont"><mi>𝑙</mi></math>=<span>1D459</span></span> + <span><math class="testfont"><mi>𝑚</mi></math>=<span>1D45A</span></span> + <span><math class="testfont"><mi>𝑛</mi></math>=<span>1D45B</span></span><br/> + <span><math class="testfont"><mi>𝑜</mi></math>=<span>1D45C</span></span> + <span><math class="testfont"><mi>𝑝</mi></math>=<span>1D45D</span></span> + <span><math class="testfont"><mi>𝑞</mi></math>=<span>1D45E</span></span> + <span><math class="testfont"><mi>𝑟</mi></math>=<span>1D45F</span></span> + <span><math class="testfont"><mi>𝑠</mi></math>=<span>1D460</span></span> + <span><math class="testfont"><mi>𝑡</mi></math>=<span>1D461</span></span> + <span><math class="testfont"><mi>𝑢</mi></math>=<span>1D462</span></span> + <span><math class="testfont"><mi>𝑣</mi></math>=<span>1D463</span></span> + <span><math class="testfont"><mi>𝑤</mi></math>=<span>1D464</span></span> + <span><math class="testfont"><mi>𝑥</mi></math>=<span>1D465</span></span><br/> + <span><math class="testfont"><mi>𝑦</mi></math>=<span>1D466</span></span> + <span><math class="testfont"><mi>𝑧</mi></math>=<span>1D467</span></span> + <span><math class="testfont"><mi>𝚤</mi></math>=<span>1D6A4</span></span> + <span><math class="testfont"><mi>𝚥</mi></math>=<span>1D6A5</span></span> + <span><math class="testfont"><mi>𝛢</mi></math>=<span>1D6E2</span></span> + <span><math class="testfont"><mi>𝛣</mi></math>=<span>1D6E3</span></span> + <span><math class="testfont"><mi>𝛤</mi></math>=<span>1D6E4</span></span> + <span><math class="testfont"><mi>𝛥</mi></math>=<span>1D6E5</span></span> + <span><math class="testfont"><mi>𝛦</mi></math>=<span>1D6E6</span></span> + <span><math class="testfont"><mi>𝛧</mi></math>=<span>1D6E7</span></span><br/> + <span><math class="testfont"><mi>𝛨</mi></math>=<span>1D6E8</span></span> + <span><math class="testfont"><mi>𝛩</mi></math>=<span>1D6E9</span></span> + <span><math class="testfont"><mi>𝛪</mi></math>=<span>1D6EA</span></span> + <span><math class="testfont"><mi>𝛫</mi></math>=<span>1D6EB</span></span> + <span><math class="testfont"><mi>𝛬</mi></math>=<span>1D6EC</span></span> + <span><math class="testfont"><mi>𝛭</mi></math>=<span>1D6ED</span></span> + <span><math class="testfont"><mi>𝛮</mi></math>=<span>1D6EE</span></span> + <span><math class="testfont"><mi>𝛯</mi></math>=<span>1D6EF</span></span> + <span><math class="testfont"><mi>𝛰</mi></math>=<span>1D6F0</span></span> + <span><math class="testfont"><mi>𝛱</mi></math>=<span>1D6F1</span></span><br/> + <span><math class="testfont"><mi>𝛲</mi></math>=<span>1D6F2</span></span> + <span><math class="testfont"><mi>𝛳</mi></math>=<span>1D6F3</span></span> + <span><math class="testfont"><mi>𝛴</mi></math>=<span>1D6F4</span></span> + <span><math class="testfont"><mi>𝛵</mi></math>=<span>1D6F5</span></span> + <span><math class="testfont"><mi>𝛶</mi></math>=<span>1D6F6</span></span> + <span><math class="testfont"><mi>𝛷</mi></math>=<span>1D6F7</span></span> + <span><math class="testfont"><mi>𝛸</mi></math>=<span>1D6F8</span></span> + <span><math class="testfont"><mi>𝛹</mi></math>=<span>1D6F9</span></span> + <span><math class="testfont"><mi>𝛺</mi></math>=<span>1D6FA</span></span> + <span><math class="testfont"><mi>𝛻</mi></math>=<span>1D6FB</span></span><br/> + <span><math class="testfont"><mi>𝛼</mi></math>=<span>1D6FC</span></span> + <span><math class="testfont"><mi>𝛽</mi></math>=<span>1D6FD</span></span> + <span><math class="testfont"><mi>𝛾</mi></math>=<span>1D6FE</span></span> + <span><math class="testfont"><mi>𝛿</mi></math>=<span>1D6FF</span></span> + <span><math class="testfont"><mi>𝜀</mi></math>=<span>1D700</span></span> + <span><math class="testfont"><mi>𝜁</mi></math>=<span>1D701</span></span> + <span><math class="testfont"><mi>𝜂</mi></math>=<span>1D702</span></span> + <span><math class="testfont"><mi>𝜃</mi></math>=<span>1D703</span></span> + <span><math class="testfont"><mi>𝜄</mi></math>=<span>1D704</span></span> + <span><math class="testfont"><mi>𝜅</mi></math>=<span>1D705</span></span><br/> + <span><math class="testfont"><mi>𝜆</mi></math>=<span>1D706</span></span> + <span><math class="testfont"><mi>𝜇</mi></math>=<span>1D707</span></span> + <span><math class="testfont"><mi>𝜈</mi></math>=<span>1D708</span></span> + <span><math class="testfont"><mi>𝜉</mi></math>=<span>1D709</span></span> + <span><math class="testfont"><mi>𝜊</mi></math>=<span>1D70A</span></span> + <span><math class="testfont"><mi>𝜋</mi></math>=<span>1D70B</span></span> + <span><math class="testfont"><mi>𝜌</mi></math>=<span>1D70C</span></span> + <span><math class="testfont"><mi>𝜍</mi></math>=<span>1D70D</span></span> + <span><math class="testfont"><mi>𝜎</mi></math>=<span>1D70E</span></span> + <span><math class="testfont"><mi>𝜏</mi></math>=<span>1D70F</span></span><br/> + <span><math class="testfont"><mi>𝜐</mi></math>=<span>1D710</span></span> + <span><math class="testfont"><mi>𝜑</mi></math>=<span>1D711</span></span> + <span><math class="testfont"><mi>𝜒</mi></math>=<span>1D712</span></span> + <span><math class="testfont"><mi>𝜓</mi></math>=<span>1D713</span></span> + <span><math class="testfont"><mi>𝜔</mi></math>=<span>1D714</span></span> + <span><math class="testfont"><mi>𝜕</mi></math>=<span>1D715</span></span> + <span><math class="testfont"><mi>𝜖</mi></math>=<span>1D716</span></span> + <span><math class="testfont"><mi>𝜗</mi></math>=<span>1D717</span></span> + <span><math class="testfont"><mi>𝜘</mi></math>=<span>1D718</span></span> + <span><math class="testfont"><mi>𝜙</mi></math>=<span>1D719</span></span><br/> + <span><math class="testfont"><mi>𝜚</mi></math>=<span>1D71A</span></span> + <span><math class="testfont"><mi>𝜛</mi></math>=<span>1D71B</span></span> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto.html b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto.html new file mode 100644 index 0000000000..affb02f0c9 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto.html @@ -0,0 +1,145 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>mathvariant auto</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://w3c.github.io/mathml-core/#new-text-transform-values"> +<link rel="help" href="https://w3c.github.io/mathml-core/#italic-mappings"> +<link rel="match" href="mathvariant-auto-ref.html"/> +<meta name="assert" content="Verify that a single-char <mi> is equivalent to an <mi> with the transformed italic unicode character."> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/mathvariant-italic.woff"); + } + body > span { + padding: 10px; + } + span > span { + font-family: monospace; + font-size: 10px; + } + .testfont { + font-family: TestFont; + font-size: 10px; + } +</style> +<body> + <!-- Generated by mathml/tools/mathvariant.py; DO NOT EDIT. --> + <p>Test passes if all the equalities below are true.</p> + <span><math class="testfont"><mi>A</mi></math>=<span>1D434</span></span> + <span><math class="testfont"><mi>B</mi></math>=<span>1D435</span></span> + <span><math class="testfont"><mi>C</mi></math>=<span>1D436</span></span> + <span><math class="testfont"><mi>D</mi></math>=<span>1D437</span></span> + <span><math class="testfont"><mi>E</mi></math>=<span>1D438</span></span> + <span><math class="testfont"><mi>F</mi></math>=<span>1D439</span></span> + <span><math class="testfont"><mi>G</mi></math>=<span>1D43A</span></span> + <span><math class="testfont"><mi>H</mi></math>=<span>1D43B</span></span> + <span><math class="testfont"><mi>I</mi></math>=<span>1D43C</span></span> + <span><math class="testfont"><mi>J</mi></math>=<span>1D43D</span></span><br/> + <span><math class="testfont"><mi>K</mi></math>=<span>1D43E</span></span> + <span><math class="testfont"><mi>L</mi></math>=<span>1D43F</span></span> + <span><math class="testfont"><mi>M</mi></math>=<span>1D440</span></span> + <span><math class="testfont"><mi>N</mi></math>=<span>1D441</span></span> + <span><math class="testfont"><mi>O</mi></math>=<span>1D442</span></span> + <span><math class="testfont"><mi>P</mi></math>=<span>1D443</span></span> + <span><math class="testfont"><mi>Q</mi></math>=<span>1D444</span></span> + <span><math class="testfont"><mi>R</mi></math>=<span>1D445</span></span> + <span><math class="testfont"><mi>S</mi></math>=<span>1D446</span></span> + <span><math class="testfont"><mi>T</mi></math>=<span>1D447</span></span><br/> + <span><math class="testfont"><mi>U</mi></math>=<span>1D448</span></span> + <span><math class="testfont"><mi>V</mi></math>=<span>1D449</span></span> + <span><math class="testfont"><mi>W</mi></math>=<span>1D44A</span></span> + <span><math class="testfont"><mi>X</mi></math>=<span>1D44B</span></span> + <span><math class="testfont"><mi>Y</mi></math>=<span>1D44C</span></span> + <span><math class="testfont"><mi>Z</mi></math>=<span>1D44D</span></span> + <span><math class="testfont"><mi>a</mi></math>=<span>1D44E</span></span> + <span><math class="testfont"><mi>b</mi></math>=<span>1D44F</span></span> + <span><math class="testfont"><mi>c</mi></math>=<span>1D450</span></span> + <span><math class="testfont"><mi>d</mi></math>=<span>1D451</span></span><br/> + <span><math class="testfont"><mi>e</mi></math>=<span>1D452</span></span> + <span><math class="testfont"><mi>f</mi></math>=<span>1D453</span></span> + <span><math class="testfont"><mi>g</mi></math>=<span>1D454</span></span> + <span><math class="testfont"><mi>h</mi></math>=<span>0210E</span></span> + <span><math class="testfont"><mi>i</mi></math>=<span>1D456</span></span> + <span><math class="testfont"><mi>j</mi></math>=<span>1D457</span></span> + <span><math class="testfont"><mi>k</mi></math>=<span>1D458</span></span> + <span><math class="testfont"><mi>l</mi></math>=<span>1D459</span></span> + <span><math class="testfont"><mi>m</mi></math>=<span>1D45A</span></span> + <span><math class="testfont"><mi>n</mi></math>=<span>1D45B</span></span><br/> + <span><math class="testfont"><mi>o</mi></math>=<span>1D45C</span></span> + <span><math class="testfont"><mi>p</mi></math>=<span>1D45D</span></span> + <span><math class="testfont"><mi>q</mi></math>=<span>1D45E</span></span> + <span><math class="testfont"><mi>r</mi></math>=<span>1D45F</span></span> + <span><math class="testfont"><mi>s</mi></math>=<span>1D460</span></span> + <span><math class="testfont"><mi>t</mi></math>=<span>1D461</span></span> + <span><math class="testfont"><mi>u</mi></math>=<span>1D462</span></span> + <span><math class="testfont"><mi>v</mi></math>=<span>1D463</span></span> + <span><math class="testfont"><mi>w</mi></math>=<span>1D464</span></span> + <span><math class="testfont"><mi>x</mi></math>=<span>1D465</span></span><br/> + <span><math class="testfont"><mi>y</mi></math>=<span>1D466</span></span> + <span><math class="testfont"><mi>z</mi></math>=<span>1D467</span></span> + <span><math class="testfont"><mi>ı</mi></math>=<span>1D6A4</span></span> + <span><math class="testfont"><mi>ȷ</mi></math>=<span>1D6A5</span></span> + <span><math class="testfont"><mi>Α</mi></math>=<span>1D6E2</span></span> + <span><math class="testfont"><mi>Β</mi></math>=<span>1D6E3</span></span> + <span><math class="testfont"><mi>Γ</mi></math>=<span>1D6E4</span></span> + <span><math class="testfont"><mi>Δ</mi></math>=<span>1D6E5</span></span> + <span><math class="testfont"><mi>Ε</mi></math>=<span>1D6E6</span></span> + <span><math class="testfont"><mi>Ζ</mi></math>=<span>1D6E7</span></span><br/> + <span><math class="testfont"><mi>Η</mi></math>=<span>1D6E8</span></span> + <span><math class="testfont"><mi>Θ</mi></math>=<span>1D6E9</span></span> + <span><math class="testfont"><mi>Ι</mi></math>=<span>1D6EA</span></span> + <span><math class="testfont"><mi>Κ</mi></math>=<span>1D6EB</span></span> + <span><math class="testfont"><mi>Λ</mi></math>=<span>1D6EC</span></span> + <span><math class="testfont"><mi>Μ</mi></math>=<span>1D6ED</span></span> + <span><math class="testfont"><mi>Ν</mi></math>=<span>1D6EE</span></span> + <span><math class="testfont"><mi>Ξ</mi></math>=<span>1D6EF</span></span> + <span><math class="testfont"><mi>Ο</mi></math>=<span>1D6F0</span></span> + <span><math class="testfont"><mi>Π</mi></math>=<span>1D6F1</span></span><br/> + <span><math class="testfont"><mi>Ρ</mi></math>=<span>1D6F2</span></span> + <span><math class="testfont"><mi>ϴ</mi></math>=<span>1D6F3</span></span> + <span><math class="testfont"><mi>Σ</mi></math>=<span>1D6F4</span></span> + <span><math class="testfont"><mi>Τ</mi></math>=<span>1D6F5</span></span> + <span><math class="testfont"><mi>Υ</mi></math>=<span>1D6F6</span></span> + <span><math class="testfont"><mi>Φ</mi></math>=<span>1D6F7</span></span> + <span><math class="testfont"><mi>Χ</mi></math>=<span>1D6F8</span></span> + <span><math class="testfont"><mi>Ψ</mi></math>=<span>1D6F9</span></span> + <span><math class="testfont"><mi>Ω</mi></math>=<span>1D6FA</span></span> + <span><math class="testfont"><mi>∇</mi></math>=<span>1D6FB</span></span><br/> + <span><math class="testfont"><mi>α</mi></math>=<span>1D6FC</span></span> + <span><math class="testfont"><mi>β</mi></math>=<span>1D6FD</span></span> + <span><math class="testfont"><mi>γ</mi></math>=<span>1D6FE</span></span> + <span><math class="testfont"><mi>δ</mi></math>=<span>1D6FF</span></span> + <span><math class="testfont"><mi>ε</mi></math>=<span>1D700</span></span> + <span><math class="testfont"><mi>ζ</mi></math>=<span>1D701</span></span> + <span><math class="testfont"><mi>η</mi></math>=<span>1D702</span></span> + <span><math class="testfont"><mi>θ</mi></math>=<span>1D703</span></span> + <span><math class="testfont"><mi>ι</mi></math>=<span>1D704</span></span> + <span><math class="testfont"><mi>κ</mi></math>=<span>1D705</span></span><br/> + <span><math class="testfont"><mi>λ</mi></math>=<span>1D706</span></span> + <span><math class="testfont"><mi>μ</mi></math>=<span>1D707</span></span> + <span><math class="testfont"><mi>ν</mi></math>=<span>1D708</span></span> + <span><math class="testfont"><mi>ξ</mi></math>=<span>1D709</span></span> + <span><math class="testfont"><mi>ο</mi></math>=<span>1D70A</span></span> + <span><math class="testfont"><mi>π</mi></math>=<span>1D70B</span></span> + <span><math class="testfont"><mi>ρ</mi></math>=<span>1D70C</span></span> + <span><math class="testfont"><mi>ς</mi></math>=<span>1D70D</span></span> + <span><math class="testfont"><mi>σ</mi></math>=<span>1D70E</span></span> + <span><math class="testfont"><mi>τ</mi></math>=<span>1D70F</span></span><br/> + <span><math class="testfont"><mi>υ</mi></math>=<span>1D710</span></span> + <span><math class="testfont"><mi>φ</mi></math>=<span>1D711</span></span> + <span><math class="testfont"><mi>χ</mi></math>=<span>1D712</span></span> + <span><math class="testfont"><mi>ψ</mi></math>=<span>1D713</span></span> + <span><math class="testfont"><mi>ω</mi></math>=<span>1D714</span></span> + <span><math class="testfont"><mi>∂</mi></math>=<span>1D715</span></span> + <span><math class="testfont"><mi>ϵ</mi></math>=<span>1D716</span></span> + <span><math class="testfont"><mi>ϑ</mi></math>=<span>1D717</span></span> + <span><math class="testfont"><mi>ϰ</mi></math>=<span>1D718</span></span> + <span><math class="testfont"><mi>ϕ</mi></math>=<span>1D719</span></span><br/> + <span><math class="testfont"><mi>ϱ</mi></math>=<span>1D71A</span></span> + <span><math class="testfont"><mi>ϖ</mi></math>=<span>1D71B</span></span> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight-ref.html new file mode 100644 index 0000000000..c3e586f4dd --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight-ref.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>mathvariant attribute and font-style/font-weight (reference)</title> + <style> + .italic { font-style: italic; } + .bold { font-weight: bold; } + </style> + </head> + <body> + <p>This test passes if you see six lines of text (italic, italic, bold, bold, bold italic and bold italic) with the corresponding style applied:</p> + <p> + <math> + <mtext class="italic">italic</mtext> + </math> + </p> + <p> + <math> + <mtext class="italic">italic</mtext> + </math> + </p> + <p> + <math> + <mtext class="bold">bold</mtext> + </math> + </p> + <p> + <math> + <mtext class="bold">bold</mtext> + </math> + </p> + <p> + <math> + <mtext class="bold italic">bold italic</mtext> + </math> + </p> + <p> + <math> + <mtext class="bold italic">bold italic</mtext> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight.html b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight.html new file mode 100644 index 0000000000..793c687b09 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>mathvariant attribute and font-style/font-weight</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute"> + <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1788645"> + <link rel="match" href="mathvariant-font-style-font-weight-ref.html"/> + <meta name="assert" content="Verify that a mathvariant attribute does not cancel the effect of font-style/font-weight."> + <style> + .italic { font-style: italic; } + .bold { font-weight: bold; } + </style> + </head> + <body> + <p>This test passes if you see six lines of text (italic, italic, bold, bold, bold italic and bold italic) with the corresponding style applied:</p> + <p> + <math mathvariant="normal"> + <mtext class="italic">italic</mtext> + </math> + </p> + <p> + <math> + <mtext mathvariant="normal" class="italic">italic</mtext> + </math> + </p> + <p> + <math mathvariant="normal"> + <mtext class="bold">bold</mtext> + </math> + </p> + <p> + <math> + <mtext mathvariant="normal" class="bold">bold</mtext> + </math> + </p> + <p> + <math mathvariant="normal"> + <mtext class="bold italic">bold italic</mtext> + </math> + </p> + <p> + <math> + <mtext mathvariant="normal" class="bold italic">bold italic</mtext> + </math> + </p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight-ref.html new file mode 100644 index 0000000000..63e6e2ba9c --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight-ref.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>single-char mi and fontstyle/fontweight attributes (reference)</title> + <style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/mathvariant-italic.woff"); + } + .testfont { + font-family: TestFont; + font-size: 32px; + } + </style> + </head> + <body> + <p>Test passes if you see <span class="testfont">𝜕</span> rendered twice, without any bold or italic style applied:</p> + <p><math class="testfont"><mi mathvariant="normal">𝜕</mi></math></p> + <p><math class="testfont"><mi mathvariant="normal">𝜕</mi></math></p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight.html b/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight.html new file mode 100644 index 0000000000..b6dd05ea20 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>single-char mi and fontstyle/fontweight attributes</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute"> + <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1789081"> + <link rel="match" href="mi-fontstyle-fontweight-ref.html"/> + <meta name="assert" content="Verify that fontstyle/fontweight don't cancel the mathvariant transform on single-char mi elements."> + <style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/mathvariant-italic.woff"); + } + .testfont { + font-family: TestFont; + font-size: 32px; + } + </style> + </head> + <body> + <p>Test passes if you see <span class="testfont">𝜕</span> rendered twice, without any bold or italic style applied:</p> + <p><math class="testfont"><mi fontweight="bold">∂</mi></math></p> + <p><math class="testfont"><mi fontstyle="normal">∂</mi></math></p> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/multi-column-layout.html b/testing/web-platform/tests/mathml/relations/css-styling/multi-column-layout.html new file mode 100644 index 0000000000..88db5047e9 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/multi-column-layout.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML inside multi-column</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg"> +<meta name="assert" content="Verify that putting MathML inside a multi-column list shouldn't affect its layout."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("DOMContentLoaded", function() { + var epsilon = 1; + var mfrac = document.getElementById("mfrac"); + var num = mfrac.firstElementChild.getBoundingClientRect(); + var denom = mfrac.lastElementChild.getBoundingClientRect(); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(num.width, 30, epsilon, "numerator width"); + assert_approx_equals(num.height, 40, epsilon, "numerator height"); + assert_approx_equals(denom.width, 50, epsilon, "numerator width"); + assert_approx_equals(denom.height, 60, epsilon, "numerator height"); + }, "mspace layout in multicol"); + test(function() { + assert_true(MathMLFeatureDetection.has_mfrac()); + assert_greater_than_equal(denom.bottom - num.top, + (40 + 60), + "numerator is above the denominator"); + assert_approx_equals((num.left + num.right) / 2, + (denom.left + denom.right) / 2, + epsilon, "numerator and denominator are horizontally aligned"); + }, "mfrac layout in multicol"); + done(); + }); +</script> +</head> +<body> + <div id="log"></div> + <div style="column-width: 10em; list-style-type: decimal;"> + <ol> + <li>blah</li> + <li> + <math> + <mfrac id="mfrac"> + <mspace width="30px" height="40px" style="background: cyan"></mspace> + <mspace width="50px" height="60px" style="background: yellow"></mspace> + </mfrac> + </li> + <li>blah</li> + <li>blah</li> + <li>blah</li> + </ol> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/not-participating-to-parent-layout.html b/testing/web-platform/tests/mathml/relations/css-styling/not-participating-to-parent-layout.html new file mode 100644 index 0000000000..0952679c62 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/not-participating-to-parent-layout.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Elements not participating to the layout of their parent</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that display: none and out-of-flow positioned elements do not participate to layout of their parent."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag) || + FragmentHelper.isEmpty(tag)) + continue; + ["display: none", + "display: contents", + "position: absolute", + "position: fixed" + ].forEach(style => { + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ +<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\ +<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\ +</div>`); + var div = document.body.lastElementChild; + + var elementContainer = div.firstElementChild; + var elementContainerWidth = elementContainer.getBoundingClientRect().width; + var element = FragmentHelper.element(elementContainer); + if (style === "display: contents" && + !element.classList.contains("mathml-container")) { + // A "display: contents" MathML child is not participating to + // parent layout because its computed style is "display: none". + // If we cannot append a MathML child then skip that test. + return; + } + FragmentHelper.forceNonEmptyElement(element); + var allowInvalid = true; + var child = FragmentHelper.appendChild(element, allowInvalid); + child.setAttribute("style", style); + + var referenceContainer = div.lastElementChild; + var referenceContainerWidth = referenceContainer.getBoundingClientRect().width; + var reference = FragmentHelper.element(referenceContainer); + FragmentHelper.forceNonEmptyElement(reference); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + assert_approx_equals(elementContainerWidth, referenceContainerWidth, epsilon); + }, `${tag} preferred width calculation is not affected by children with "${style}" style`); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + compareLayout(element, reference, epsilon); + }, `${tag} layout is not affected by children with "${style}" style`); + + div.style = "display: none;"; // Hide the div after measurement. + }); + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001-ref.html new file mode 100644 index 0000000000..447c5b722a --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Absolutely positioned (reference)</title> +<body> + <p>Test passes if you see a green square and no red.</p> + <div style="position: absolute; left: 100px; top: 100px;"> + <math> + <mrow> + <mspace width="100px" height="300px" style="background: green"/> + <mspace width="100px" height="300px" style="background: green"/> + <mspace width="100px" height="300px" style="background: green"/> + </mrow> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001.html new file mode 100644 index 0000000000..9a7851ba23 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Absolutely positioned</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<link rel="match" href="absolutely-positioned-001-ref.html"/> +<meta name="assert" content="Verify visual rendering of absolutely positioned mtext elements."> +<body> + <p>Test passes if you see a green square and no red.</p> + <div style="position: absolute; left: 100px; top: 100px;"> + <math> + <mrow> + <mspace width="100px" height="300px" style="background: green"/> + <mspace width="100px" height="300px" style="background: red"/> + <mspace width="100px" height="300px" style="background: green"/> + <mtext style="position: absolute; left: 100px; top: 0px;"><span style="display: inline-block; width: 50px; height: 300px; background: green"></span></mtext> + <mtext style="position: absolute; left: 150px; top: 0px;"><span style="display: inline-block; width: 50px; height: 150px; background: green"></span></mtext> + <mtext style="position: absolute; left: 150px; top: 150px;"><span style="display: inline-block; width: 50px; height: 150px; background: green"></span></mtext> + </mrow> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/all-mathml-containers.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/all-mathml-containers.html new file mode 100644 index 0000000000..9069b92637 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/all-mathml-containers.html @@ -0,0 +1,103 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>absolutely positioned in all MathML elements</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that absolutely positioned node works in all MathML elements."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<style> + /* override display: none on children of maction/semantics */ + maction > *, semantics > * { + display: math; + } +</style> +<script> + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + ["absolute", "fixed"].forEach(positionValue => { + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag) || + FragmentHelper.isEmpty(tag)) + continue; + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ +<math>${MathMLFragments[tag]}</math>\ +</div>`); + let div = document.body.lastElementChild; + let element = FragmentHelper.element(div.firstElementChild); + FragmentHelper.forceNonEmptyElement(element); + if (element.classList.contains("mathml-container") || + element.classList.contains("foreign-container")) { + for (let i = 0; i < 5; i++) { + FragmentHelper.appendChild(element); + } + } + + let middleChild; + if (element.children.length >= 2) { + middleChild = FragmentHelper.appendChild(element, true /*allowInvalid*/); + middleChild.setAttribute("style", `position: ${positionValue}; left: 300px; top: 400px`); + let middlePosition = Math.floor(element.children.length/2); + element.insertBefore(middleChild, element.children[middlePosition]); + } + + let firstChild = FragmentHelper.appendChild(element, true /*allowInvalid*/); + firstChild.setAttribute("style", `position: ${positionValue}; left: 100px; top: 200px`); + element.insertBefore(firstChild, element.firstElementChild); + + let lastChild = FragmentHelper.appendChild(element, true /*allowInvalid*/); + lastChild.setAttribute("style", `position: ${positionValue}; left: 500px; top: 600px`); + + let referenceBox; + switch (positionValue) { + case "absolute": + // Use the absolutely positioned div ancestor. + referenceBox = div.getBoundingClientRect(); + break + case "fixed": + // Use the viewport. + referenceBox = {left: 0, top: 0}; + break; + default: + throw "reference box not defined"; + } + + let firstChildBox = firstChild.getBoundingClientRect(); + let lastChildBox = lastChild.getBoundingClientRect(); + let middleChildBox; + if (middleChild) { + middleChildBox = middleChild.getBoundingClientRect(); + } + + let epsilon = 1; + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + assert_approx_equals(firstChildBox.left - referenceBox.left, 100, epsilon); + assert_approx_equals(firstChildBox.top - referenceBox.top, 200, epsilon); + if (middleChildBox) { + assert_approx_equals(middleChildBox.left - referenceBox.left, 300, epsilon); + assert_approx_equals(middleChildBox.top - referenceBox.top, 400, epsilon); + } + assert_approx_equals(lastChildBox.left - referenceBox.left, 500, epsilon); + assert_approx_equals(lastChildBox.top - referenceBox.top, 600, epsilon); + }, `position: ${positionValue}; children in ${tag}`); + + div.style = "display: none;"; // Hide the div after measurement. + } + }); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001-ref.html new file mode 100644 index 0000000000..03b9f56698 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001-ref.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"/> +<title>Fixed positioned (reference)</title> +<style> + body { overflow: hidden; } +</style> +<body> + <div style="position: absolute; left: 100px; top: 200px; + height: 3000px; width: 3000px;"> + <math> + <mrow> + <mspace width="100px" height="300px" style="background: green"/> + <mspace width="100px" height="300px" style="background: green"/> + <mspace width="100px" height="300px" style="background: green"/> + </mrow> + </math> + <p>Test passes if you see a green square and no red.</p> + </div> + <script> + requestAnimationFrame(() => { + window.scrollTo(50, 100); + document.documentElement.classList.remove("reftest-wait"); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001.html new file mode 100644 index 0000000000..994174162c --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"/> +<title>Fixed positioned</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<link rel="match" href="fixed-positioned-001-ref.html"/> +<meta name="assert" content="Verify visual rendering of fixed positioned mtext elements."> +<style> + body { overflow: hidden; } +</style> +<body> + <div style="position: absolute; left: 100px; top: 200px; + height: 3000px; width: 3000px;"> + <math> + <mrow> + <mspace width="100px" height="300px" style="background: green"/> + <mspace width="100px" height="300px" style="background: red"/> + <mspace width="100px" height="300px" style="background: green"/> + <mtext style="position: fixed; left: 150px; top: 100px;"><span style="display: inline-block; width: 50px; height: 300px; background: green"></span></mtext> + <mtext style="position: fixed; left: 200px; top: 100px;"><span style="display: inline-block; width: 50px; height: 150px; background: green"></span></mtext> + <mtext style="position: fixed; left: 200px; top: 250px;"><span style="display: inline-block; width: 50px; height: 150px; background: green"></span></mtext> + </mrow> + </math> + <p>Test passes if you see a green square and no red.</p> + </div> + <script> + requestAnimationFrame(() => { + window.scrollTo(50, 100); + document.documentElement.classList.remove("reftest-wait"); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/overflow/computed-value-001.html b/testing/web-platform/tests/mathml/relations/css-styling/overflow/computed-value-001.html new file mode 100644 index 0000000000..0510f1da6d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/overflow/computed-value-001.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>overflow on MathML elements</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<meta name="assert" content="overflow can be overridden on MathML elements."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<style> + /* selector defined in mathml-fragments.js */ + .element { + overflow: scroll; + } +</style> +</head> +<body> + <div id="log"></div> + <div id="container"> + <math class="element"></math> + </div> + <script> + test(function () { + var container = document.getElementById("container"); + for (tag in MathMLFragments) { + // Skip mtable as browsers don't have interoperable behavior for + // display: table. + // See https://github.com/w3c/csswg-drafts/issues/8133 + if (tag == "mtable") + continue; + container.insertAdjacentHTML("beforeend", `<math>${MathMLFragments[tag]}</math>`); + } + let unknownElement = FragmentHelper.createElement("unknown"); + unknownElement.setAttribute("class", "element"); + container.appendChild(unknownElement); + Array.from(document.getElementsByClassName("element")).forEach(element => { + var tag = element.tagName; + var style = window.getComputedStyle(element); + assert_equals(style["overflow"], "scroll", `overflow on ${tag}`); + }, `overflow can be overridden on all MathML elements`); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-001.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-001.html new file mode 100644 index 0000000000..fd86388ccd --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-001.html @@ -0,0 +1,179 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>border</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that border is taken into account."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/box-comparison.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-border") + assert_approx_equals(s.left, 20, epsilon, "left border"); + assert_approx_equals(s.right, 30, epsilon, "right border"); + assert_approx_equals(s.top, 40, epsilon, "top border"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom border"); + var b = document.getElementById("mrow-border"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Border properties on mrow"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-border-rtl") + assert_approx_equals(s.left, 20, epsilon, "left border"); + assert_approx_equals(s.right, 30, epsilon, "right border"); + assert_approx_equals(s.top, 40, epsilon, "top border"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom border"); + var b = document.getElementById("mrow-border-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Border properties on mrow (rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-border-shorthand") + assert_approx_equals(s.left, 20, epsilon, "left border"); + assert_approx_equals(s.right, 20, epsilon, "right border"); + assert_approx_equals(s.top, 20, epsilon, "top border"); + assert_approx_equals(s.bottom, 20, epsilon, "bottom border"); + var b = document.getElementById("mrow-border-shorthand"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 20, epsilon, "element width"); + assert_approx_equals(b.height, 20 + 50 + 20, epsilon, "element height"); + }, "Border properties on mrow (shorthand)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-border-logical") + assert_approx_equals(s.left, 20, epsilon, "left border"); + assert_approx_equals(s.right, 30, epsilon, "right border"); + assert_approx_equals(s.top, 40, epsilon, "top border"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom border"); + var b = document.getElementById("mrow-border-logical"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Border properties on mrow (logical)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-border-logical-rtl") + assert_approx_equals(s.left, 30, epsilon, "left border"); + assert_approx_equals(s.right, 20, epsilon, "right border"); + assert_approx_equals(s.top, 40, epsilon, "top border"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom border"); + var b = document.getElementById("mrow-border-logical-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Border properties on mrow (logical, rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-border-logical-shorthand") + assert_approx_equals(s.left, 20, epsilon, "left border"); + assert_approx_equals(s.right, 20, epsilon, "right border"); + assert_approx_equals(s.top, 30, epsilon, "top border"); + assert_approx_equals(s.bottom, 30, epsilon, "bottom border"); + var b = document.getElementById("mrow-border-logical-shorthand"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 20, epsilon, "element width"); + assert_approx_equals(b.height, 30 + 50 + 30, epsilon, "element height"); + }, "Border properties on mrow (logical, shorthand)"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow> + <mrow id="mrow-border" + style="border-left: 20px solid transparent; + border-right: 30px solid transparent; + border-top: 40px solid transparent; + border-bottom: 50px solid transparent;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-border-rtl" + style="border-left: 20px solid transparent; + border-right: 30px solid transparent; + border-top: 40px solid transparent; + border-bottom: 50px solid transparent;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-border-shorthand" + style="border: 20px solid transparent;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-border-logical" + style="border-inline-start: 20px solid transparent; + border-inline-end: 30px solid transparent; + border-block-start: 40px solid transparent; + border-block-end: 50px solid transparent;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-border-logical-rtl" + style="border-inline-start: 20px solid transparent; + border-inline-end: 30px solid transparent; + border-block-start: 40px solid transparent; + border-block-end: 50px solid transparent;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-border-logical-shorthand" + style="border-inline: 20px solid transparent; + border-block: 30px solid transparent;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-002.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-002.html new file mode 100644 index 0000000000..bfb7f76adc --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-002.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>border</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that border is taken into account."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/mathml/support/box-comparison.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag)) + continue; + + var style = "border-left: 30px solid; border-right: 40px solid; border-top: 50px solid; border-bottom: 60px solid;"; + + if (FragmentHelper.isEmpty(tag)) { + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSizeWithAndWithoutStyle(tag, style); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "left/right border"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "top/bottom border"); + assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width"); + }, `Border properties on ${tag}`); + continue; + } + + var default_border = tag === "merror" ? 1 : 0; + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSpaceWithAndWithoutStyle(tag, style); + assert_approx_equals(s.left_delta + default_border, 30, epsilon, "left border"); + assert_approx_equals(s.right_delta + default_border, 40, epsilon, "right border"); + assert_approx_equals(s.top_delta + default_border, 50, epsilon, "top border"); + assert_approx_equals(s.bottom_delta + default_border, 60, epsilon, "bottom border"); + assert_approx_equals(s.element_width_delta + 2 * default_border, 30 + 40, epsilon, "element width"); + assert_approx_equals(s.element_height_delta + 2 * default_border, 50 + 60, epsilon, "element height"); + assert_approx_equals(s.preferred_width_delta + 2 * default_border, 30 + 40, epsilon, "element preferred width"); + }, `Border properties on ${tag}`); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSpaceWithAndWithoutStyle(tag, style, null, "rtl"); + assert_approx_equals(s.left_delta + default_border, 30, epsilon, "left border"); + assert_approx_equals(s.right_delta + default_border, 40, epsilon, "right border"); + assert_approx_equals(s.top_delta + default_border, 50, epsilon, "top border"); + assert_approx_equals(s.bottom_delta + default_border, 60, epsilon, "bottom border"); + assert_approx_equals(s.element_width_delta + 2 * default_border, 30 + 40, epsilon, "element width"); + assert_approx_equals(s.element_height_delta + 2 * default_border, 50 + 60, epsilon, "element height"); + assert_approx_equals(s.preferred_width_delta + 2 * default_border, 30 + 40, epsilon, "element preferred width"); + }, `Border properties on ${tag} (rtl)`); + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-001.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-001.html new file mode 100644 index 0000000000..eabb6f46c7 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-001.html @@ -0,0 +1,179 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>margin</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that margin is taken into account."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/box-comparison.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-margin") + assert_approx_equals(s.left, 20, epsilon, "left margin"); + assert_approx_equals(s.right, 30, epsilon, "right margin"); + assert_approx_equals(s.top, 40, epsilon, "top margin"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom margin"); + var b = document.getElementById("mrow-margin"). + getBoundingClientRect(); + assert_approx_equals(b.width, 50, epsilon, "element width"); + assert_approx_equals(b.height, 50, epsilon, "element height"); + }, "Margin properties on mrow"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-margin-rtl") + assert_approx_equals(s.left, 20, epsilon, "left margin"); + assert_approx_equals(s.right, 30, epsilon, "right margin"); + assert_approx_equals(s.top, 40, epsilon, "top margin"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom margin"); + var b = document.getElementById("mrow-margin-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 50, epsilon, "element width"); + assert_approx_equals(b.height, 50, epsilon, "element height"); + }, "Margin properties on mrow (rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-margin-shorthand") + assert_approx_equals(s.left, 20, epsilon, "left margin"); + assert_approx_equals(s.right, 20, epsilon, "right margin"); + assert_approx_equals(s.top, 20, epsilon, "top margin"); + assert_approx_equals(s.bottom, 20, epsilon, "bottom margin"); + var b = document.getElementById("mrow-margin-shorthand"). + getBoundingClientRect(); + assert_approx_equals(b.width, 50, epsilon, "element width"); + assert_approx_equals(b.height, 50, epsilon, "element height"); + }, "Margin properties on mrow (shorthand)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-margin-logical") + assert_approx_equals(s.left, 20, epsilon, "left margin"); + assert_approx_equals(s.right, 30, epsilon, "right margin"); + assert_approx_equals(s.top, 40, epsilon, "top margin"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom margin"); + var b = document.getElementById("mrow-margin-logical"). + getBoundingClientRect(); + assert_approx_equals(b.width, 50, epsilon, "element width"); + assert_approx_equals(b.height, 50, epsilon, "element height"); + }, "Margin properties on mrow (logical)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-margin-logical-rtl") + assert_approx_equals(s.left, 30, epsilon, "left margin"); + assert_approx_equals(s.right, 20, epsilon, "right margin"); + assert_approx_equals(s.top, 40, epsilon, "top margin"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom margin"); + var b = document.getElementById("mrow-margin-logical-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 50, epsilon, "element width"); + assert_approx_equals(b.height, 50, epsilon, "element height"); + }, "Margin properties on mrow (logical, rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-margin-logical-shorthand") + assert_approx_equals(s.left, 20, epsilon, "left margin"); + assert_approx_equals(s.right, 20, epsilon, "right margin"); + assert_approx_equals(s.top, 30, epsilon, "top margin"); + assert_approx_equals(s.bottom, 30, epsilon, "bottom margin"); + var b = document.getElementById("mrow-margin-logical-shorthand"). + getBoundingClientRect(); + assert_approx_equals(b.width, 50, epsilon, "element width"); + assert_approx_equals(b.height, 50, epsilon, "element height"); + }, "Margin properties on mrow (logical, shorthand)"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow> + <mrow id="mrow-margin" + style="margin-left: 20px; + margin-right: 30px; + margin-top: 40px; + margin-bottom: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-margin-rtl" + style="margin-left: 20px; + margin-right: 30px; + margin-top: 40px; + margin-bottom: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-margin-shorthand" + style="margin: 20px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-margin-logical" + style="margin-inline-start: 20px; + margin-inline-end: 30px; + margin-block-start: 40px; + margin-block-end: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-margin-logical-rtl" + style="margin-inline-start: 20px; + margin-inline-end: 30px; + margin-block-start: 40px; + margin-block-end: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-margin-logical-shorthand" + style="margin-inline: 20px; + margin-block: 30px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-002.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-002.html new file mode 100644 index 0000000000..b560ed125c --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-002.html @@ -0,0 +1,86 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>margin</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that margin is taken into account."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/mathml/support/box-comparison.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag)) + continue; + + var style = "margin-left: 30px; margin-right: 40px; margin-top: 50px; margin-bottom: 60px;"; + + if (FragmentHelper.isEmpty(tag)) { + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSizeWithAndWithoutStyle(tag, style); + assert_approx_equals(s.width_delta, 30 + 40, epsilon, "left/right margin"); + assert_approx_equals(s.height_delta, 50 + 60, epsilon, "top/bottom margin"); + assert_approx_equals(s.element_width_delta, 0, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 0, epsilon, "element height"); + assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width"); + }, `Margin properties on ${tag}`); + continue; + } + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSpaceWithAndWithoutStyle(tag, style); + assert_approx_equals(s.left_delta, 30, epsilon, "left margin"); + assert_approx_equals(s.right_delta, 40, epsilon, "right margin"); + assert_approx_equals(s.top_delta, 50, epsilon, "top margin"); + assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom margin"); + assert_approx_equals(s.element_width_delta, 0, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 0, epsilon, "element height"); + assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width"); + }, `Margin properties on ${tag}`); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSpaceWithAndWithoutStyle(tag, style, null, "rtl"); + assert_approx_equals(s.left_delta, 30, epsilon, "left margin"); + assert_approx_equals(s.right_delta, 40, epsilon, "right margin"); + assert_approx_equals(s.top_delta, 50, epsilon, "top margin"); + assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom margin"); + assert_approx_equals(s.element_width_delta, 0, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 0, epsilon, "element height"); + assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width"); + }, `Margin properties on ${tag} (rtl)`); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + // Apply the same margin style on the parent mrow. + // The margins are not collapsed so they should be added twice. + var s = compareSpaceWithAndWithoutStyle(tag, style, style); + assert_approx_equals(s.left_delta, 30 * 2, epsilon, "left margin"); + assert_approx_equals(s.right_delta, 40 * 2, epsilon, "right margin"); + assert_approx_equals(s.top_delta, 50 * 2, epsilon, "top margin"); + assert_approx_equals(s.bottom_delta, 60 * 2, epsilon, "bottom margin"); + assert_approx_equals(s.element_width_delta, 0, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 0, epsilon, "element height"); + assert_approx_equals(s.preferred_width_delta, (30 + 40) * 2, epsilon, "preferred width"); + }, `Margin properties on ${tag} (no margin-collapsing)`); + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-003.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-003.html new file mode 100644 index 0000000000..3b6b2a38db --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-003.html @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>margin</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that margin is taken into account on children."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag) || + FragmentHelper.isEmpty(tag) || + FragmentHelper.isTokenElement(tag) || + tag == "semantics" || + tag == "maction" || + tag == "mtable") + continue; + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + + document.body.insertAdjacentHTML("beforeend", `<hr/><div>\ +<div style="display: inline-block; border: 1px dashed blue;"><math>${MathMLFragments[tag]}</math></div><br/>\ +<div style="display: inline-block; border: 1px dashed green;"><math>${MathMLFragments[tag]}</math></div>\ +</div>`); + + var div = document.body.lastElementChild; + var elementShrinkWrapContainer = div.firstElementChild; + var element = elementShrinkWrapContainer.firstElementChild.firstElementChild; + var elementContainer = div.firstElementChild; + var referenceShrinkWrapContainer = div.lastElementChild; + var reference = referenceShrinkWrapContainer.firstElementChild.firstElementChild; + + FragmentHelper.forceNonEmptyElement(element); + FragmentHelper.forceNonEmptyElement(reference); + + var mspaceWidth = 20, mspaceHeight = 40, mspaceDepth = 30; + var marginLeft = 10, marginRight = 15, marginTop = 20, marginBottom = 25; + Array.from(element.children).forEach(mrow => { + mrow.outerHTML = `<mspace width="${mspaceWidth}px" height="${mspaceHeight}px" depth='${mspaceDepth}px' style='background: blue; margin-left: ${marginLeft}px; margin-right: ${marginRight}px; margin-top: ${marginTop}px; margin-bottom: ${marginBottom}px;'></mspace>`; + }); + + Array.from(reference.children).forEach(mrow => { + mrow.outerHTML = `<mspace width="${marginLeft+mspaceWidth+marginRight}px" height="${mspaceHeight+marginTop}px" depth='${mspaceDepth+marginBottom}px' style='background: green;'></mspace>`; + }); + + // Compare sizes. + compareSize(element, reference, epsilon); + + // Compare children positions. + var elementBox = element.getBoundingClientRect(); + var referenceBox = reference.getBoundingClientRect(); + for (var i = 0; i < element.children.length; i++) { + var childBox = element.children[i].getBoundingClientRect(); + var referenceChildBox = reference.children[i].getBoundingClientRect(); + assert_approx_equals(childBox.width + marginLeft + marginRight, referenceChildBox.width, epsilon, "inline size (child ${i})"); + assert_approx_equals(childBox.height + marginTop + marginBottom, referenceChildBox.height, epsilon, "block size (child ${i})"); + + assert_approx_equals(childBox.left - marginLeft - elementBox.left, + referenceChildBox.left - referenceBox.left, + epsilon, + `inline position (child ${i})`); + assert_approx_equals(childBox.top - marginTop - elementBox.top, + referenceChildBox.top - referenceBox.top, + epsilon, + `block position (child ${i})`); + } + + // Compare preferred widths. + assert_approx_equals(elementShrinkWrapContainer.offsetWidth, referenceShrinkWrapContainer.offsetWidth, epsilon, "preferred width"); + + }, `Margin properties on the children of ${tag}`); + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-001.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-001.html new file mode 100644 index 0000000000..b6d4901f36 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-001.html @@ -0,0 +1,179 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>padding</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that padding is taken into account."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/box-comparison.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-padding") + assert_approx_equals(s.left, 20, epsilon, "left padding"); + assert_approx_equals(s.right, 30, epsilon, "right padding"); + assert_approx_equals(s.top, 40, epsilon, "top padding"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom padding"); + var b = document.getElementById("mrow-padding"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Padding properties on mrow"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-padding-rtl") + assert_approx_equals(s.left, 20, epsilon, "left padding"); + assert_approx_equals(s.right, 30, epsilon, "right padding"); + assert_approx_equals(s.top, 40, epsilon, "top padding"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom padding"); + var b = document.getElementById("mrow-padding-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Padding properties on mrow (rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-padding-shorthand") + assert_approx_equals(s.left, 20, epsilon, "left padding"); + assert_approx_equals(s.right, 20, epsilon, "right padding"); + assert_approx_equals(s.top, 20, epsilon, "top padding"); + assert_approx_equals(s.bottom, 20, epsilon, "bottom padding"); + var b = document.getElementById("mrow-padding-shorthand"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 20, epsilon, "element width"); + assert_approx_equals(b.height, 20 + 50 + 20, epsilon, "element height"); + }, "Padding properties on mrow (shorthand)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-padding-logical") + assert_approx_equals(s.left, 20, epsilon, "left padding"); + assert_approx_equals(s.right, 30, epsilon, "right padding"); + assert_approx_equals(s.top, 40, epsilon, "top padding"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom padding"); + var b = document.getElementById("mrow-padding-logical"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Padding properties on mrow (logical)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection.has_dir()); + var s = measureSpaceAround("mrow-padding-logical-rtl") + assert_approx_equals(s.left, 30, epsilon, "left padding"); + assert_approx_equals(s.right, 20, epsilon, "right padding"); + assert_approx_equals(s.top, 40, epsilon, "top padding"); + assert_approx_equals(s.bottom, 50, epsilon, "bottom padding"); + var b = document.getElementById("mrow-padding-logical-rtl"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width"); + assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height"); + }, "Padding properties on mrow (logical, rtl)"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var s = measureSpaceAround("mrow-padding-logical-shorthand") + assert_approx_equals(s.left, 20, epsilon, "left padding"); + assert_approx_equals(s.right, 20, epsilon, "right padding"); + assert_approx_equals(s.top, 30, epsilon, "top padding"); + assert_approx_equals(s.bottom, 30, epsilon, "bottom padding"); + var b = document.getElementById("mrow-padding-logical-shorthand"). + getBoundingClientRect(); + assert_approx_equals(b.width, 20 + 50 + 20, epsilon, "element width"); + assert_approx_equals(b.height, 30 + 50 + 30, epsilon, "element height"); + }, "Padding properties on mrow (logical, shorthand)"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow> + <mrow id="mrow-padding" + style="padding-left: 20px; + padding-right: 30px; + padding-top: 40px; + padding-bottom: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-padding-rtl" + style="padding-left: 20px; + padding-right: 30px; + padding-top: 40px; + padding-bottom: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-padding-shorthand" + style="padding: 20px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-padding-logical" + style="padding-inline-start: 20px; + padding-inline-end: 30px; + padding-block-start: 40px; + padding-block-end: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math dir="rtl"> + <mrow> + <mrow id="mrow-padding-logical-rtl" + style="padding-inline-start: 20px; + padding-inline-end: 30px; + padding-block-start: 40px; + padding-block-end: 50px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> + <p> + <math> + <mrow> + <mrow id="mrow-padding-logical-shorthand" + style="padding-inline: 20px; + padding-block: 30px;"> + <mspace width="50px" height="50px"></mspace> + </mrow> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-002.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-002.html new file mode 100644 index 0000000000..89d3bdc7ef --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-002.html @@ -0,0 +1,71 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>padding</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that padding is taken into account."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/mathml/support/box-comparison.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag)) + continue; + + var defaultInlinePadding = (tag === "mfrac" ? 1 : 0); + var style = `padding-left: ${defaultInlinePadding + 30}px; padding-right: ${defaultInlinePadding + 40}px; padding-top: 50px; padding-bottom: 60px;`; + + if (FragmentHelper.isEmpty(tag)) { + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSizeWithAndWithoutStyle(tag, style); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "left/right padding"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "top/bottom padding"); + assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width"); + }, `Padding properties on ${tag}`); + continue; + } + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSpaceWithAndWithoutStyle(tag, style); + assert_approx_equals(s.left_delta, 30, epsilon, "left padding"); + assert_approx_equals(s.right_delta, 40, epsilon, "right padding"); + assert_approx_equals(s.top_delta, 50, epsilon, "top padding"); + assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom padding"); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "element height"); + assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width"); + }, `Padding properties on ${tag}`); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var s = compareSpaceWithAndWithoutStyle(tag, style, "rtl"); + assert_approx_equals(s.left_delta, 30, epsilon, "left padding"); + assert_approx_equals(s.right_delta, 40, epsilon, "right padding"); + assert_approx_equals(s.top_delta, 50, epsilon, "top padding"); + assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom padding"); + assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "element width"); + assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "element height"); + assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width"); + }, `Padding properties on ${tag} (rtl)`); + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001-ref.html new file mode 100644 index 0000000000..150a650bc2 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Padding/border/margin</title> +<body> + <p>This test passes if you see a purple square of side 100px, surrounded by a + 10px blue padding, surrounded by a 10px blue/yellow dashed border, itself + surrounded by a 10px pink margin.</p> + </div> + <div style="background: pink; position: absolute; left: 10px; top: 3em;"> + <div style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;"> + <div style="width: 100px; height: 100px; background: purple;"></div> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html new file mode 100644 index 0000000000..b0fb17c7d2 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Padding/border/margin</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow"> +<link rel="match" href="padding-border-margin-001-ref.html"/> +<meta name="assert" content="Verify visual rendering of padding/border/margin on the mrow element."> +<body> + <p>This test passes if you see a purple square of side 100px, surrounded by a + 10px blue padding, surrounded by a 10px blue/yellow dashed border, itself + surrounded by a 10px pink margin.</p> + <div style="background: pink; position: absolute; left: 10px; top: 3em;"> + <math> + <mrow style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;"> + <mspace width="100px" height="100px" style="background: purple;"></mspace> + </mrow> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002-ref.html new file mode 100644 index 0000000000..e13a9f47ff --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Padding/border/margin on largeop (reference)</title> +<body> + <p>This test passes if you see a cyan rectangle of width 300px and + height 1500px, surrounded by a 10px blue padding, surrounded by a 10px + blue/yellow dashed border, itself + surrounded by a 10px pink margin.</p> + </div> + <div style="background: pink; position: absolute; left: 10px; top: 4em;"> + <div style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;"> + <div style="width: 300px; height: 1500px; background: cyan;"></div> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002.html new file mode 100644 index 0000000000..4559fc49ce --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Padding/border/margin on largeop</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-math-style-property"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-operators"> +<link rel="match" href="padding-border-margin-002-ref.html"/> +<meta name="assert" content="Verify visual rendering of padding/border/margin on a displaystyle mo element with the largeop property."> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/largeop-displayoperatorminheight5000.woff"); + } + math { + /* Largeop variant for U+2AFF has width 100px + and height 300 * 5000 / 1000 = 1500px */ + font-family: TestFont; + font-size: 300px; + } +</style> +<body> + <p>This test passes if you see a cyan rectangle of width 300px and + height 1500px, surrounded by a 10px blue padding, surrounded by a 10px + blue/yellow dashed border, itself + surrounded by a 10px pink margin.</p> + <div style="background: pink; position: absolute; left: 10px; top: 4em;"> + <math displaystyle="true"> + <mo largeop="true" lspace="0" rspace="0" style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px; color: cyan;">⫿</mo> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003-ref.html new file mode 100644 index 0000000000..275494ddd8 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Padding/border/margin on an operator, stretchy along the block axis (reference)</title> +<body> + <p>This test passes if you see a cyan rectangle of width 300px and + height 1500px, surrounded by a 10px blue padding, surrounded by a 10px + blue/yellow dashed border, itself + surrounded by a 10px pink margin.</p> + </div> + <div style="background: pink; position: absolute; left: 10px; top: 4em;"> + <div style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;"> + <div style="width: 300px; height: 1500px; background: cyan;"></div> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003.html new file mode 100644 index 0000000000..c54682f309 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Padding/border/margin on an operator, stretchy along the block axis</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dfn-algorithm-for-stretching-operators-along-the-block-axis"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-operators"> +<link rel="match" href="padding-border-margin-003-ref.html"/> +<meta name="assert" content="Verify visual rendering of padding/border/margin on an operator, stretchy along the block axis."> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/stretchy.woff"); + } + math { + font-family: TestFont; + font-size: 300px; + } +</style> +<body> + <p>This test passes if you see a cyan rectangle of width 300px and + height 1500px, surrounded by a 10px blue padding, surrounded by a 10px + blue/yellow dashed border, itself + surrounded by a 10px pink margin.</p> + <div style="background: pink; position: absolute; left: 10px; top: 4em;"> + <math> + <mspace height="750px" depth="750px"/> + <mo lspace="0" rspace="0" style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px; color: cyan;">⥜</mo> + </math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001-ref.html new file mode 100644 index 0000000000..ca539440f8 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001-ref.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>presentational hints</title> +<link rel="stylesheet" href="/fonts/ahem.css"> +<style> + @font-face { + font-family: DoubleStruck; + src: url("/fonts/math/mathvariant-double-struck.woff"); + } + @font-face { + font-family: Italic; + src: url("/fonts/math/mathvariant-italic.woff"); + } + math { + font: 25px/1 Ahem; + } +</style> +<body> + <p>dir: + <math style="direction: ltr;"> + <mtext>X</mtext> + <mtext>p</mtext> + </math> + </p> + <p>mathcolor: + <math style="color: green;"> + <mtext>X</mtext> + <mtext>p</mtext> + </math> + </p> + <p>mathbackground: + <math style="background: green;"> + <mtext>X</mtext> + <mtext>p</mtext> + </p> + <p>mathsize: + <math> + <mtext style="font-size: 100%">X</mtext> + </math> + </p> + <p>mathvariant: + <math> + <mi style="text-transform: uppercase">sin</mi> + </math> + </p> + <p>displaystyle: + <math style="math-style: compact"> + <munder> + <mo movablelimits="true">X</mo> + <mo>X</mo> + </munder> + </math> + </p> + <p>scriptlevel: + <math> + <mtext style="math-depth: 0;">X</mtext> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001.html b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001.html new file mode 100644 index 0000000000..96ee69541b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>presentational hints</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#double-struck-mappings"> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#new-text-transform-values"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="match" href="presentational-hints-001-ref.html"/> +<link rel="stylesheet" href="/fonts/ahem.css"> +<meta name="assert" content="Verify that local author style wins over presentation hints attributes"> +<style> + math { + font: 25px/1 Ahem; + } +</style> +<body> + <p>dir: + <math dir="rtl" style="direction: ltr;"> + <mtext>X</mtext> + <mtext>p</mtext> + </math> + </p> + <p>mathcolor: + <math mathcolor="red" style="color: green;"> + <mtext>X</mtext> + <mtext>p</mtext> + </math> + </p> + <p>mathbackground: + <math mathbackground="red" style="background: green;"> + <mtext>X</mtext> + <mtext>p</mtext> + </p> + <p>mathsize: + <math> + <mtext mathsize="300%" style="font-size: 100%">X</mtext> + </math> + </p> + <p>mathvariant: + <math> + <mi mathvariant="normal" style="text-transform: uppercase">sin</mi> + </math> + </p> + <p>displaystyle: + <math displaystyle="true" style="math-style: compact"> + <munder> + <mo movablelimits="true">X</mo> + <mo>X</mo> + </munder> + </math> + </p> + <p>scriptlevel: + <math> + <mtext scriptlevel="1" style="math-depth: 0;">X</mtext> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002-ref.html new file mode 100644 index 0000000000..fa22741efe --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002-ref.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>presentational hints (dynamic)</title> +<link rel="stylesheet" href="/fonts/ahem.css"> +<style> + math { + font: 25px/1 Ahem; + } + @font-face { + font-family: Italic; + src: url("/fonts/math/mathvariant-italic.woff"); + } +</style> +</head> +<body> + <p>dir: + <math dir="rtl"> + <mtext>X</mtext> + <mtext>p</mtext> + </math> + </p> + <p>mathcolor: + <math mathcolor="green"> + <mtext>X</mtext> + <mtext>p</mtext> + </math> + </p> + <p>mathbackground: + <math mathbackground="green"> + <mtext>X</mtext> + <mtext>p</mtext> + </p> + <p>mathsize: + <math> + <mtext mathsize="300%">X</mtext> + </math> + </p> + <p>mathvariant: + <math style="font-family: Italic"> + <mi mathvariant="normal">X</mi> + </math> + </p> + <p>displaystyle: + <math displaystyle="true"> + <munder> + <mo movablelimits="true">X</mo> + <mo>X</mo> + </munder> + </math> + </p> + <p>scriptlevel: + <math> + <mtext scriptlevel="-1">X</mtext> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002.html b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002.html new file mode 100644 index 0000000000..8bb9153b86 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"/> +<title>presentational hints (dynamic)</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#double-struck-mappings"> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#new-text-transform-values"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="match" href="presentational-hints-002-ref.html"/> +<link rel="stylesheet" href="/fonts/ahem.css"> +<meta name="assert" content="Verify dynamically setting attributes mapped to style."> +<style> + math { + font: 25px/1 Ahem; + } + @font-face { + font-family: Italic; + src: url("/fonts/math/mathvariant-italic.woff"); + } +</style> +<script> + window.addEventListener("load", function() { + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + document.getElementById("dir").setAttribute("dir", "rtl"); + document.getElementById("mathcolor").setAttribute("mathcolor", "green"); + document.getElementById("mathbackground").setAttribute("mathbackground", "green"); + document.getElementById("mathsize").setAttribute("mathsize", "300%"); + document.getElementById("mathvariant").setAttribute("mathvariant", "normal"); + document.getElementById("displaystyle").setAttribute("displaystyle", "true"); + document.getElementById("scriptlevel").setAttribute("scriptlevel", "-1"); + + document.documentElement.classList.remove('reftest-wait'); + }); +</script> +</head> +<body> + <p>dir: + <math id="dir"> + <mtext>X</mtext> + <mtext>p</mtext> + </math> + </p> + <p>mathcolor: + <math id="mathcolor"> + <mtext>X</mtext> + <mtext>p</mtext> + </math> + </p> + <p>mathbackground: + <math id="mathbackground"> + <mtext>X</mtext> + <mtext>p</mtext> + </p> + <p>mathsize: + <math> + <mtext id="mathsize">X</mtext> + </math> + </p> + <p>mathvariant: + <math style="font-family: Italic"> + <mi id="mathvariant">X</mi> + </math> + </p> + <p>displaystyle: + <math id="displaystyle"> + <munder> + <mo movablelimits="true">X</mo> + <mo>X</mo> + </munder> + </math> + </p> + <p>scriptlevel: + <math> + <mtext id="scriptlevel">X</mtext> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/scriptlevel-001.html b/testing/web-platform/tests/mathml/relations/css-styling/scriptlevel-001.html new file mode 100644 index 0000000000..e9be1f2965 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/scriptlevel-001.html @@ -0,0 +1,219 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Automatic scriptlevel</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes"> +<link rel="stylesheet" href="/fonts/ahem.css"> +<meta name="assert" content="Verify automatic scriptlevel changes"> +<style> + #container, math { + /* Ahem font does not have a MATH table so the font-size scale factor + is always 0.71^{computed - inherited math script level} */ + font: 100px/1 Ahem; + } +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + function fontSize(element) { + return parseFloat((/(.+)px/).exec(window.getComputedStyle(element).getPropertyValue("font-size"))[1]); + } + function runTests() { + var container = document.getElementById("container"); + var epsilon = .1 + var fontSizeAtScriptLevelZero = fontSize(container); + + test(function() { + var element = document.getElementById("mfrac_displaystyle"); + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "numerator"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "denominator"); + }, "automatic scriptlevel on mfrac (displaystyle=true)"); + + test(function() { + var element = document.getElementById("mfrac_notdisplaystyle"); + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero * .71, epsilon, "numerator"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71, epsilon, "denominator"); + }, "automatic scriptlevel on mfrac (displaystyle=false)"); + + test(function() { + var element = document.getElementsByTagName("mroot")[0]; + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71 * .71, epsilon, "index"); + }, "automatic scriptlevel on mroot"); + + ["msub", "msup", "msubsup", "munder", "mover", "munderover", "mmultiscripts"].forEach(tag => { + test(function() { + var element = document.getElementsByTagName(tag)[0]; + for (var i = 0; i < element.children.length; i++) + assert_approx_equals(fontSize(element.children[i]), i > 0 ? fontSizeAtScriptLevelZero * .71 : fontSizeAtScriptLevelZero, epsilon, `child ${i}`); + }, `automatic scriptlevel on ${tag}`); + }); + + test(function() { + var element = document.querySelector("munder[accentunder='true']"); + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under"); + }, `automatic scriptlevel on munder (accentunder=true)`); + + test(function() { + var element = document.querySelector("mover[accent='true']"); + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "over"); + }, `automatic scriptlevel on mover (accent=true)`); + + test(function() { + var element = document.querySelector("munderover[accentunder='true']"); + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under"); + assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero * .71, epsilon, "over"); + }, `automatic scriptlevel on munderover (accentunder=true)`); + + test(function() { + var element = document.querySelector("munderover[accent='true']"); + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71, epsilon, "under"); + assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero, epsilon, "over"); + }, `automatic scriptlevel on munderover (accent=true)`); + + test(function() { + var element = document.getElementById("munderover-dynamic-case-insensitive") + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71, epsilon, "under"); + assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero, epsilon, "over"); + + element.removeAttribute("accent"); + element.setAttribute("accentunder", "TrUe"); + assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base"); + assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under"); + assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero * .71, epsilon, "over"); + }, "checking dynamic/case-insensitive accent/accentunder"); + + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <div id="container"> + <p> + <math displaystyle="true"> + <mfrac id="mfrac_displaystyle"> + <mn>0</mn> + <mn>1</mn> + </mfrac> + </math> + + <math displaystyle="false"> + <mfrac id="mfrac_notdisplaystyle"> + <mn>0</mn> + <mn>1</mn> + </mfrac> + </math> + </p> + <p> + <math> + <mroot> + <mn>0</mn> + <mn>1</mn> + </mroot> + </math> + </p> + <p> + <math> + <msub> + <mn>0</mn> + <mn>1</mn> + </msub> + </math> + <math> + <msup> + <mn>0</mn> + <mn>1</mn> + </msup> + </math> + <math> + <msubsup> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + </msubsup> + </math> + <math> + <munder> + <mn>0</mn> + <mn>1</mn> + </munder> + </math> + <math> + <mover> + <mn>0</mn> + <mn>1</mn> + </mover> + </math> + <math> + <munderover> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + </munderover> + </math> + <math> + <mmultiscripts> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + <mn>3</mn> + <mn>4</mn> + <mprescripts/> + <mn>6</mn> + <mn>7</mn> + <mn>8</mn> + <mn>9</mn> + </mmultiscripts> + </math> + </p> + <p> + <math> + <munder accentunder="true"> + <mn>0</mn> + <mn>1</mn> + </munder> + </math> + <math> + <mover accent="true"> + <mn>0</mn> + <mn>1</mn> + </mover> + </math> + <math> + <munderover accent="true"> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + </munderover> + </math> + <math> + <munderover accentunder="true"> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + </munderover> + </math> + </p> + <p> + <math> + <munderover id="munderover-dynamic-case-insensitive" accent="TrUe"> + <mn>0</mn> + <mn>1</mn> + <mn>2</mn> + </munderover> + </math> + </p> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/transform-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/transform-ref.html new file mode 100644 index 0000000000..005e8a7882 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/transform-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Transform property (reference)</title> +</head> +<body> + <p>Rectangles should be rotated.</p> + <div style="background: green; width: 200px; height: 200px; position: absolute; top: 100px; transform: rotate(90deg)"></div> + <div style="background: green; width: 200px; height: 200px; position: absolute; top: 300px; transform: rotate(90deg)"></div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/transform.html b/testing/web-platform/tests/mathml/relations/css-styling/transform.html new file mode 100644 index 0000000000..c45fda3469 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/transform.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Transform property</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="transform-ref.html"/> +<meta name="assert" content="Verify that the transform property works on MathML elements."> +</head> +<body> + <p>Rectangles should be rotated.</p> + <div> + <math><mspace width="200px" height="200px" style="position:absolute; top:100px; background: green; transform: rotate(90deg)"/></math> + </div> + <div style="position: absolute; top: 300px; width: 200px; height: 200px"> + <math style="position: absolute; transform: rotate(90deg)"><mspace width="200px" height="200px" style="background: green"/></math> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-001-ref.html new file mode 100644 index 0000000000..fcaf5fe85b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-001-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>visibility (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-001.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-001.html new file mode 100644 index 0000000000..56bf7b7da2 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-001.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>visibility</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="match" href="visibility-001-ref.html"/> +<meta name="assert" content="Verify that visibility=hidden is used for the text of token elements."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px;"> + <math><mi style="visibility: hidden">1</mi></math> + <math><mn style="visibility: hidden">2</mn></math> + <math><mo style="visibility: hidden">3</mo></math> + <math><mtext style="visibility: hidden">4</mtext></math> + <math><ms style="visibility: hidden">5</ms></math> + <div id="dynamic"> + <math><mi>1</mi></math> + <math><mn>2</mn></math> + <math><mo>3</mo></math> + <math><mtext>4</mtext></math> + <math><ms>5</ms></math> + </div> + </div> + <script> + window.addEventListener("load", () => { + document.getElementById("dynamic").style.visibility = "hidden"; + document.documentElement.classList.remove("reftest-wait"); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-002-ref.html new file mode 100644 index 0000000000..fcaf5fe85b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-002-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>visibility (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-002.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-002.html new file mode 100644 index 0000000000..f92d0faf6d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-002.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>visibility</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fraction-with-nonzero-line-thickness"> +<link rel="match" href="visibility-002-ref.html"/> +<meta name="assert" content="Verify that visibility=hidden is used for the text and fraction bar of the mfrac element."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px;"> + <math><mfrac style="visibility: hidden"><mn>1</mn><mn>2</mn></mfrac></math> + <div id="dynamic"> + <math><mfrac><mn>1</mn><mn>2</mn></mfrac></math> + </div> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script> + window.addEventListener("load", () => { + document.getElementById("dynamic").style.visibility = "hidden"; + document.documentElement.classList.remove("reftest-wait"); + }); + </script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-003-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-003-ref.html new file mode 100644 index 0000000000..fcaf5fe85b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-003-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>visibility (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-003.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-003.html new file mode 100644 index 0000000000..4bf4d45c81 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-003.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>visibility</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://w3c.github.io/mathml-core/#radical-symbol"> +<link rel="match" href="visibility-003-ref.html"/> +<meta name="assert" content="Verify that visibility=hidden is used for the text and radical symbol of the msqrt and mroot elements."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px;"> + <math><msqrt style="visibility: hidden"><mn>1</mn></msqrt></math> + <math><mroot style="visibility: hidden"><mn>2</mn><mn>3</mn></mroot></math> + <div id="dynamic"> + <math><msqrt><mn>1</mn></msqrt></math> + <math><mroot><mn>2</mn><mn>3</mn></mroot></math> + </div> + </div> + <script src="/mathml/support/feature-detection.js"></script> + <script> + window.addEventListener("load", () => { + document.getElementById("dynamic").style.visibility = "hidden"; + document.documentElement.classList.remove("reftest-wait"); + }); + </script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_msqrt");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative-ref.html new file mode 100644 index 0000000000..fcaf5fe85b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>visibility (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative.html new file mode 100644 index 0000000000..28678eaf0c --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>visibility</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext"> +<link rel="help" href="https://github.com/mathml-refresh/mathml-core/pull/24"> +<link rel="match" href="visibility-004.tentative-ref.html"/> +<meta name="assert" content="Verify that visibility=hidden is used for the text and graphical elements of the menclose element."> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px;"> + <math><menclose notation="left" style="visibility: hidden"><mn>1</mn></menclose></math> + <math><menclose notation="right" style="visibility: hidden"><mn>2</mn></menclose></math> + <math><menclose notation="top" style="visibility: hidden"><mn>3</mn></menclose></math> + <math><menclose notation="bottom" style="visibility: hidden"><mn>4</mn></menclose></math> + <math><menclose notation="box" style="visibility: hidden"><mn>5</mn></menclose></math> + <math><menclose notation="roundedbox" style="visibility: hidden"><mn>6</mn></menclose></math> + <math><menclose notation="actuarial" style="visibility: hidden"><mn>7</mn></menclose></math> + <math><menclose notation="madruwb" style="visibility: hidden"><mn>8</mn></menclose></math> + <math><menclose notation="horizontalstrike" style="visibility: hidden"><mn>9</mn></menclose></math> + <math><menclose notation="verticalstrike" style="visibility: hidden"><mn>10</mn></menclose></math> + <math><menclose notation="updiagonalstrike" style="visibility: hidden"><mn>11</mn></menclose></math> + <math><menclose notation="downdiagonalstrike" style="visibility: hidden"><mn>12</mn></menclose></math> + <math><menclose notation="longdiv" style="visibility: hidden"><mn>13</mn></menclose></math> + <math><menclose notation="circle" style="visibility: hidden"><mn>14</mn></menclose></math> + <div id="dynamic"> + <math><menclose notation="left"><mn>1</mn></menclose></math> + <math><menclose notation="right"><mn>2</mn></menclose></math> + <math><menclose notation="top"><mn>3</mn></menclose></math> + <math><menclose notation="bottom"><mn>4</mn></menclose></math> + <math><menclose notation="box"><mn>5</mn></menclose></math> + <math><menclose notation="roundedbox"><mn>6</mn></menclose></math> + <math><menclose notation="actuarial"><mn>7</mn></menclose></math> + <math><menclose notation="madruwb"><mn>8</mn></menclose></math> + <math><menclose notation="horizontalstrike"><mn>9</mn></menclose></math> + <math><menclose notation="verticalstrike"><mn>10</mn></menclose></math> + <math><menclose notation="updiagonalstrike"><mn>11</mn></menclose></math> + <math><menclose notation="downdiagonalstrike"><mn>12</mn></menclose></math> + <math><menclose notation="longdiv"><mn>13</mn></menclose></math> + <math><menclose notation="circle"><mn>14</mn></menclose></math> + </div> + </div> + <script> + window.addEventListener("load", () => { + document.getElementById("dynamic").style.visibility = "hidden"; + document.documentElement.classList.remove("reftest-wait"); + }); + </script> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_menclose");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-005-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-005-ref.html new file mode 100644 index 0000000000..fcaf5fe85b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-005-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>visibility (reference)</title> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; width: 200px; height: 200px;"> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-005.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-005.html new file mode 100644 index 0000000000..a3af376fea --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-005.html @@ -0,0 +1,88 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"> +<title>visibility</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo"> +<link rel="match" href="visibility-005-ref.html"/> +<meta name="assert" content="Verify that visibility=hidden is used for normal, stretchy and large operators."> +<style> + math { + font: 20px/1 Ahem; + } + @font-face { + font-family: operators; + src: url("/fonts/math/operators.woff"); + } + mo { + font-family: operators; + } +</style> +</head> +<body> + <p>Test passes if you see a green square.</p> + <div style="background: green; color: red; width: 200px; height: 200px;"> + <math> + <!-- unstretched operators --> + <mo style="visibility: hidden">⥯</mo> + <mo style="visibility: hidden">+</mo> + <mo style="visibility: hidden">-</mo> + </math> + <math displaystyle="true"> + <!-- large operator --> + <mo largeop="true" style="visibility: hidden">⥯</mo> + </math> + <math> + <mrow> + <!-- stretchy, small size --> + <mspace height="2em"/> + <mo style="visibility: hidden">⥯</mo> + </mrow> + </math> + <math> + <mrow> + <!-- stretchy, large size --> + <mspace height="4em"/> + <mo style="visibility: hidden">⥯</mo> + </mrow> + </math> + <div id="dynamic"> + <math> + <!-- unstretched operators --> + <mo stretchy="false">⥯</mo> + <mo>+</mo> + <mo>-</mo> + </math> + <math displaystyle="true"> + <!-- large operator --> + <mo largeop="true">⥯</mo> + </math> + <math> + <mrow> + <!-- stretchy, small size --> + <mspace height="2em"/> + <mo>⥯</mo> + </mrow> + </math> + <math> + <mrow> + <!-- stretchy, large size --> + <mspace height="4em"/> + <mo>⥯</mo> + </mrow> + </math> + </div> + </div> + <script src="/mathml/support/fonts.js"></script> + <script> + window.addEventListener("load", () => loadAllFonts().then(() => { + document.getElementById("dynamic").style.visibility = "hidden"; + document.documentElement.classList.remove("reftest-wait"); + })); + </script> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_menclose");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-001.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-001.html new file mode 100644 index 0000000000..2deedc3f0b --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-001.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>width, height, inline-size and block-size</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify that width, height, inline-size and block-size properties are ignored."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/mathml/support/box-comparison.js"></script> +<style> + /* Revert style specified in the UA style sheet that changes box size. */ + merror { border: 0; } + mfrac { padding: 0; } +</style> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag)) + continue; + + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;"><math><mrow>${MathMLFragments[tag]}</mrow></math></div>`); + let div = document.body.lastElementChild; + let element = FragmentHelper.element(div.firstElementChild); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var style = `width: 500px; height: 400px;`; + element.setAttribute("style", style); + let box = element.getBoundingClientRect(); + assert_approx_equals(box.width, 500, epsilon, "width"); + assert_approx_equals(box.height, 400, epsilon, "height"); + }, `width and height properties on ${tag}`); + + test(function() { + assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); + var style = `inline-size: 600px; block-size: 700px;`; + element.setAttribute("style", style); + let box = element.getBoundingClientRect(); + assert_approx_equals(box.width, 600, epsilon, "width"); + assert_approx_equals(box.height, 700, epsilon, "height"); + }, `inline-size and block-size properties on ${tag}`); + + div.style = "display: none;"; // Hide the div after measurement. + } + + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-002-ref.html new file mode 100644 index 0000000000..ed5125e952 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-002-ref.html @@ -0,0 +1,162 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>content position with width/height (reference)</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + body, math { + font: 25px/1 Ahem; + color: black; + } + .test { + margin: .5em; + } + .box { + width: 7em; + height: 3em; + border: 1px solid blue; + display: inline-block; + } + .center { + text-align: center; + } + + /* Revert style specified in the UA style sheet that changes box size. */ + mfrac { padding: 0; } +</style> +</head> +<body> + <div class="test"> + <div class="box"> + <math> + <mtext>X</mtext> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <mtext>X</mtext> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <mrow> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mrow> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <mrow> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mrow> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <mpadded lspace="1em" voffset="-1em"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mpadded> + </math> + </diV> + <div class="box" dir="rtl"> + <math dir="rtl"> + <mpadded lspace="1em" voffset="-1em"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mpadded> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <mpadded width="9em" height="1em" depth=".5em"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mpadded> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <mpadded width="9em" height="1em" depth=".5em"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mpadded> + </math> + </div> + </div> + + <div class="test"> + <div class="box center"> + <math> + <mfrac linethickness="0"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + </math> + </div> + <div class="box center" dir="rtl"> + <math dir="rtl"> + <mfrac linethickness="0"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <msqrt> + <mtext>X</mtext> + </msqrt> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <msqrt> + <mtext>X</mtext> + </msqrt> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <mroot> + <mtext>X</mtext> + <mtext>X</mtext> + </mroot> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <mroot> + <mtext>X</mtext> + <mtext>X</mtext> + </mroot> + </math> + </div> + </div> + +</body> +</htmL> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-002.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-002.html new file mode 100644 index 0000000000..99822c1ed9 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-002.html @@ -0,0 +1,135 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>content position with width/height</title> +<link rel="match" href="width-height-002-ref.html"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<meta name="assert" content="Verify the inline-start and block-start edges of the math content box for the mtext, mrow, mpadded, mfrac, msqrt, mroot layout algorithms."/> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + body, math { + font: 25px/1 Ahem; + color: black; + } + .test { + margin: .5em; + } + .box { + width: 7em; + height: 3em; + border: 1px solid blue; + } + + /* Revert style specified in the UA style sheet that changes box size. */ + mfrac { padding: 0; } +</style> +</head> +<body> + + <div class="test"> + <math> + <mtext class="box">X</mtext> + </math> + <math dir="rtl"> + <mtext class="box">X</mtext> + </math> + </div> + + <div class="test"> + <math> + <mrow class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mrow> + </math> + <math dir="rtl"> + <mrow class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mrow> + </math> + </div> + + <div class="test"> + <math> + <mpadded lspace="1em" voffset="-1em" class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mpadded> + </math> + <math dir="rtl"> + <mpadded lspace="1em" voffset="-1em" class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mpadded> + </math> + </div> + + <div class="test"> + <math> + <mpadded width="9em" height="1em" depth=".5em" class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mpadded> + </math> + <math dir="rtl"> + <mpadded width="9em" height="1em" depth=".5em" class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </mpadded> + </math> + </div> + + <div class="test"> + <math> + <mfrac class="box" linethickness="0"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + </math> + <math dir="rtl"> + <mfrac class="box" linethickness="0"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + </math> + </div> + + <div class="test"> + <math> + <msqrt class="box"> + <mtext>X</mtext> + </msqrt> + </math> + <math dir="rtl"> + <msqrt class="box"> + <mtext>X</mtext> + </msqrt> + </math> + </div> + + <div class="test"> + <math> + <mroot class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </mroot> + </math> + <math dir="rtl"> + <mroot class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </mroot> + </math> + </div> + +</body> +</htmL> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-003-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-003-ref.html new file mode 100644 index 0000000000..84eb2cd089 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-003-ref.html @@ -0,0 +1,178 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>content position with width/height (reference)</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + body, math { + font: 25px/1 Ahem; + color: black; + } + .test { + margin: .5em; + } + .box { + width: 7em; + height: 3em; + border: 1px solid blue; + display: inline-block; + } + .center { + text-align: center; + } +</style> +</head> +<body> + + <div class="test"> + <div class="box center"> + <math> + <munder> + <mtext>X</mtext> + <mtext>X</mtext> + </munder> + </math> + </div> + <div class="box center" dir="rtl"> + <math dir="rtl"> + <munder> + <mtext>X</mtext> + <mtext>X</mtext> + </munder> + </math> + </div> + </div> + + <div class="test"> + <div class="box center"> + <math> + <mover> + <mtext>X</mtext> + <mtext>X</mtext> + </mover> + </math> + </div> + <div class="box center" dir="rtl"> + <math dir="rtl"> + <mover> + <mtext>X</mtext> + <mtext>X</mtext> + </mover> + </math> + </div> + </div> + + <div class="test"> + <div class="box center"> + <math> + <munderover> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + </math> + </div> + <div class="box center" dir="rtl"> + <math dir="rtl"> + <munderover> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <msub> + <mtext>X</mtext> + <mtext>X</mtext> + </msub> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <msub> + <mtext>X</mtext> + <mtext>X</mtext> + </msub> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <msup> + <mtext>X</mtext> + <mtext>X</mtext> + </msup> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <msup> + <mtext>X</mtext> + <mtext>X</mtext> + </msup> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <msubsup> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </msubsup> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <msubsup> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </msubsup> + </math> + </div> + </div> + + <div class="test"> + <div class="box"> + <math> + <mmultiscripts> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mprescripts/> + <mtext>X</mtext> + <mtext>X</mtext> + </mmultiscripts> + </math> + </div> + <div class="box" dir="rtl"> + <math dir="rtl"> + <mmultiscripts> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mprescripts/> + <mtext>X</mtext> + <mtext>X</mtext> + </mmultiscripts> + </math> + </div> + </div> + +</body> +</htmL> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-003.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-003.html new file mode 100644 index 0000000000..05e00f4759 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-003.html @@ -0,0 +1,150 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>content position with width/height</title> +<link rel="match" href="width-height-003-ref.html"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Verify the inline-start and block-start edges of the math content box for the munder, mover, munderover, msub, msup, msubsup, multiscripts layout algorithms."/> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> + body, math { + font: 25px/1 Ahem; + color: black; + } + .test { + margin: .5em; + } + .box { + width: 7em; + height: 3em; + border: 1px solid blue; + } +</style> +</head> +<body> + + <div class="test"> + <math> + <munder class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </munder> + </math> + <math dir="rtl"> + <munder class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </munder> + </math> + </div> + + <div class="test"> + <math> + <mover class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </mover> + </math> + <math dir="rtl"> + <mover class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </mover> + </math> + </div> + + <div class="test"> + <math> + <munderover class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + </math> + <math dir="rtl"> + <munderover class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + </math> + </div> + + <div class="test"> + <math> + <msub class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </msub> + </math> + <math dir="rtl"> + <msub class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </msub> + </math> + </div> + + <div class="test"> + <math> + <msup class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </msup> + </math> + <math dir="rtl"> + <msup class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + </msup> + </math> + </div> + + <div class="test"> + <math> + <msubsup class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </msubsup> + </math> + <math dir="rtl"> + <msubsup class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </msubsup> + </math> + </div> + + <div class="test"> + <math> + <mmultiscripts class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mprescripts/> + <mtext>X</mtext> + <mtext>X</mtext> + </mmultiscripts> + </math> + <math dir="rtl"> + <mmultiscripts class="box"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + <mprescripts/> + <mtext>X</mtext> + <mtext>X</mtext> + </mmultiscripts> + </math> + </div> + +</body> +</htmL> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-004.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-004.html new file mode 100644 index 0000000000..7133573b04 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-004.html @@ -0,0 +1,133 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>content position with width/height</title> +<link rel="match" href="width-height-003-ref.html"> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Verify the inline-start of the children of the munder, mover, munderover and mfrac layout algorithms."/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<script src="/mathml/support/fonts.js"></script> +<style> + .test, math { + font: 25px/1 Ahem; + color: black; + } + .test { + margin: .5em; + } + [data-name] { + width: 7em; + height: 3em; + border: 1px solid blue; + } +</style> +<script> + var epsilon = 1; + + function getMiddle(aElement) { + let box = aElement.getBoundingClientRect(); + return (box.left + box.right) / 2; + } + + setup({ explicit_done: true }); + window.addEventListener("load", () => { loadAllFonts().then(runTests); }); + + function runTests() { + Array.from(document.querySelectorAll("[data-name]")).forEach(element => { + test(() => { + let elementMiddle = getMiddle(element); + Array.from(element.children).forEach(child => { + assert_approx_equals(getMiddle(child), elementMiddle, epsilon); + }); + }, element.dataset.name); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + + <div class="test"> + <math> + <mfrac data-name="mfrac"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + </math> + <math dir="rtl"> + <mfrac data-name="RTL mfrac"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + </math> + </div> + + <div class="test"> + <math> + <mfrac linethickness="0" data-name="mfrac without bar"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + </math> + <math dir="rtl"> + <mfrac linethickness="0" data-name="RTL mfrac without bar"> + <mtext>X</mtext> + <mtext>X</mtext> + </mfrac> + </math> + </div> + + <div class="test"> + <math> + <munder data-name="munder"> + <mtext>X</mtext> + <mtext>X</mtext> + </munder> + </math> + <math dir="rtl"> + <munder data-name="RTL munder"> + <mtext>X</mtext> + <mtext>X</mtext> + </munder> + </math> + </div> + + <div class="test"> + <math> + <mover data-name="mover"> + <mtext>X</mtext> + <mtext>X</mtext> + </mover> + </math> + <math dir="rtl"> + <mover data-name="RTL mover"> + <mtext>X</mtext> + <mtext>X</mtext> + </mover> + </math> + </div> + + <div class="test"> + <math> + <munderover data-name="munderover"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + </math> + <math dir="rtl"> + <munderover data-name="RTL munderover"> + <mtext>X</mtext> + <mtext>X</mtext> + <mtext>X</mtext> + </munderover> + </math> + </div> + +</body> +</htmL> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/force-horizontal-tb.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/force-horizontal-tb.html new file mode 100644 index 0000000000..e239cdca5a --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/force-horizontal-tb.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Forced writing-mode on MathML elements</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet"> +<meta name="assert" content="Test that writing-mode is forced to horizontal-tb on MathML elements."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<style> + /* selector defined in mathml-fragments.js */ + .element { + writing-mode: vertical-lr; + padding-block-start: 10px; + padding-block-end: 15px; + padding-inline-start: 20px; + padding-inline-end: 25px; + } +</style> +</head> +<body> + <div id="log"></div> + <div id="container"> + <math class="element"></math> + </div> + <script> + var container = document.getElementById("container"); + for (tag in MathMLFragments) { + container.insertAdjacentHTML("beforeend", `<math>${MathMLFragments[tag]}</math>`); + } + let unknownElement = FragmentHelper.createElement("unknown"); + unknownElement.setAttribute("class", "element"); + container.appendChild(unknownElement); + Array.from(document.getElementsByClassName("element")).forEach(element => { + var tag = element.tagName; + var style = window.getComputedStyle(element); + test(function () { + assert_equals(style["writing-mode"], "horizontal-tb"); + }, `writing-mode is forced to horizontal-tb on <${tag}> element`); + test(function () { + assert_equals(style["padding-block-start"], style["padding-top"]); + assert_equals(style["padding-block-end"], style["padding-bottom"]); + assert_equals(style["padding-inline-start"], style["padding-left"]); + assert_equals(style["padding-inline-end"], style["padding-right"]); + }, `logical properties interpreted in horizontal-tb on <${tag}> element`); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property-ref.html new file mode 100644 index 0000000000..6eae88efb1 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Reset writing-mode and logical property (reference)</title> + </head> + <body> + <p>Test passes if you see a green square.</p> + <math style="writing-mode: horizontal-tb; + padding-top: 200px; + background: green"> + <mspace width="200px"/> + </math> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property.html new file mode 100644 index 0000000000..939cfc5ba6 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Reset writing-mode and logical property</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> + <meta name="assert" content="Verify how forced writing-mode is taken into account for logicial properties."> + <link rel="match" href="reset-and-logicial-property-ref.html"> + </head> + <body> + <p>Test passes if you see a green square.</p> + <math style="writing-mode: vertical-lr; + padding-block-start: 200px; + background: green"> + <mspace width="200px"/> + </math> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-001.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-001.html new file mode 100644 index 0000000000..b751caf90d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-001.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>writing mode</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify CSS writing mode (writing-mode and directionproperties) for mrow."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + var reference = document.getElementById("horizontal-tb_ltr"); + + ["horizontal-tb_rtl"].forEach(id => { + var element = document.getElementById(id); + + test(function() { + var style = window.getComputedStyle(element); + var writingMode = id.split("_"); + assert_equals(style.getPropertyValue("writing-mode"), + writingMode[0], "writing-mode"); + assert_equals(style.getPropertyValue("direction"), + writingMode[1], "direction"); + }, `Inheritance of CSS writing-mode and direction (id='${id}')`); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + compareLayout(element, reference, epsilon); + }, `Layout of mrow (id='${id}')`); + }); + done(); + } +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mrow id="horizontal-tb_ltr"> + <mspace style="background: blue" + width="20px" height="30px" depth="40px"></mspace> + <mspace style="background: black" + width="50px" depth="60px"></mspace> + <mspace style="background: yellow" + width="70px" height="80px"></mspace> + </mrow> + </math> + </p> + <p> + <math style="direction: rtl;"> + <mrow id="horizontal-tb_rtl"> + <mspace style="background: blue" + width="20px" height="30px" depth="40px"></mspace> + <mspace style="background: black" + width="50px" depth="60px"></mspace> + <mspace style="background: yellow" + width="70px" height="80px"></mspace> + </mrow> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-002.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-002.html new file mode 100644 index 0000000000..c0b64a917a --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-002.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>writing mode</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> +<meta name="assert" content="Verify CSS writing mode (writing-mode and direction properties) for mrow."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script src="/mathml/support/mathml-fragments.js"></script> +<script> + var epsilon = 1; + + setup({ explicit_done: true }); + window.addEventListener("load", runTests); + + function runTests() { + for (tag in MathMLFragments) { + if (tag == "annotation" || tag == "annotation-xml") + continue; // These tags have display: none. + + ["horizontal-tb_rtl"].forEach(id => { + var writingMode = id.split("_"); + var writingModeString = `writing-mode: ${writingMode[0]}; direction: ${writingMode[1]};`; + + document.body.insertAdjacentHTML("beforeend", `<div>\ +<math>${MathMLFragments[tag]}</math>\ +<math>${MathMLFragments[tag]}</math>\ +</div>`); + var div = document.body.lastElementChild; + + var styleMath = div.firstElementChild; + styleMath.setAttribute("style", writingModeString); + var styleElement = FragmentHelper.element(styleMath); + + var referenceMath = div.lastElementChild; + var referenceElement = FragmentHelper.element(referenceMath); + + [styleMath, referenceMath].forEach(math => { + Array.from(math.getElementsByClassName("mathml-container")).forEach(container => { + container.insertAdjacentHTML("beforeend", "\ +<mspace style='background: blue'\ + width='20px' height='30px' depth='40px'></mspace>\ +<mspace style='background: black'\ + width='50px' depth='60px'></mspace>\ +<mspace style='background: yellow'\ + width='70px' height='80px'></mspace>"); + }); + Array.from(math.getElementsByClassName("foreign-container")).forEach(container => { + container.insertAdjacentHTML("beforeend", "\ +<span style='display: inline-block; background: lightblue;\ + inline-size: 20px; block-size: 30px;\ + vertical-align: bottom;'></span>\ +<span style='display: inline-block; background: pink;\ + inline-size: 40px; block-size: 50px;\ + vertical-align: bottom;'></span>"); + }); + }); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + var style = window.getComputedStyle(styleElement); + assert_equals(style.getPropertyValue("writing-mode"), + writingMode[0], "writing-mode"); + assert_equals(style.getPropertyValue("direction"), + writingMode[1], "direction"); + compareLayout(styleElement, referenceElement, epsilon); + }, `Layout of ${tag} (${writingModeString})`); + + div.style = "display: none;"; // Hide the div after testing. + }); + } + done(); + } +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/class-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/class-1-ref.html new file mode 100644 index 0000000000..5afa59ecf2 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/class-1-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Class (reference)</title> +</head> +<body> + + <p>Test passes if you see the text "PASS".</p> + <math> + <mtext style="background: green; color: white;">PASS</mtext> + </math> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/class-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/class-1.html new file mode 100644 index 0000000000..fd1678d440 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/class-1.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Class</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="class-1-ref.html"/> +<meta name="assert" content="Verify that the class attribute affects CSS selectors."> +<style> + mtext.fail { display: none; } + mtext.pass { background: green; } +</style> +</head> +<body> + + <p>Test passes if you see the text "PASS".</p> + <math> + <mtext class="fail" style="background: red; color: white;">FAIL</mtext> + <mtext class="pass" style="color: white;">PASS</mtext> + </math> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/class-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/class-2.html new file mode 100644 index 0000000000..e694b063a6 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/class-2.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Class</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<meta name="assert" content="Verify whether the getElementsByClassName() works for MathML elements."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("DOMContentLoaded", function() { + var mtext = document.getElementsByClassName("cl"); + test(function() { + assert_equals(mtext.length, 3); + var mtext_ref = document.body.lastElementChild.firstElementChild; + mtext_ref = mtext_ref.nextElementSibling.nextElementSibling + assert_equals(mtext[0], mtext_ref); + mtext_ref = mtext_ref.nextElementSibling.nextElementSibling; + assert_equals(mtext[1], mtext_ref); + mtext_ref = mtext_ref.nextElementSibling.nextElementSibling; + assert_equals(mtext[2], mtext_ref); + }, "getElementsByClassName()"); + done(); + }); +</script> +</head> +<body> + <div id="log"></div> + <math> + <mtext class="cl_"></mtext> + <mtext class="c"></mtext> + <mtext class="cl"></mtext> + <mtext class="cl_"></mtext> + <mtext class="cl"></mtext> + <mtext class="c"></mtext> + <mtext class="cl"></mtext> + <mtext class="cl_"></mtext> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html new file mode 100644 index 0000000000..bf2f8d11ed --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html @@ -0,0 +1,119 @@ +<!DOCTYPE html> +<title>clipboard event handlers for MathML</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/> +<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#globaleventhandlers"/> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-copy"/> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-cut"/> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-paste"/> +<meta + name="assert" + content="MathMLElements incorporates oncopy / oncut / onpaste event handlers" +/> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<math + oncopy="window.copyHappened1 = true" + oncut="window.cutHappened1 = true" + onpaste="window.pasteHappened1 = true" +> + <mi>E</mi> +</math> +<script> + const EVENTS = ["copy", "cut", "paste"]; + const el = document.querySelector("math"); + + function dispatchEventTest(name) { + const mathEl = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + test(() => { + let target = undefined; + mathEl[`on${name}`] = (e) => { target = e.currentTarget; } + const event = new ClipboardEvent(name, { + bubbles: true, + cancellable: true + }); + mathEl.dispatchEvent(event); + assert_equals(target, mathEl, "The event must be fired at the <math> element"); + }, `${name}: dispatching an Event at a <math> element must trigger element.on${name}`); + } + + function evaluatedHandlerTest(name) { + const handlerName = "on" + name; + + test(() => { + const compiledHandler = el[handlerName]; + + assert_equals( + typeof compiledHandler, + "function", + `The ${handlerName} property must be a function` + ); + compiledHandler(); + assert_true( + window[`${name}Happened1`], + "Calling the handler must run the code" + ); + }, `${handlerName}: the content attribute must be compiled into a function as the corresponding property`); + + test(() => { + const mathEl = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + assert_equals(mathEl[handlerName], null, `The ${handlerName} property must be null (no attribute)`); + + mathEl.setAttribute(handlerName, `window.${handlerName}Happened2 = true;`); + const compiledHandler = mathEl[handlerName]; + assert_equals( + typeof compiledHandler, + "function", + `The ${handlerName} property must be a function (set attribute)` + ); + compiledHandler(); + assert_true( + window[`${handlerName}Happened2`], + "Calling the handler must run the code (set attribute)" + ); + + window[`${handlerName}Happened2`] = false; + const clonedMathEl = mathEl.cloneNode(true); + const clonedCompiledHandler = clonedMathEl[handlerName]; + assert_equals( + typeof clonedCompiledHandler, + "function", + `The ${handlerName} property must be a function (clone node)` + ); + clonedCompiledHandler(); + assert_true( + window[`${handlerName}Happened2`], + "Calling the handler must run the code (clone node)" + ); + + mathEl.setAttribute(handlerName, `window.${handlerName}Happened3 = true;`); + const newCompiledHandler = mathEl[handlerName]; + assert_equals( + typeof newCompiledHandler, + "function", + `The ${handlerName} property must be a function (modify attribute)` + ); + newCompiledHandler(); + assert_true( + window[`${handlerName}Happened3`], + "Calling the handler must run the code (modify attribute)" + ); + + mathEl.removeAttribute(handlerName); + assert_equals(mathEl[handlerName], null, `The ${handlerName} property must be null (remove attribute)`); + }, `${handlerName}: dynamic changes on the attribute`); + + } + + EVENTS.forEach(name => { + dispatchEventTest(name); + evaluatedHandlerTest(name); + }); +</script> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1-ref.html new file mode 100644 index 0000000000..71ee8cea9d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1-ref.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Color Attributes (reference)</title> +<style> + #content > div { + position: absolute; + } +</style> +</head> +<body> + + <p>Test passes if you see the text below is written in white on a green + background.</p> + + <div id="content"> + <div> + <math style="background: green;"> + <mtext style="color: white;">Hello World!</mtext> + </math> + </div> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1.html new file mode 100644 index 0000000000..211bda7f85 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Color Attributes</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes"> +<meta name="assert" content="Verify that the mathcolor and mathbackground attributes are supported on the math element."> +<link rel="match" href="color-attributes-1-ref.html"/> +<style> + #content { + color: red; + } + #content > div { + position: absolute; + } +</style> +</head> +<body> + + <p>Test passes if you see the text below is written in white on a green + background.</p> + + <div id="content"> + <div> + <math style="background: red;"> + <mtext style="visibility: hidden;">Hello World!</mtext> + </math> + </div> + <div> + <math mathcolor="white" mathbackground="green"> + <mtext>Hello World!</mtext> + </math> + </div> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/content-editable.html b/testing/web-platform/tests/mathml/relations/html5-tree/content-editable.html new file mode 100644 index 0000000000..28e8630829 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/content-editable.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML inside content-editable</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg"> +<meta name="assert" content="Verify that putting MathML inside a content-editable div shouldn't affect its layout."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("DOMContentLoaded", function() { + var epsilon = 1; + var mfrac = document.getElementById("mfrac"); + var num = mfrac.firstElementChild.getBoundingClientRect(); + var denom = mfrac.lastElementChild.getBoundingClientRect(); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(num.width, 30, epsilon, "numerator width"); + assert_approx_equals(num.height, 40, epsilon, "numerator height"); + assert_approx_equals(denom.width, 50, epsilon, "denominator width"); + assert_approx_equals(denom.height, 60, epsilon, "denominator height"); + }, "mspace layout in content-editable div"); + test(function() { + assert_true(MathMLFeatureDetection.has_mfrac()); + assert_greater_than_equal(denom.bottom - num.top, + (40 + 60), + "numerator is above the denominator"); + assert_approx_equals((num.left + num.right) / 2, + (denom.left + denom.right) / 2, + epsilon, "numerator and denominator are horizontally aligned"); + }, "mfrac layout in content-editable div"); + done(); + }); +</script> +</head> +<body> + <div id="log"></div> + <div contenteditable="true"> + This is + <math> + <mfrac id="mfrac"> + <mspace width="30px" height="40px" style="background: cyan"></mspace> + <mspace width="50px" height="60px" style="background: yellow"></mspace> + </mfrac> + </math> + a content editable div + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative-ref.html new file mode 100644 index 0000000000..19f3e6c82a --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML 'ElementCSSInlineStyle` Dynamic Tests</title> +<style> +mspace { + background-color: green; +} +</style> +</head> +<body> + <span>This tests that `ElementCSSInlineStyle` interface changes update rendering.</span> + <div> + <math><mspace width="50px" height="100px"/><mspace width="50px" height="100px"/></math> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative.html new file mode 100644 index 0000000000..5d27d6a7e6 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html class="reftest-wait"> + <head> + <meta charset="utf-8" /> + <title>MathML 'ElementCSSInlineStyle` Dynamic Tests</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/> + <link rel="match" href="css-inline-style-dynamic.tentative-ref.html"/> + <script src="/mathml/support/feature-detection.js"></script> + <style> + #hidden { + visibility: hidden; + background-color: green; + } + #red { + background-color: red; + } + </style> + <meta + name="assert" + content="MathMLElements ElementCSSInlineStyle interface changes update rendering" + /> + <script type="text/javascript"> + function test() + { + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + document.body.offsetTop; // Update layout + + var mspace = document.getElementById("hidden"); + if (mspace.style) + mspace.style.visibility = "visible"; + + mspace = document.getElementById("red"); + if (mspace.style) + mspace.style.backgroundColor = "green"; + + document.documentElement.className = ""; + } + </script> + </head> + <body onload="test()"> + <span>This tests that `ElementCSSInlineStyle` interface changes update rendering.</span> + <div> + <math><mspace width="50px" height="100px" id="hidden"/><mspace width="50px" height="100px" id="red"/></math> + </div> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-interface.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-interface.tentative.html new file mode 100644 index 0000000000..f8348c15b2 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-interface.tentative.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>MathML 'ElementCSSInlineStyle` Mixin Tests</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/> + <style> + math * { + background-color: red; + } + </style> + <meta + name="assert" + content="MathMLElements incorporate a functional ElementCSSInlineStyle interface" + /> + <script src="/mathml/support/mathml-fragments.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <span + >This tests the presence and functionality of features of the + `ElementCSSInlineStyle` interface for MathMLElements</span + > + <math></math> + <script> + let mathEl = document.querySelector("math"); + + test(function() { + mathEl.style.backgroundColor = "lime"; + assert_equals( + getComputedStyle(mathEl).backgroundColor, + "rgb(0, 255, 0)", + "The applied background should be green." + ); + }, `The <math> element style property should be present and be functional.`); + + Object.keys(MathMLFragments).forEach(elName => { + mathEl.innerHTML = MathMLFragments[elName]; + + test(function() { + let el = FragmentHelper.element(mathEl); + el.style.backgroundColor = "blue"; + + assert_equals( + getComputedStyle(el).backgroundColor, + "rgb(0, 0, 255)", + "The applied background should be blue." + ); + }, `The ${elName}'s style property should be present and be functional.`); + }); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/display-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/display-1.html new file mode 100644 index 0000000000..fa92771fac --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/display-1.html @@ -0,0 +1,175 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML display attribute</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<meta name="assert" content="Verify that the display attribute on the math element is supported and impacts centering and line breaking with surrounding content."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/attribute-values.js"></script> +<script> + function getBox(aId) { + return document.getElementById(aId).getBoundingClientRect(); + } + window.addEventListener("DOMContentLoaded", function() { + for (transform in AttributeValueTransforms) { + TransformAttributeValues(transform, ["display"]); + var content = getBox("content"); + + var before_block = getBox("before_block"); + var mspace_block = getBox("mspace_block"); + var after_block = getBox("after_block"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(before_block.left, content.left, 1, + "content before must be left aligned"); + assert_approx_equals((mspace_block.left + mspace_block.right) / 2, + (content.left + content.right) / 2, + 1, + "math must be centered."); + assert_approx_equals(after_block.left, content.left, 1, + "content after must be left aligned"); + assert_less_than_equal(before_block.bottom, mspace_block.top, + "new line before math"); + assert_less_than_equal(mspace_block.bottom, after_block.top, + "new line after math"); + }, `Test display math ${transform}`); + + var before_inline = getBox("before_inline"); + var mspace_inline = getBox("mspace_inline"); + var after_inline = getBox("after_inline"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals((before_inline.top + before_inline.bottom) / 2, + (mspace_inline.top + mspace_inline.bottom) / 2, + 1, + "content before must be horizontally aligned with math"); + assert_approx_equals((after_inline.top + after_inline.bottom) / 2, + (mspace_inline.top + mspace_inline.bottom) / 2, + 1, + "content after must be horizontally aligned with math"); + assert_less_than_equal(before_inline.right, mspace_inline.left, + "content before must be on the left of math"); + assert_less_than_equal(mspace_inline.right, after_inline.left, + "content after must be on the right of math"); + }, `Test inline math ${transform}`); + + var before_block_and_specified_width = getBox("before_block_and_specified_width"); + var mspace_width = getBox("mspace_width"); + var after_block_and_specified_width = getBox("after_block_and_specified_width"); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + let math = getBox("math_with_specified_width"); + assert_approx_equals(before_block_and_specified_width.left, math.left, 1, + "content before must be left aligned"); + assert_approx_equals(math.width, 100, 1, + "math uses specified width."); + assert_approx_equals((mspace_width.left + mspace_width.right) / 2, + (math.left + math.right) / 2, + 1, + "math must be centered."); + assert_approx_equals(after_block_and_specified_width.left, math.left, 1, + "content after must be left aligned"); + assert_less_than_equal(before_block_and_specified_width.bottom, mspace_width.top, + "new line before math"); + assert_less_than_equal(mspace_width.bottom, after_block_and_specified_width.top, + "new line after math"); + }, `Test width on display=block math ${transform}`); + } + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + document.getElementById("mspace_dynamic_block").parentNode. + setAttribute("display", "block"); + var before_block = getBox("before_dynamic_block"); + var mspace_block = getBox("mspace_dynamic_block"); + var after_block = getBox("after_dynamic_block"); + + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(before_block.left, content.left, 1, + "content before must be left aligned"); + assert_approx_equals((mspace_block.left + mspace_block.right) / 2, + (content.left + content.right) / 2, + 1, + "math must be centered."); + assert_approx_equals(after_block.left, content.left, 1, + "content after must be left aligned"); + assert_less_than_equal(before_block.bottom, mspace_block.top, + "new line before math"); + assert_less_than_equal(mspace_block.bottom, after_block.top, + "new line after math"); + }, "Test dynamically setting display=block"); + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + document.getElementById("mspace_dynamic_inline").parentNode. + removeAttribute("display"); + var before_inline = getBox("before_dynamic_inline"); + var mspace_inline = getBox("mspace_dynamic_inline"); + var after_inline = getBox("after_dynamic_inline"); + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals((before_inline.top + before_inline.bottom) / 2, + (mspace_inline.top + mspace_inline.bottom) / 2, + 1, + "content before must be horizontally aligned with math"); + assert_approx_equals((after_inline.top + after_inline.bottom) / 2, + (mspace_inline.top + mspace_inline.bottom) / 2, + 1, + "content after must be horizontally aligned with math"); + assert_less_than_equal(before_inline.right, mspace_inline.left, + "content before must be on the left of math"); + assert_less_than_equal(mspace_inline.right, after_inline.left, + "content after must be on the right of math"); + }, "Test dynamically setting display=inline"); + + done(); + }); +</script> +<style> + #content { + width: 600px; + background: #ccc; + } + span.square { + display: inline-block; + width: 50px; + height: 50px; + background: black; + } + mspace { + background: blue; + } +</style> +</head> +<body> + <div id="log"></div> + <div id="content"> + <span id="before_block" class="square"></span> + <math display="block"><mspace id="mspace_block" width="50px" height="50px"/></math> + <span id="after_block" class="square"></span> + <br/> + <span id="before_inline" class="square"></span> + <math display="inline"><mspace id="mspace_inline" width="50px" height="50px"/></math> + <span id="after_inline" class="square"></span> + <br/> + <span id="before_block_and_specified_width" class="square"></span> + <math display="block" id="math_with_specified_width" style="background: pink; width:100px"><mspace id="mspace_width" width="50px" height="50px"/></math> + <span id="after_block_and_specified_width" class="square"></span> + <br/> + <div> + <span id="before_dynamic_block" class="square"></span> + <math><mspace id="mspace_dynamic_block" width="50px" height="50px"/></math> + <span id="after_dynamic_block" class="square"></span> + </div> + <div> + <span id="before_dynamic_inline" class="square"></span> + <math display="block"><mspace id="mspace_dynamic_inline" width="50px" height="50px"/></math> + <span id="after_dynamic_inline" class="square"></span> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/display-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/display-2-ref.html new file mode 100644 index 0000000000..7864c04099 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/display-2-ref.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>display attribute VS legacy mode attribute (reference)</title> +</head> +<body> + <p>Test passes if you see four green squares, the last one + centered and the others left-aligned.</p> + <p> + <math> + <mspace width="100px" height="100px" style="background: green"></mspace> + </math> + </p> + <p> + <math> + <mspace width="100px" height="100px" style="background: green"></mspace> + </math> + </p> + <p> + <math display="inline"> + <mspace width="100px" height="100px" style="background: green"></mspace> + </math> + </p> + <p> + <math display="block"> + <mspace width="100px" height="100px" style="background: green"></mspace> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/display-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/display-2.html new file mode 100644 index 0000000000..b4e79395a1 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/display-2.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>display attribute VS legacy mode attribute</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<link rel="help" href="https://www.w3.org/TR/MathML3/chapter2.html#id.2.2.2"> +<link rel="match" href="display-2-ref.html"/> +<meta name="assert" content="Verify that the legacy mode attribute has no effect."> +</head> +<body> + <p>Test passes if you see four green squares, the last one + centered and the others left-aligned.</p> + <p> + <math mode="inline"> + <mspace width="100px" height="100px" style="background: green"></mspace> + </math> + </p> + <p> + <math mode="display"> + <mspace width="100px" height="100px" style="background: green"></mspace> + </math> + </p> + <p> + <math display="inline" mode="display"> + <mspace width="100px" height="100px" style="background: green"></mspace> + </math> + </p> + <p> + <math display="block" mode="inline"> + <mspace width="100px" height="100px" style="background: green"></mspace> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1-ref.html new file mode 100644 index 0000000000..5fa90e9d2f --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Dynamic MathML DOM (reference)</title> +<style> + mtext.pass { background: green; color: white; } +</style> +</head> +<body> + <p>Test passes if you see the text "PASS".</p> + <math> + <mtext class="pass">PASS</mtext> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1.html new file mode 100644 index 0000000000..59403196a8 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Dynamic MathML DOM</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/> +<link rel="match" href="dynamic-1-ref.html"/> +<meta name="assert" content="Verify that the MathML DOM tree can be modified via javascript and that the rendering is correctly updated."> +<style> + mtext.fail { background: red; color: white; } + mtext.pass { background: green; color: white; } +</style> +<script> + window.addEventListener("DOMContentLoaded", function() { + var kMathMLNamespace = "http://www.w3.org/1998/Math/MathML"; + var mtext = document.createElementNS(kMathMLNamespace, "mtext"); + mtext.setAttribute("class", "pass"); + mtext.textContent = "PASS"; + var math = document.getElementsByTagNameNS(kMathMLNamespace, "math")[0]; + math.replaceChild(mtext, math.firstElementChild); + }); +</script> +</head> +<body> + <p>Test passes if you see the text "PASS".</p> + <math> + <mtext class="fail">FAIL</mtext> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2-ref.html new file mode 100644 index 0000000000..272e8b33ca --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Dynamic id and style (reference)</title> +<style> + #pass { background: green; color: white; } +</style> +</head> +<body> + <p>Test passes if you see the text "PASS".</p> + <math> + <mtext id="pass">PASS</mtext> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2.html new file mode 100644 index 0000000000..8ad47c5cd9 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Dynamic id and style</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/> +<link rel="match" href="dynamic-2-ref.html"/> +<meta name="assert" content="Verify dynamic change of id and style attributes."> +<style> + #fail, #fail2 { background: red; color: white; } + #pass { background: green; color: white; } +</style> +<script> + window.addEventListener("DOMContentLoaded", function() { + document.getElementById("fail2").setAttribute("id", "pass"); + document.getElementById("fail").setAttribute("style", "display: none"); + }); +</script> +</head> +<body> + <p>Test passes if you see the text "PASS".</p> + <math> + <mtext id="fail">FAIL</mtext> + <mtext id="fail2">PASS</mtext> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-001.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-001.html new file mode 100644 index 0000000000..ffd0ae239f --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-001.html @@ -0,0 +1,630 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Dynamic childlist of MathML elements</title> +<script src="/mathml/support/mathml-fragments.js"></script> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac"> +<link rel="help" href="https://w3c.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts"> +<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot"> +<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace"> +<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup"> +<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> +<meta name="assert" content="Dynamically modify DOM tree of some MathML elements by adding or removing children."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script> + function forceNumberOfChildren(element, count) { + while (element.children.length > count) + element.removeChild(element.lastElementChild); + for (let i = element.children.length; i < count; i++) { + if (element.tagName === "mmultiscripts" && i === 5) { + element.appendChild(FragmentHelper.createElement("mprescripts")); + } else { + let mspace = FragmentHelper.createElement("mspace"); + mspace.setAttribute("width", `10px`); + mspace.setAttribute("height", `${10*(i+1)}px`); + mspace.setAttribute("style", `background: black;`); + element.appendChild(mspace); + } + } + } + + setup({ explicit_done: true }); + window.addEventListener("load", function() { + // force initial layout so we're sure what we're testing against + document.documentElement.getBoundingClientRect(); + + let reference = document.getElementById("reference"); + + Array.from(document.querySelectorAll("[data-title]")).forEach(element => { + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + let reference = document.getElementById(`${element.getAttribute("data-reference")}`); + forceNumberOfChildren(element, reference.children.length); + const epsilon = 1; + if (element.tagName == "mspace") { + compareSize(element, reference, epsilon); + childrenHaveEmptyBoundingClientRects(element); + childrenHaveEmptyBoundingClientRects(reference); + } else { + compareLayout(element, reference, epsilon); + } + }, `${element.getAttribute("data-title")}`); + }); + done(); + }); +</script> +</head> +<body> + <div id="log"></div> + <p> + <math> + <mfrac id="mfrac-reference-1"> + <mspace width="10px" height="10px" style="background: black;"/> + </mfrac> + <mfrac id="mfrac-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mfrac> + <mfrac id="mfrac-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mfrac> + </math> + </p> + <p> + <math> + <mfrac data-reference="mfrac-reference-2" data-title="Adding missing children to mfrac"> + </mfrac> + </math> + </p> + <p> + <math> + <mfrac data-reference="mfrac-reference-1" data-title="Removing child from valid mfrac"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mfrac> + </math> + </p> + <p> + <math> + <mfrac data-reference="mfrac-reference-3" data-title="Adding child to valid mfrac"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mfrac> + </math> + </p> + <p> + <math> + <mfrac data-reference="mfrac-reference-2" data-title="Removing extra child from mfrac"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mfrac> + </math> + </p> + <hr/> + <p> + <math> + <munder id="munder-reference-1"> + <mspace width="10px" height="10px" style="background: black;"/> + </munder> + <munder id="munder-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </munder> + <munder id="munder-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </munder> + </math> + </p> + <p> + <math> + <munder data-reference="munder-reference-2" data-title="Adding missing children to munder"> + </munder> + </math> + </p> + <p> + <math> + <munder data-reference="munder-reference-1" data-title="Removing child from valid munder"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </munder> + </math> + </p> + <p> + <math> + <munder data-reference="munder-reference-3" data-title="Adding child to valid munder"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </munder> + </math> + </p> + <p> + <math> + <munder data-reference="munder-reference-2" data-title="Removing extra child from munder"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </munder> + </math> + </p> + <hr/> + <p> + <math> + <mover id="mover-reference-1"> + <mspace width="10px" height="10px" style="background: black;"/> + </mover> + <mover id="mover-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mover> + <mover id="mover-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mover> + </math> + </p> + <p> + <math> + <mover data-reference="mover-reference-2" data-title="Adding missing children to mover"> + </mover> + </math> + </p> + <p> + <math> + <mover data-reference="mover-reference-1" data-title="Removing child from valid mover"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mover> + </math> + </p> + <p> + <math> + <mover data-reference="mover-reference-3" data-title="Adding child to valid mover"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mover> + </math> + </p> + <p> + <math> + <mover data-reference="mover-reference-2" data-title="Removing extra child from mover"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mover> + </math> + </p> + <hr/> + <p> + <math> + <munderover id="munderover-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </munderover> + <munderover id="munderover-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </munderover> + <munderover id="munderover-reference-4"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + <mspace width="10px" height="40px" style="background: black;"/> + </munderover> + </math> + </p> + <p> + <math> + <munderover data-reference="munderover-reference-3" data-title="Adding missing children to munderover"> + </munderover> + </math> + </p> + <p> + <math> + <munderover data-reference="munderover-reference-2" data-title="Removing child from valid munderover"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </munderover> + </math> + </p> + <p> + <math> + <munderover data-reference="munderover-reference-4" data-title="Adding child to valid munderover"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </munderover> + </math> + </p> + <p> + <math> + <munderover data-reference="munderover-reference-3" data-title="Removing extra child from munderover"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + <mspace width="10px" height="40px" style="background: black;"/> + </munderover> + </math> + </p> + <hr/> + <p> + <math> + <msub id="msub-reference-1"> + <mspace width="10px" height="10px" style="background: black;"/> + </msub> + <msub id="msub-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </msub> + <msub id="msub-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </msub> + </math> + </p> + <p> + <math> + <msub data-reference="msub-reference-2" data-title="Adding missing children to msub"> + </msub> + </math> + </p> + <p> + <math> + <msub data-reference="msub-reference-1" data-title="Removing child from valid msub"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </msub> + </math> + </p> + <p> + <math> + <msub data-reference="msub-reference-3" data-title="Adding child to valid msub"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </msub> + </math> + </p> + <p> + <math> + <msub data-reference="msub-reference-2" data-title="Removing extra child from msub"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </msub> + </math> + </p> + <hr/> + <p> + <math> + <msup id="msup-reference-1"> + <mspace width="10px" height="10px" style="background: black;"/> + </msup> + <msup id="msup-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </msup> + <msup id="msup-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </msup> + </math> + </p> + <p> + <math> + <msup data-reference="msup-reference-2" data-title="Adding missing children to msup"> + </msup> + </math> + </p> + <p> + <math> + <msup data-reference="msup-reference-1" data-title="Removing child from valid msup"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </msup> + </math> + </p> + <p> + <math> + <msup data-reference="msup-reference-3" data-title="Adding child to valid msup"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </msup> + </math> + </p> + <p> + <math> + <msup data-reference="msup-reference-2" data-title="Removing extra child from msup"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </msup> + </math> + </p> + <hr/> + <p> + <math> + <msubsup id="msubsup-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </msubsup> + <msubsup id="msubsup-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </msubsup> + <msubsup id="msubsup-reference-4"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + <mspace width="10px" height="40px" style="background: black;"/> + </msubsup> + </math> + </p> + <p> + <math> + <msubsup data-reference="msubsup-reference-3" data-title="Adding missing children to msubsup"> + </msubsup> + </math> + </p> + <p> + <math> + <msubsup data-reference="msubsup-reference-2" data-title="Removing child from valid msubsup"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </msubsup> + </math> + </p> + <p> + <math> + <msubsup data-reference="msubsup-reference-4" data-title="Adding child to valid msubsup"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </msubsup> + </math> + </p> + <p> + <math> + <msubsup data-reference="msubsup-reference-3" data-title="Removing extra child from msubsup"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + <mspace width="10px" height="40px" style="background: black;"/> + </msubsup> + </math> + </p> + <hr/> + <p> + <math> + <mroot id="mroot-reference-1"> + <mspace width="10px" height="10px" style="background: black;"/> + </mroot> + <mroot id="mroot-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mroot> + <mroot id="mroot-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mroot> + </math> + </p> + <p> + <math> + <mroot data-reference="mroot-reference-2" data-title="Adding missing children to mroot"> + </mroot> + </math> + </p> + <p> + <math> + <mroot data-reference="mroot-reference-1" data-title="Removing child from valid mroot"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mroot> + </math> + </p> + <p> + <math> + <mroot data-reference="mroot-reference-3" data-title="Adding child to valid mroot"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mroot> + </math> + </p> + <p> + <math> + <mroot data-reference="mroot-reference-2" data-title="Removing extra child from mroot"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mroot> + </math> + </p> + <hr/> + <p> + <math> + <msqrt id="msqrt-reference-0"> + </msqrt> + <msqrt id="msqrt-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </msqrt> + </math> + </p> + <p> + <math> + <msqrt data-reference="msqrt-reference-0" data-title="Removing children from msqrt"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </msqrt> + </math> + </p> + <p> + <math> + <msqrt data-reference="msqrt-reference-2" data-title="Adding children to msqrt"> + <mspace width="10px" height="10px" style="background: black;"/> + </msqrt> + </math> + </p> + <hr/> + <p> + <math> + <mpadded id="mpadded-reference-0"> + </mpadded> + <mpadded id="mpadded-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mpadded> + </math> + </p> + <p> + <math> + <mpadded data-reference="mpadded-reference-0" data-title="Removing children from mpadded"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mpadded> + </math> + </p> + <p> + <math> + <mpadded data-reference="mpadded-reference-2" data-title="Adding children to mpadded"> + <mspace width="10px" height="10px" style="background: black;"/> + </mpadded> + </math> + </p> + <hr/> + <p> + <math> + <mspace id="mspace-reference-0" width="30px" height="70px" style="background: blue"> + </mspace> + <mspace id="mspace-reference-2" width="30px" height="70px" style="background: green"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mspace> + </math> + </p> + <p> + <math> + <mspace data-reference="mspace-reference-0" data-title="Removing children from mspace" width="30px" height="70px" style="background: lightblue"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mspace> + </math> + </p> + <p> + <math> + <mspace data-reference="mspace-reference-2" data-title="Adding children to mspace" width="30px" height="70px" style="background: lightgreen"> + <mspace width="10px" height="10px" style="background: black;"/> + </mspace> + </math> + </p> + <hr/> + <p> + <math> + <mmultiscripts id="mmultiscripts-reference-0"> + </mmultiscripts> + <mmultiscripts id="mmultiscripts-reference-1"> + <mspace width="10px" height="10px" style="background: black;"/> + </mmultiscripts> + <mmultiscripts id="mmultiscripts-reference-2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + </mmultiscripts> + <mmultiscripts id="mmultiscripts-reference-3"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mmultiscripts> + <mmultiscripts id="mmultiscripts-reference-6"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + <mspace width="10px" height="40px" style="background: black;"/> + <mspace width="10px" height="50px" style="background: black;"/> + <mprescripts/> + </mmultiscripts> + <mmultiscripts id="mmultiscripts-reference-8"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + <mspace width="10px" height="40px" style="background: black;"/> + <mspace width="10px" height="50px" style="background: black;"/> + <mprescripts/> + <mspace width="10px" height="70px" style="background: black;"/> + <mspace width="10px" height="80px" style="background: black;"/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-reference="mmultiscripts-reference-0" data-title="multiscripts child count from 3 to 0"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-reference="mmultiscripts-reference-1" data-title="multiscripts child count from 3 to 1"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-reference="mmultiscripts-reference-2" data-title="multiscripts child count from 3 to 2"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-reference="mmultiscripts-reference-3" data-title="multiscripts child count from 0 to 3"> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-reference="mmultiscripts-reference-6" data-title="multiscripts child count from 3 to 6"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mmultiscripts> + </math> + </p> + <p> + <math> + <mmultiscripts data-reference="mmultiscripts-reference-8" data-title="multiscripts child count from 3 to 8"> + <mspace width="10px" height="10px" style="background: black;"/> + <mspace width="10px" height="20px" style="background: black;"/> + <mspace width="10px" height="30px" style="background: black;"/> + </mmultiscripts> + </math> + </p> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-002.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-002.html new file mode 100644 index 0000000000..099401eacc --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-002.html @@ -0,0 +1,119 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Dynamic childlist of MathML elements</title> +<script src="/mathml/support/mathml-fragments.js"></script> +<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<meta name="assert" content="Dynamically modify DOM tree of some MathML elements by adding or removing children."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script src="/mathml/support/layout-comparison.js"></script> +<script> + function generateMathForTag(tag, childCount) { + let math = FragmentHelper.createElement("math"); + let element = FragmentHelper.createElement(tag); + // Add the children with different sizes at odd positions and OOF + // mrow at even position. + for (let i = 0; i < childCount; i++) { + if (i % 2) { + let mspace = FragmentHelper.createElement("mspace"); + mspace.setAttribute("width", `10px`); + mspace.setAttribute("height", `${10*(i+1)}px`); + mspace.setAttribute("style", `background: black;`); + element.appendChild(mspace); + } else { + let mrow = FragmentHelper.createElement("mrow"); + mrow.setAttribute("style", "position: absolute"); + element.appendChild(mrow); + } + } + if (FragmentHelper.isValidChildOfMrow(tag)) { + math.appendChild(element); + } else if (tag === "mtd") { + let mtr = FragmentHelper.createElement("mtr"); + mtr.appendChild(element); + let mtable = FragmentHelper.createElement("mtable"); + mtable.appendChild(mtr); + math.appendChild(mtable); + } else { + throw `Invalid argument: ${tag}`; + } + return math; + } + + setup({ explicit_done: true }); + window.addEventListener("load", function() { + + for (tag in MathMLFragments) { + if (!FragmentHelper.isValidChildOfMrow(tag) || tag === "mtd") + continue; + + document.body.insertAdjacentHTML("beforeend", `<div style='display: none; background: pink;'>${tag}: <div></div><div></div><div></div></div>`); + + let container = document.body.lastElementChild; + let referenceDiv = container.children[0]; + const maxChild = 10; + const epsilon = 1; + + // Create the references for different number of children as well + // as the element that will get the children added / removed. + for (let i = 0; i <= maxChild; i++) + referenceDiv.append(generateMathForTag(tag, i)); + let fullReferenceMath = referenceDiv.lastElementChild; + let fullReferenceTag = fullReferenceMath.firstElementChild; + + let removeChildrenMath = generateMathForTag(tag, maxChild); + container.children[1].append(removeChildrenMath); + let removeChildrenTag = removeChildrenMath.firstElementChild; + + let appendChildrenMath = generateMathForTag(tag, 0); + container.children[2].append(appendChildrenMath); + let appendChildrenTag = appendChildrenMath.firstElementChild; + + // Make content visible after the DOM is ready so that the layout + // only happens now. + container.style.display = "block"; + + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_true(MathMLFeatureDetection[`has_${tag}`]()); + + for (let i = 0; i < maxChild; i++) { + // append and remove children. + appendChildrenTag.append(fullReferenceTag.children[i].cloneNode(true)); + removeChildrenTag.removeChild(removeChildrenTag.lastElementChild); + + // force layout so we're sure what we're testing against + container.getBoundingClientRect(); + + let appendCount = appendChildrenTag.children.length; + let removeCount = removeChildrenTag.children.length; + if (tag == "mspace") { + compareSize(appendChildrenTag, referenceDiv.children[appendCount].firstElementChild, epsilon); + childrenHaveEmptyBoundingClientRects(appendChildrenTag); + childrenHaveEmptyBoundingClientRects(referenceDiv.children[appendCount].firstElementChild); + childrenHaveEmptyBoundingClientRects(removeChildrenTag); + childrenHaveEmptyBoundingClientRects(referenceDiv.children[removeCount].firstElementChild); + } else { + compareLayout(appendChildrenTag, referenceDiv.children[appendCount].firstElementChild, epsilon, `appending ${appendCount}-th child`); + compareLayout(removeChildrenTag, referenceDiv.children[removeCount].firstElementChild, epsilon, `removing ${appendCount + 1}-th child`); + } + } + + // Hide back the div after successful testing. + container.style.display = "none"; + + }, `Appending and removing children to ${tag}`); + } + + done(); + }); +</script> +</head> +<body> + <div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1-ref.html new file mode 100644 index 0000000000..86952567c7 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>href click (reference)</title> +</head> +<body> + + <p>This test passes if you see a green square.</p> + + <div style="width: 150px; height: 150px; background: green"> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1.html new file mode 100644 index 0000000000..c3e605cb72 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"/> +<title>href click</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<link rel="match" href="href-click-1-ref.html"/> +<meta name="assert" content="Verify that a click on a link moves to the target."> +<script type="text/javascript"> + function test() + { + var event = new MouseEvent('click', {bubbles: true, cancelable: true}); + document.getElementById('link').dispatchEvent(event); + document.documentElement.className = ""; + } +</script> +</head> +<body onload="test()"> + + <p>This test passes if you see a green square.</p> + + <div style="width: 150px; height: 150px; overflow: hidden"> + <math> + <mrow id="link" href="#target"> + <mspace id="space" width="150px" height="150px" style="background: red"/> + </mrow> + </math> + <div style="height: 500px;"></div> + <math id="target"> + <mspace width="150px" height="150px" style="background: green"/> + </math> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2-ref.html new file mode 100644 index 0000000000..86952567c7 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>href click (reference)</title> +</head> +<body> + + <p>This test passes if you see a green square.</p> + + <div style="width: 150px; height: 150px; background: green"> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2.html new file mode 100644 index 0000000000..8ffec61cc7 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="utf-8"/> +<title>href click</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<link rel="match" href="href-click-2-ref.html"/> +<meta name="assert" content="Verify that a click on an element bubbles to an ancestor link."> +<script type="text/javascript"> + function test() + { + var event = new MouseEvent('click', {bubbles: true, cancelable: true}); + document.getElementById('space').dispatchEvent(event); + document.documentElement.className = ""; + } +</script> +</head> +<body onload="test()"> + + <p>This test passes if you see a green square.</p> + + <div style="width: 150px; height: 150px; overflow: hidden"> + <math> + <mrow href="#target"> + <mrow> + <mrow> + <mspace id="space" width="150px" height="150px" style="background: red"/> + </mrow> + </mrow> + </mrow> + </math> + <div style="height: 500px;"></div> + <math id="target"> + <mspace width="150px" height="150px" style="background: green"/> + </math> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-3.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-3.html new file mode 100644 index 0000000000..f6f1ada6d7 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-3.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>href click</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +</head> +<body> + <p>To test manually, click the blue rectangle.</p> + <p> + <math> + <mspace width="50px" height="10px" style="background: gray"></mspace> + <mspace id="target" href="javascript:handler()" width="50px" height="10px" style="background: blue"></mspace> + <mspace width="50px" height="10px" style="background: gray"></mspace> + </math> + </p> + <a id="badTarget" href="javascript:badHandler()">DON'T CLICK ME</a> + <script> + var t = async_test("Click element with href"); + function handler() { t.done(); } + function badHandler() { + t.step(() => { assert_unreached("Bad handler executed"); }); + t.done(); + } + test_driver.click(document.getElementById("target")).then(() => { + return test_driver.click(document.getElementById("badTarget")); + }).catch(() => { + t.step(() => { assert_unreached("Click failed"); }); + t.done(); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html new file mode 100644 index 0000000000..028428cd75 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html @@ -0,0 +1,111 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>MathML 'HTMLOrForeignElement` Mixin Tests</title> + <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/> + <style> + mi { + background-color: red; + } + :focus { + background-color: rgb(0, 255, 0); + } + </style> + <meta + name="assert" + content="MathMLElements incorporate a functional HTMLOrForeignElement interface" + /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body tabindex="-1"> + <span tabindex="-1" + >This tests the presence and functionality of features of + `HTMLOrForeignElement` (currently `HTMLOrSVGElement`)</span + > + <math tabindex="-1"> + <mi>E</mi> + </math> + </body> + <script> + // spot check the functionality of several interfaces + let el = document.querySelector("mi"); + let mathEl = document.querySelector("math"); + + // this really belongs in + // https://github.com/web-platform-tests/wpt/blob/master/html/dom/elements/global-attributes/dataset.html + // it is here tentatively + test(function() { + var mathml = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + assert_true(mathml.dataset instanceof DOMStringMap); + }, "MathML elements should have a .dataset"); + + // exercise some basic tests on .dataset + test(function() { + assert_equals( + Object.keys(el.dataset).toString(), + "", + "The .dataset property should be present" + ); + + el.setAttribute("data-one", "x"); + el.setAttribute("data-two", "y"); + + assert_equals( + el.dataset.one, + "x", + '.one should be "x" after setting the data-one attribute' + ); + assert_equals( + el.dataset.two, + "y", + '.one should be "y" after setting the data-two attribute' + ); + + el.dataset.one = "o"; + assert_equals( + el.getAttribute("data-one"), + "o", + 'the data-one attribute should reflect a change to dataset.one and contain "o"' + ); + }, "The dataset property should be present and be functional."); + + test(function() { + assert_equals(mathEl.tabIndex, -1); + }, "MathML elements should have a tabIndex property"); + + promise_test(function() { + function focus() { + mathEl.focus(); + return Promise.resolve(); + } + + return focus().then(() => { + assert_equals( + getComputedStyle(mathEl).backgroundColor, + "rgb(0, 255, 0)", + "MathML elements with tabindex=-1 should be programmatically focusable and apply :focus" + ); + }); + }, "MathML elements should work with focus predictably"); + + promise_test(function() { + function blur() { + mathEl.blur(); + return Promise.resolve(); + } + + return blur().then(() => { + assert_equals( + getComputedStyle(mathEl).backgroundColor, + "rgba(0, 0, 0, 0)", + "MathML elements with tabindex=-1 be programmatically blur() able" + ); + }); + }, "MathML elements should work with blur predictably"); + </script> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1-ref.html new file mode 100644 index 0000000000..4987754967 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML inside foreignObject (reference)</title> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + <div> + <div style="position: absolute; width: 200px; height: 200px; background: green"></div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1.html new file mode 100644 index 0000000000..bc725e9d19 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML inside foreignObject</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg"> +<link rel="match" href="integration-point-1-ref.html"/> +<meta name="assert" content="Verify that MathML can be used inside a foreignObject element."> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + <div> + <div style="position: absolute; width: 200px; height: 200px; background: red"></div> + <div style="position: absolute;"> + <svg width="200px" height="200px"> + <rect width="200px" height="100px" fill="red"/> + <foreignObject width="200px" height="200px" + requiredExtensions="http://www.w3.org/1998/Math/MathML"> + <div style="width: 200px; height: 200px; background: green"></div> + </foreignObject> + </svg> + </div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2-ref.html new file mode 100644 index 0000000000..33c4b7e910 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML as a phrasing content (reference)</title> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + + <div> + <div style="position: absolute; background: green; width: 300px; height: 300px;"></div> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2.html new file mode 100644 index 0000000000..7e6c11a5ac --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML as a phrasing content</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg"> +<link rel="match" href="integration-point-2-ref.html"/> +<meta name="assert" content="Verify that MathML can be used at positions where phrasing content is accepted."> +<style type="text/css"> + span, math { font-family: monospace; font-size: 10px; } + div { + color: green; + } + span.redsquare { + display: inline-block; + width: 10px; + height: 10px; + background: red; + } + mspace { + background: green; + } +</style> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + + <div> + + <div style="position: absolute; background: green; width: 300px; height: 300px;"> + <p><span class="redsquare"></span></p> + <h1><span class="redsquare"></span></h1> + <h2><span class="redsquare"></span></h2> + <ul> + <li><span class="redsquare"></span></li> + </ul> + <ol> + <li><span class="redsquare"></span></li> + </ol> + <table><tr><td><span class="redsquare"></span></td></tr></table> + <a href="#id"><span class="redsquare"></span></a> + <em><span class="redsquare"></span></em> + <strong><span class="redsquare"></span></strong> + <small><span class="redsquare"></span></small> + <span><span class="redsquare"></span></span> + <u><span class="redsquare"></span></u> + <q><span class="redsquare"></span></q> + </div> + <div style="position: absolute; width: 400px;"> + <p><math><mspace width="10px" height="10px"/></math></p> + <h1><math><mspace width="10px" height="10px"/></math></h1> + <h2><math><mspace width="10px" height="10px"/></math></h2> + <ul> + <li><math><mspace width="10px" height="10px"/></math></li> + </ul> + <ol> + <li><math><mspace width="10px" height="10px"/></math></li> + </ol> + <table><tr><td><math><mspace width="10px" height="10px"/></math></td></tr></table> + <a href="#id"><math><mspace width="10px" height="10px"/></math></a> + <em><math><mspace width="10px" height="10px"/></math></em> + <strong><math><mspace width="10px" height="10px"/></math></strong> + <small><math><mspace width="10px" height="10px"/></math></small> + <span><math><mspace width="10px" height="10px"/></math></span> + <u><math><mspace width="10px" height="10px"/></math></u> + <q><math><mspace width="10px" height="10px"/></math></q> + </div> + + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3-ref.html new file mode 100644 index 0000000000..8362ed28e3 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>phrasing content inside mtext (reference)</title> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + + <div> + + <div style="position: absolute; background: green; width: 200px; height: 200px;"></div> + + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3.html new file mode 100644 index 0000000000..4c6f89ee93 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>phrasing content inside mtext</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg"> +<link rel="match" href="integration-point-3-ref.html"/> +<meta name="assert" content="Verify that <mtext> can contain phrasing content"> +<style type="text/css"> + div { + color: green; + } + span, math, mtext { font-family: monospace; font-size: 10px; } + span.redsquare, span.greensquare { + display: inline-block; + width: 10px; + height: 10px; + } + span.redsquare { + background: red; + } + span.greensquare { + background: green; + } + mspace { + background: green; + } +</style> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + + <div> + + <div style="position: absolute; background: green; width: 200px; height: 200px;"> + <span><span><span><span class="redsquare"></span></span></span></span> + <span><span><u><span class="redsquare"></span></u></span></span> + <span><span><a href="#id"><span class="redsquare"></span></a></span></span> + <span><span><del><span class="redsquare"></span></del></span></span> + <span><span><em><span class="redsquare"></span></em></span></span> + <span><span><strong><span class="redsquare"></span></strong></span></span> + <span><span><q><span class="redsquare"></span></q></span></span> + <span><span><small><span class="redsquare"></span></small></span></span> + <span><span><var><span class="redsquare"></span></var></span></span> + <span><span><samp><span class="redsquare"></span></samp></span></span> + </div> + <div style="position: absolute; width: 200px;"> + <math><mtext><span><span class="greensquare"></span></span></mtext></math> + <math><mtext><u><span class="greensquare"></span></u></mtext></math> + <math><mtext><a href="#id"><span class="greensquare"></span></a></mtext></math> + <math><mtext><del><span class="greensquare"></span></del></mtext></math> + <math><mtext><em><span class="greensquare"></span></em></mtext></math> + <math><mtext><strong><span class="greensquare"></span></strong></mtext></math> + <math><mtext><q><span class="greensquare"></span></q></mtext></math> + <math><mtext><small><span class="greensquare"></span></small></mtext></math> + <math><mtext><var><span class="greensquare"></span></var></mtext></math> + <math><mtext><samp><span class="greensquare"></span></samp></mtext></math> + </div> + + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-4.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-4.html new file mode 100644 index 0000000000..c3bc95d1ef --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-4.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML inside foreignObject</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg"> +<meta name="assert" content="Verify that MathML can be used inside a foreignObject element."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("DOMContentLoaded", function() { + var scale = 2; + var epsilon = 1; + var mfrac = document.getElementById("mfrac"); + var num = mfrac.firstElementChild.getBoundingClientRect(); + var denom = mfrac.lastElementChild.getBoundingClientRect(); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + // The values of width and height are inverted (because of the + // rotation) and multiplied by the scale factor. + assert_approx_equals(num.height, 30 * scale, epsilon, "numerator width"); + assert_approx_equals(num.width, 40 * scale, epsilon, "numerator height"); + assert_approx_equals(denom.height, 50 * scale, epsilon, "numerator width"); + assert_approx_equals(denom.width, 60 * scale, epsilon, "numerator height"); + }, "mspace layout in SVG foreignObject"); + test(function() { + // The horizontal/vertical metrics are inverted (because of the + // rotation) and multiplied by the scale factor. + assert_true(MathMLFeatureDetection.has_mfrac()); + assert_greater_than_equal(num.right - denom.left, + (40 + 60) * scale, + "numerator is on the right of denominator"); + assert_approx_equals((num.top + num.bottom) / 2, + (denom.top + denom.bottom) / 2, + epsilon, "numerator and denominator are vertically aligned"); + }, "mfrac layout in SVG foreignObject"); + done(); + }); +</script> +</head> +<body> + <div id="log"></div> + <svg width="400px" height="400px"> + <g transform="rotate(90, 200, 200) scale(2)"> + <foreignObject width="400px" height="400px" + requiredExtensions="http://www.w3.org/1998/Math/MathML"> + <math> + <mfrac id="mfrac"> + <mspace width="30px" height="40px" style="background: cyan"></mspace> + <mspace width="50px" height="60px" style="background: yellow"></mspace> + </mfrac> + </math> + </foreignObject> + </g> + </svg> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-5.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-5.html new file mode 100644 index 0000000000..b63ab7a63c --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-5.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML sibling of SVG with foreignObject[overflow=visible]</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=989920"> +<meta name="assert" content="Verify that an SVG containing a foreignObject with visible overflow does not affect layout of MathML siblings."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/mathml/support/feature-detection.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("DOMContentLoaded", function() { + var scale = 2; + var epsilon = 1; + var mfrac = document.getElementById("mfrac"); + var num = mfrac.firstElementChild.getBoundingClientRect(); + var denom = mfrac.lastElementChild.getBoundingClientRect(); + test(function() { + assert_true(MathMLFeatureDetection.has_mspace()); + assert_approx_equals(num.width, 30, epsilon, "numerator width"); + assert_approx_equals(num.height, 40, epsilon, "numerator height"); + assert_approx_equals(denom.width, 50, epsilon, "denonimator width"); + assert_approx_equals(denom.height, 60, epsilon, "denonimator height"); + }, "mspace layout in sibling of SVG foreignObject[overflow=visible]"); + test(function() { + assert_true(MathMLFeatureDetection.has_mfrac()); + assert_greater_than_equal(denom.bottom - num.top, + (40 + 60), + "numerator above denominator"); + assert_approx_equals((num.left + num.right) / 2, + (denom.left + denom.right) / 2, + epsilon, "numerator and denominator are horizontally aligned"); + }, "mfrac layout in sibling of SVG with foreignObject[overflow=visible]"); + done(); + }); +</script> +</head> +<body> + <div id="log"></div> + <math> + <mfrac id="mfrac"> + <mspace width="30px" height="40px" style="background: cyan"></mspace> + <mspace width="50px" height="60px" style="background: yellow"></mspace> + </mfrac> + </math> + <svg width="200px" height="200px" style="background: lightblue"> + <foreignObject width="200px" height="200px" + overflow="visible"> + <div xmlns="http://www.w3.org/1999/xhtml"> + This is a foreignObject + </div> + </foreignObject> + </svg> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/math-global-event-handlers.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/math-global-event-handlers.tentative.html new file mode 100644 index 0000000000..b924eefa7d --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/math-global-event-handlers.tentative.html @@ -0,0 +1,155 @@ +<!DOCTYPE html> +<title>MathMLElement GlobalEventHandlers</title> +<link rel="author" title="Brian Kardell" href="mailto:bkardell@igalia.com" /> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#event-handler-idl-attributes"/> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#event-handler-content-attributes"/> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/WebIDLParser.js"></script> + +<script> + "use strict"; + + // The prefixed animation events are special; their event types are + // camel-case. + const prefixedAnimationAttributeToEventType = new Map([ + ["webkitanimationend", "webkitAnimationEnd"], + ["webkitanimationiteration", "webkitAnimationIteration"], + ["webkitanimationstart", "webkitAnimationStart"], + ["webkittransitionend", "webkitTransitionEnd"], + ]); + + // basic pattern lifted from /html/webappapis/scripting/events/event-handler-all-global-events.html + promise_setup(async function() { + const res = await fetch("/interfaces/html.idl"); + const htmlIDL = await res.text(); + // Parsing the whole IDL file is slow, so use a small regexp to extract only + // the part that is relevant for this test. + const parsedHTMLIDL = WebIDL2.parse(htmlIDL. + match(/^interface mixin GlobalEventHandlers {[^{}]*};$/m)[0]); + const globalEventHandlers = parsedHTMLIDL.find( + idl => idl.name === "GlobalEventHandlers" + ); + + // onerror is too special + const names = globalEventHandlers.members + .map(member => member.name) + .filter(name => name !== "onerror"); + + for (const name of names) { + const withoutOn = name.substring(2); + + promise_test(async () => { + const location = MathMLElement.prototype; + assert_true( + location.hasOwnProperty(name), + `${location.constructor.name} has an own property named "${name}"` + ); + + assert_false( + name in Element.prototype, + `Element.prototype must not contain a "${name}" property` + ); + }, `${name}: must be on the appropriate locations for GlobalEventHandlers`); + + promise_test(async () => { + const location = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + + assert_equals( + location[name], + null, + `The default value of the property is null for a ${ + location.constructor.name + } instance` + ); + }, `${name}: the default value must be null`); + + promise_test(async () => { + const div = document.createElement("div"); + div.insertAdjacentHTML("beforeend", `<math ${name}="window.${name}Happened1 = true;"></math>`); + const compiledHandler = div.firstElementChild[name]; + assert_equals( + typeof compiledHandler, + "function", + `The ${name} property must be a function` + ); + compiledHandler(); + assert_true( + window[`${name}Happened1`], + "Calling the handler must run the code" + ); + }, `${name}: the content attribute must be compiled into a function as the corresponding property`); + + promise_test(async () => { + const el = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + assert_equals(el[name], null, `The ${name} property must be null (no attribute)`); + + el.setAttribute(name, `window.${name}Happened2 = true;`); + const compiledHandler = el[name]; + assert_equals( + typeof compiledHandler, + "function", + `The ${name} property must be a function (set attribute)` + ); + compiledHandler(); + assert_true( + window[`${name}Happened2`], + "Calling the handler must run the code (set attribute)" + ); + + window[`${name}Happened2`] = false; + const clonedEl = el.cloneNode(true); + const clonedCompiledHandler = clonedEl[name]; + assert_equals( + typeof clonedCompiledHandler, + "function", + `The ${name} property must be a function (clone node)` + ); + clonedCompiledHandler(); + assert_true( + window[`${name}Happened2`], + "Calling the handler must run the code (clone node)" + ); + + el.setAttribute(name, `window.${name}Happened3 = true;`); + const newCompiledHandler = el[name]; + assert_equals( + typeof newCompiledHandler, + "function", + `The ${name} property must be a function (modify attribute)` + ); + newCompiledHandler(); + assert_true( + window[`${name}Happened3`], + "Calling the handler must run the code (modify attribute)" + ); + + el.removeAttribute(name); + assert_equals(el[name], null, `The ${name} property must be null (remove attribute)`); + }, `${name}: dynamic changes on the attribute`); + + promise_test(async () => { + const element = document.createElementNS( + "http://www.w3.org/1998/Math/MathML", + "math" + ); + let target = undefined; + element[name] = (e) => { target = e.currentTarget; } + let eventType = withoutOn; + if (prefixedAnimationAttributeToEventType.has(eventType)) { + eventType = prefixedAnimationAttributeToEventType.get(eventType); + } + element.dispatchEvent(new Event(eventType)); + assert_equals(target, element, "The event must be fired at the <math> element"); + }, `${name}: dispatching an Event at a <math> element must trigger element.${name}`); + } + }); +</script> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2-ref.html new file mode 100644 index 0000000000..dcc5b2b7d3 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>SVG requiredExtensions (reference)</title> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + <svg width="200px" height="200px"> + <rect width="200px" height="200px" fill="green"/> + </svg> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2.html new file mode 100644 index 0000000000..738f125507 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>SVG requiredExtensions</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg"> +<link rel="match" href="required-extensions-2-ref.html"/> +<meta name="assert" content="Verify that a foreignObject with MathML used as a requiredExtensions value is selected for display in a SVG switch element."> +</head> +<body> + <p>Test passes if there is a green square and no red.</p> + <svg width="200px" height="200px"> + <rect width="200px" height="100px" fill="red"/> + <switch> + <foreignObject width="200px" height="200px" + requiredExtensions="http://www.w3.org/1998/Math/MathML"> + <div style="width: 200px; height: 200px; background: green"></div> + </foreignObject> + <rect y="100px" width="200px" height="100px" fill="red"/> + </switch> + </svg> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-001.html b/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-001.html new file mode 100644 index 0000000000..3aaf0d955a --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-001.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>MathML tabIndex attribute</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element"> +<meta name="assert" content="Verify default values for the tabIndex attribute"> + +<script src="/mathml/support/mathml-fragments.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> + <div id="log"></div> + <math> + </math> + <script> + const htmlLinkableElements = + new Set([ + 'mi', 'mo', 'mn', 'ms', 'mtext', 'mrow' + ]); + + Object.keys(MathMLFragments).forEach(elName => { + const mathEl = document.querySelector('math'); + + mathEl.innerHTML = ` + <${elName} id="el" onfocus="alert('fail')"></${elName}> + <${elName} id="el-link" href="javascript:alert('fail')" onfocus="alert('fail')"></${elName}> + `; + + const el = mathEl.querySelector('#el'); + const elLink = mathEl.querySelector('#el-link'); + + const expectedDefault = (htmlLinkableElements.has(elName)) ? 0 : -1; + + test(() => { + assert_equals(el.tabIndex, expectedDefault, "no attribute"); + el.setAttribute("tabindex", "invalid"); + assert_equals(el.getAttribute("tabindex"), "invalid"); + assert_equals(el.tabIndex, expectedDefault, "invalid"); + el.setAttribute("tabindex", "9999999999"); + assert_equals(el.getAttribute("tabindex"), "9999999999"); + assert_equals(el.tabIndex, expectedDefault, "too large integer"); + }, `default and invalid values for ${elName} without href`); + test(() => { + assert_equals(elLink.tabIndex, expectedDefault, "no attribute"); + elLink.setAttribute("tabindex", "invalid"); + assert_equals(elLink.getAttribute("tabindex"), "invalid"); + assert_equals(elLink.tabIndex, expectedDefault, "invalid"); + elLink.setAttribute("tabindex", "9999999999"); + assert_equals(elLink.getAttribute("tabindex"), "9999999999"); + assert_equals(elLink.tabIndex, expectedDefault, "too large integer"); + }, `default and invalid values for ${elName} with href`); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-002.html b/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-002.html new file mode 100644 index 0000000000..d2144e3d01 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-002.html @@ -0,0 +1,71 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<title>MathML tabindex attribute</title> +<meta name="timeout" content="long"> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<meta assert="flag" content="interact"> +<meta assert="assert" content="Check the sequential focus navigation order for MathML"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<div id="log"></div> +<a href="#link">tabindex(html,href)</a> +<math> + <mtext id="text1">tabindex(omitted)</mtext> + <mtext id="text2" tabindex="">tabindex(empty)</mtext> + <mtext id="text3" tabindex="a">tabindex(a)</mtext> + <mtext id="text4" tabindex="-1">tabindex(-1)</mtext> + <mtext id="text5" tabindex="0">tabindex(0)</mtext> + <mtext id="text6" href="#link">tabindex(href)</mtext> + <mtext id="text7" tabindex="3">tabindex(3)</mtext> + <mtext id="text8" tabindex="2">tabindex(2)</mtext> + <mtext id="text9" tabindex="2">tabindex(2)</mtext> + <mtext id="text10" tabindex="2">tabindex(2)</mtext> + <mtext id="text11" tabindex="1">tabindex(1)</mtext> +</math> +<script> + +var i = 0, + expectation = ["text11", "text8", "text9", "text10", "text7", "text5"], + results = [], + t = async_test("Elements with different tabindex must be focused sequentially when pressing 'Tab' keys"); + +setup(function () { + document.body.focus(); +}); + +document.querySelector("a").addEventListener("focus", function (evt) { + // Links are tab-navigable on that platform. + expectation.push("text6"); + // TAB = '\ue004' + test_driver.send_keys(document.body, "\ue004"); +}, true); + +document.querySelector("math").addEventListener("focus", function (evt) { + results.push(evt.target.id); + i++; + if (i >= expectation.length) { + t.step(function () { + assert_array_equals(results, expectation); + }); + t.done(); + } else { + t.step(function () { + // TAB = '\ue004' + test_driver.send_keys(document.body, "\ue004"); + }); + } +}, true); + +document.addEventListener("keydown", function (evt) { + t.step(function () { + assert_equals(evt.keyCode, 9, "Please press 'Tab' key."); + }); +}, true); + +t.step(function () { + // TAB = '\ue004' + test_driver.send_keys(document.body, "\ue004"); +}); +</script> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-1.html new file mode 100644 index 0000000000..6b3ab07f1a --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-1.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Unique Identifier (iframe)</title> +</head> +<body> + + <div style="width: 100px; height: 500px;"> + <math><mtext style="background: red; color: white;">FAIL</mtext></math> + </div> + <div style="width: 100px; height: 500px;"> + <math><mtext style="background: green; color: white;" + id="PASS">PASS</mtext></math> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-2.html new file mode 100644 index 0000000000..ade0110a27 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Unique Identifier (iframe reference)</title> +</head> +<body> + + <div style="width: 100px; height: 500px;"> + <math><mtext style="background: green; color: white;" + id="PASS" class="pass">PASS</mtext></math> + </div> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-ref.html new file mode 100644 index 0000000000..a219b2c870 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Unique identifier (reference)</title> +</head> +<body> + + <p>Test passes if you see the text "PASS".</p> + + <iframe width="100" height="100" frameborder="0" scrolling="no" + marginheight="0" marginwidth="0" + src="unique-identifier-1-iframe-2.html#PASS"></iframe> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1.html new file mode 100644 index 0000000000..f5de2757c3 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Unique identifier</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="match" href="unique-identifier-1-ref.html"/> +<meta name="assert" content="Verify that the id on a MathML element can be used as a fragment identifier in order to force initial scrolling."> +</head> +<body> + + <p>Test passes if you see the text "PASS".</p> + + <iframe width="100" height="100" frameborder="0" scrolling="no" + marginheight="0" marginwidth="0" + src="unique-identifier-1-iframe-1.html#PASS"></iframe> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-2.html new file mode 100644 index 0000000000..d4e69df324 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-2.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Unique Identifier</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"> +<meta name="assert" content="Verify whether the getElementById() works for MathML elements."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + setup({ explicit_done: true }); + window.addEventListener("DOMContentLoaded", function() { + var mtext = document.getElementById("MTEXT"); + test(function() { + assert_equals(mtext, document.body.lastElementChild.lastElementChild); + }, "getElementById()"); + done(); + }); +</script> +</head> +<body> + <div id="log"></div> + <math> + <mtext id="MTEXT_"></mtext> + <mtext id="MTEX"></mtext> + <mtext id="MTEXT"></mtext> + </math> +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3-ref.html new file mode 100644 index 0000000000..ef056e0082 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Unique identifier 3 (reference)</title> +</head> +<body> + + <p>Test passes if you see the text "PASS".</p> + <math> + <mtext style="background: green; color: white;">PASS</mtext> + </math> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3.html new file mode 100644 index 0000000000..306ce41e25 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>Unique Identifier</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements"> +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling"> +<link rel="match" href="unique-identifier-3-ref.html"/> +<meta name="assert" content="Verify that the id attribute affects CSS selectors."> +<style> + #fail { display: none; } + #pass { background: green; } +</style> +</head> +<body> + + <p>Test passes if you see the text "PASS".</p> + <math> + <mtext id="fail" style="background: red; color: white;">FAIL</mtext> + <mtext id="pass" style="color: white;">PASS</mtext> + </math> + +</body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/text-and-math/basic-mathematical-alphanumeric-symbols-with-default-font.html b/testing/web-platform/tests/mathml/relations/text-and-math/basic-mathematical-alphanumeric-symbols-with-default-font.html new file mode 100644 index 0000000000..c1e8d409b9 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/text-and-math/basic-mathematical-alphanumeric-symbols-with-default-font.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Basic mathematical alphanumeric symbols with default font</title> + <meta name="assert" content="Verify whether the default font contains italic/bold/bold-italic characters from the Mathematical Alphanumeric Symbols block."> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <style> + span[data-name] { + font-size: 100px; + background: lightblue; + display: inline-block; + } + </style> + </head> + <body> + <div id="log"></div> + <p><span id="frakturL" data-name="U+1D529 MATHEMATICAL FRAKTUR SMALL L">𝔩</span></p> + <p><span id="emSpace" data-name="U+2003 EM SPACE"> </span></p> + <p><span data-test="Bold" data-name="U+1D416 MATHEMATICAL BOLD CAPITAL W">𝐖</span></p> + <p><span data-test="Italic" data-name="U+1D44A MATHEMATICAL ITALIC CAPITAL W">𝑊</span></p> + <p><span data-test="Bold-italic" data-name="U+1D47E MATHEMATICAL BOLD ITALIC CAPITAL">𝑾</span></p> + <script> + const frakturLWidth = document.getElementById("frakturL").getBoundingClientRect().width; + const emSpaceWidth = document.getElementById("emSpace").getBoundingClientRect().width; + Array.from(document.querySelectorAll('span[data-test]')).forEach(span => { + test(function() { + let spanWidth = span.getBoundingClientRect().width; + // This test expects the default font to provide a fraktur l than is much thiner than a bold/italic/bold-italic W. + // If the font lacks bold/italic/bold-italic W then a fortiori it is likely that its lacks fraktur l, so browsers + // will display "Tofu characters" for all of them (e.g. gray boxes or boxes containing the Unicode code points) + // with very similar widths, so the test is likely to fail. + assert_greater_than(spanWidth, frakturLWidth + emSpaceWidth / 4, `Width of '${span.dataset.name}' is much larger than '${frakturL.dataset.name}'`); + }, `${span.dataset.test} mathematical alphanumeric symbol with the default font`); + }); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1-ref.html b/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1-ref.html new file mode 100644 index 0000000000..3f7f764045 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1-ref.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<title>Open Font Format: USE_TYPO_METRICS (reference)</title> +<style> + #green { + position: absolute; + background: green; + left: 10px; + width: 230px; + height: 230px; + } +</style> +<body> + <p>Test passes if there is a green square and no red.</p> + + <div> + <div id="green"></div> + </div> +</body> diff --git a/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1.html b/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1.html new file mode 100644 index 0000000000..1af8fdfde1 --- /dev/null +++ b/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<title>Open Font Format: USE_TYPO_METRICS</title> +<link rel="help" href="https://w3c.github.io/mathml-core/#text-layout"/> +<link rel="match" href="use-typo-metrics-1-ref.html"/> +<meta name="assert" content="Verify that the USE_TYPO_METRICS flag from the OS/2 table is taken into account to calculate line height."> +<style> + @font-face { + font-family: TestFont; + src: url("/fonts/math/lineheight5000-typolineheight2300.woff"); + } + .green { + position: absolute; + background: green; + width: 115px; + } + .red { + position: absolute; + background: red; + width: 115px; + } + .forceHeight { + height: 230px; + } + .leftSide { + left: 10px; + } + .rightSide { + left: 125px; + } + span { + /* em=1000, lineHeight=5000, typoLineHeight=2300 and font-size=100px + implies typoLineHeightPx = 230px < 500px = lineHeightPx */ + font-family: TestFont; + font-size: 100px; + color: transparent; + } +</style> +<body> + <p>Test passes if there is a green square and no red.</p> + + <div> + <!-- Left side verifies that typoLineHeightPx <= 230px --> + <div class="leftSide red"><span>O</span></div> + <div class="leftSide green forceHeight"></div> + + <!-- Right side verifies that typoLineHeightPx => 230px --> + <div class="rightSide red forceHeight"></div> + <div class="rightSide green"><span>O</span></div> + </div> +</body> diff --git a/testing/web-platform/tests/mathml/support/attribute-values.js b/testing/web-platform/tests/mathml/support/attribute-values.js new file mode 100644 index 0000000000..8408124f49 --- /dev/null +++ b/testing/web-platform/tests/mathml/support/attribute-values.js @@ -0,0 +1,31 @@ +AttributeValueTransforms = { + lowercase: function(value) { return value.toLowerCase(); }, + uppercase: function(value) { return value.toUpperCase(); }, + alternate_case: function(value) { + var transformedValue = ""; + for (var i = 0; i < value.length; i++) { + transformedValue += i % 2 ? + value.charAt(i).toLowerCase() : + value.charAt(i).toUpperCase(); + } + return transformedValue; + }, + // TODO: Should we perform this transform too? + // https://github.com/mathml-refresh/mathml/issues/122 + // add_leading_and_trimming_whitespace: function(value) { + // var space = "\0020\0009\000A\000D"; + // return `${space}${space}${value}${space}${space}`; + // }, +}; + +function TransformAttributeValues(transform, attributeNames) { + if (typeof attributeNames === "string") + attributeNames = [attributeNames]; + attributeNames.forEach(name => { + Array.from(document.querySelectorAll(`[${name}]`)).forEach(element => { + var value = element.getAttribute(name); + var transformedValue = AttributeValueTransforms[transform](value); + element.setAttribute(name, transformedValue); + }); + }); +} diff --git a/testing/web-platform/tests/mathml/support/box-comparison.js b/testing/web-platform/tests/mathml/support/box-comparison.js new file mode 100644 index 0000000000..b30ad279df --- /dev/null +++ b/testing/web-platform/tests/mathml/support/box-comparison.js @@ -0,0 +1,107 @@ +function spaceBetween(childBox, parentBox) { + return { + left: childBox.left - parentBox.left, + right: parentBox.right - childBox.right, + top: childBox.top - parentBox.top, + bottom: parentBox.bottom - childBox.bottom + }; +} + +function measureSpaceAround(id) { + var mrow = document.getElementById(id); + var mrowBox = mrow.getBoundingClientRect(); + var parentBox = mrow.parentNode.getBoundingClientRect(); + var childBox = mrow.firstElementChild.getBoundingClientRect(); + return spaceBetween(childBox, parentBox); +} + +function compareSpaceWithAndWithoutStyle(tag, style, parentStyle, direction) { + if (!FragmentHelper.isValidChildOfMrow(tag) || + FragmentHelper.isEmpty(tag)) + throw `Invalid argument: ${tag}`; + + if (!direction) + direction = "ltr"; + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ +<div style="display: inline-block"><math><mrow dir="${direction}">${MathMLFragments[tag]}</mrow></math></div>\ +<div style="display: inline-block"><math><mrow dir="${direction}">${MathMLFragments[tag]}</mrow></math></div>\ +</div>`); + var div = document.body.lastElementChild; + + var styleDiv = div.firstElementChild; + var styleMath = styleDiv.firstElementChild; + var styleParent = styleMath.firstElementChild; + if (parentStyle) + styleParent.setAttribute("style", parentStyle); + var styleElement = FragmentHelper.element(styleMath); + styleElement.setAttribute("style", style); + var styleChild = FragmentHelper.forceNonEmptyElement(styleElement); + var styleMathBox = styleMath.getBoundingClientRect(); + var styleElementBox = styleElement.getBoundingClientRect(); + var styleChildBox = styleChild.getBoundingClientRect(); + var styleSpace = spaceBetween(styleChildBox, styleMathBox); + + var noStyleDiv = div.lastElementChild; + var noStyleMath = noStyleDiv.firstElementChild; + var noStyleElement = FragmentHelper.element(noStyleMath); + var noStyleChild = FragmentHelper.forceNonEmptyElement(noStyleElement); + var noStyleMathBox = noStyleMath.getBoundingClientRect(); + var noStyleElementBox = noStyleElement.getBoundingClientRect(); + var noStyleChildBox = noStyleChild.getBoundingClientRect(); + var noStyleSpace = spaceBetween(noStyleChildBox, noStyleMathBox); + + var preferredWidthDelta = + styleDiv.getBoundingClientRect().width - + noStyleDiv.getBoundingClientRect().width; + + div.style = "display: none;"; // Hide the div after measurement. + + return { + preferred_width_delta: preferredWidthDelta, + left_delta: styleSpace.left - noStyleSpace.left, + right_delta: styleSpace.right - noStyleSpace.right, + top_delta: styleSpace.top - noStyleSpace.top, + bottom_delta: styleSpace.bottom - noStyleSpace.bottom, + element_width_delta: styleElementBox.width - noStyleElementBox.width, + element_height_delta: styleElementBox.height - noStyleElementBox.height + }; +} + +function compareSizeWithAndWithoutStyle(tag, style) { + if (!FragmentHelper.isValidChildOfMrow(tag)) + throw `Invalid argument: ${tag}`; + + // FIXME <mrow> only needed as workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1658135 + document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ +<div style="display: inline-block"><math><mrow>${MathMLFragments[tag]}</mrow></math></div>\ +<div style="display: inline-block"><math><mrow>${MathMLFragments[tag]}</mrow></math></div>\ +</div>`); + var div = document.body.lastElementChild; + + var styleDiv = div.firstElementChild; + var styleParent = styleDiv.firstElementChild.firstElementChild; + var styleElement = FragmentHelper.element(styleParent); + styleElement.setAttribute("style", style); + var styleParentBox = styleParent.getBoundingClientRect(); + var styleElementBox = styleElement.getBoundingClientRect(); + + var noStyleDiv = div.lastElementChild; + var noStyleParent = noStyleDiv.firstElementChild.firstElementChild; + var noStyleElement = FragmentHelper.element(noStyleParent); + var noStyleParentBox = noStyleParent.getBoundingClientRect(); + var noStyleElementBox = noStyleElement.getBoundingClientRect(); + + var preferredWidthDelta = + styleDiv.getBoundingClientRect().width - + noStyleDiv.getBoundingClientRect().width; + + div.style = "display: none;"; // Hide the div after measurement. + + return { + preferred_width_delta: preferredWidthDelta, + width_delta: styleParentBox.width - noStyleParentBox.width, + height_delta: styleParentBox.height - noStyleParentBox.height, + element_width_delta: styleElementBox.width - noStyleElementBox.width, + element_height_delta: styleElementBox.height - noStyleElementBox.height + }; +}; diff --git a/testing/web-platform/tests/mathml/support/box-navigation.js b/testing/web-platform/tests/mathml/support/box-navigation.js new file mode 100644 index 0000000000..f4897cfe99 --- /dev/null +++ b/testing/web-platform/tests/mathml/support/box-navigation.js @@ -0,0 +1,29 @@ +function IsInFlow(element) { + var style = window.getComputedStyle(element); + return style.getPropertyValue("display") !== "none" && + style.getPropertyValue("position") !== "absolute" && + style.getPropertyValue("position") !== "fixed"; +} + +function firstInFlowChild(element) { + var child = element.firstElementChild; + if (!child || IsInFlow(child)) + return child; + return nextInFlowSibling(child); +} + +function nextInFlowSibling(element) { + var child = element; + do { + child = child.nextElementSibling; + } while (child && !IsInFlow(child)); + return child; +} + +function previousInFlowSibling(element) { + var child = element; + do { + child = child.previousElementSibling; + } while (child && !IsInFlow(child)); + return child; +} diff --git a/testing/web-platform/tests/mathml/support/feature-detection-operators.js b/testing/web-platform/tests/mathml/support/feature-detection-operators.js new file mode 100644 index 0000000000..25dae40258 --- /dev/null +++ b/testing/web-platform/tests/mathml/support/feature-detection-operators.js @@ -0,0 +1,86 @@ +// This is a helper for MathML feature detection. +// It is indented to be used to prevent false negative test results. +// This adds operator-specific feature detections. + +Object.assign(MathMLFeatureDetection, { + "has_operator_lspace/rspace": async function() { + return this.has_operator_spacing(); + }, + + "has_operator_movablelimits": async function() { + return this.has_movablelimits(); + }, + + "has_operator_largeop": async function() { + if (!this.hasOwnProperty("_has_operator_largeop")) { + document.body.insertAdjacentHTML("beforeend", "\ +<math style='font: 10px HasOperatorLargeopTestFont;'\ + displaystyle='true'>\ + <mo largeop='false' stretchy='false' symmetric='false'>⫿</mo>\ + <mo largeop='true' stretchy='false' symmetric='false'>⫿</mo>\ +</math>"); + let font_face = new FontFace('HasOperatorLargeopTestFont', + 'url(/fonts/math/largeop-displayoperatorminheight5000.woff)'); + document.fonts.add(font_face); + await font_face.load(); + var math = document.body.lastElementChild; + var mo = math.getElementsByTagName("mo"); + this._has_operator_largeop = + (mo[1].getBoundingClientRect().height > + mo[0].getBoundingClientRect().height); + document.body.removeChild(math); + document.fonts.delete(font_face); + } + return this._has_operator_largeop; + }, + + "has_operator_stretchy": async function() { + if (!this.hasOwnProperty("_has_operator_stretchy")) { + document.body.insertAdjacentHTML("beforeend", "\ +<math style='font: 10px HasOperatorStretchyTestFont;'>\ + <mrow>\ + <mo stretchy='false' largeop='false' symmetric='false'>⫿</mo>\ + <mo stretchy='true' largeop='false' symmetric='false'>⫿</mo>\ + <mspace style='background: black;' width='1px' height='2em'></mspace>\ + </mrow>\ +</math>"); + let font_face = new FontFace('HasOperatorLargeopTestFont', + 'url(/fonts/math/largeop-displayoperatorminheight5000.woff)'); + document.fonts.add(font_face); + await font_face.load(); + var math = document.body.lastElementChild; + var mo = math.getElementsByTagName("mo"); + this._has_operator_stretchy = + (mo[1].getBoundingClientRect().height > + mo[0].getBoundingClientRect().height); + document.body.removeChild(math); + document.fonts.delete(font_face); + } + return this._has_operator_stretchy; + }, + + "has_operator_symmetric": async function() { + if (!this.hasOwnProperty("_has_operator_symmetric")) { + document.body.insertAdjacentHTML("beforeend", "\ +<math style='font: 10px HasOperatorSymmetricTestFont;'>\ + <mrow>\ + <mo stretchy='true' largeop='false' symmetric='false'>⫿</mo>\ + <mo stretchy='true' largeop='false' symmetric='true'>⫿</mo>\ + <mspace style='background: black;' width='1px' height='2em'></mspace>\ + </mrow>\ +</math>"); + let font_face = new FontFace('HasOperatorLargeopTestFont', + 'url(/fonts/math/largeop-displayoperatorminheight5000.woff)'); + document.fonts.add(font_face); + await font_face.load(); + var math = document.body.lastElementChild; + var mo = math.getElementsByTagName("mo"); + this._has_operator_symmetric = + (mo[1].getBoundingClientRect().height > + mo[0].getBoundingClientRect().height); + document.body.removeChild(math); + document.fonts.delete(font_face); + } + return this._has_operator_symmetric; + }, +}); diff --git a/testing/web-platform/tests/mathml/support/feature-detection.js b/testing/web-platform/tests/mathml/support/feature-detection.js new file mode 100644 index 0000000000..8b3f227d44 --- /dev/null +++ b/testing/web-platform/tests/mathml/support/feature-detection.js @@ -0,0 +1,325 @@ +// This is a helper for MathML feature detection. +// It is indented to be used to prevent false negative test results. + +var MathMLFeatureDetection = { + + "has_annotation": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_annotation-xml": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_maction": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_math": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_menclose": function() { + // Just check whether <mrow> is supported because discussion on this is + // still open ( https://github.com/mathml-refresh/mathml/issues/105 ) + // and it would have to behave at least like an mrow, even if it becomes + // an unknown element at the end. + return this.has_mrow(); + }, + + "has_merror": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mfrac": function() { + if (!this.hasOwnProperty("_has_mfrac")) { + // Use tall enough fraction to avoid side effect of min num/denum shifts. + document.body.insertAdjacentHTML("beforeend", "<math>\ +<mfrac>\ + <mspace height='50px' depth='50px'></mspace>\ + <mspace height='50px' depth='50px'></mspace>\ +</mfrac>\ +<mfrac>\ + <mspace height='60px' depth='60px'></mspace>\ + <mspace height='60px' depth='60px'></mspace>\ +</mfrac>\ +</math>"); + var math = document.body.lastElementChild; + var mfrac = math.getElementsByTagName("mfrac"); + // height/depth will add 40px per MathML, 20px if mfrac does not stack its children and none if mspace is not supported. + this._has_mfrac = + mfrac[1].getBoundingClientRect().height - + mfrac[0].getBoundingClientRect().height > 30; + document.body.removeChild(math); + } + return this._has_mfrac; + }, + + "has_mi": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mmultiscripts": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mn": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mo": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mover": function() { + // FIXME: Improve feature detection. + return this.has_munderover(); + }, + + "has_mpadded": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mphantom": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mprescripts": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mroot": function() { + // FIXME: Improve feature detection. + return this.has_msqrt(); + }, + + "has_mrow": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_ms": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mspace": function() { + // https://w3c.github.io/mathml-core/#space-mspace + if (!this.hasOwnProperty("_has_mspace")) { + document.body.insertAdjacentHTML("beforeend", "<math>\ +<mspace></mspace>\ +<mspace width='20px'></mspace>\ +</math>"); + var math = document.body.lastElementChild; + // The width attribute will add 20px per MathML and none if not supported. + this._has_mspace = + math.lastChild.getBoundingClientRect().width - + math.firstChild.getBoundingClientRect().width > 10; + document.body.removeChild(math); + } + return this._has_mspace; + }, + + "has_msqrt": function() { + if (!this.hasOwnProperty("_has_msqrt")) { + document.body.insertAdjacentHTML("beforeend", "<math>\ +<mrow style='font-size: 20px !important'>\ + <mtext>A</mtext>\ +</mrow>\ +<msqrt style='font-size: 20px !important'>\ + <mtext>A</mtext>\ +</msqrt>\ +</math>"); + var math = document.body.lastElementChild; + // The radical symbol will make msqrt wider than mrow, if the former is supported. + this._has_msqrt = + math.lastElementChild.getBoundingClientRect().width - + math.firstElementChild.getBoundingClientRect().width > 5; + document.body.removeChild(math); + } + return this._has_msqrt; + }, + + "has_mstyle": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_msub": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_msubsup": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_msup": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mtable": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mtd": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mtext": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_mtr": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_munder": function() { + // FIXME: Improve feature detection. + return this.has_munderover(); + }, + + "has_munderover": function() { + if (!this.hasOwnProperty("_has_munderover")) { + document.body.insertAdjacentHTML("beforeend", "<math>\ +<munderover>\ + <mspace width='20px'></mspace>\ + <mspace width='20px'></mspace>\ + <mspace width='20px'></mspace>\ +</munderover>\ +<munderover>\ + <mspace width='40px'></mspace>\ + <mspace width='40px'></mspace>\ + <mspace width='40px'></mspace>\ +</munderover>\ +</math>"); + var math = document.body.lastElementChild; + var munderover = math.getElementsByTagName("munderover"); + // width_delta will be 20px per MathML, 3 * 20 = 60px if mundeover does not stack its children and 0px if mspace is not supported. + var width_delta = + munderover[1].getBoundingClientRect().width - + munderover[0].getBoundingClientRect().width; + this._has_munderover = width_delta > 10 && width_delta < 30; + document.body.removeChild(math); + } + return this._has_munderover; + }, + + "has_none": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_semantics": function() { + // FIXME: Improve feature detection. + return this.has_mspace(); + }, + + "has_dir": function() { + if (!this.hasOwnProperty("_has_dir")) { + document.body.insertAdjacentHTML("beforeend", "<math style='direction: ltr !important;'>\ +<mtext dir='rtl'></mtext>\ +</math>"); + var math = document.body.lastElementChild; + this._has_dir = + window.getComputedStyle(math.firstElementChild). + getPropertyValue('direction') === 'rtl'; + document.body.removeChild(math); + } + return this._has_dir; + }, + + "has_mathsize": function() { + if (!this.hasOwnProperty("_has_mathsize")) { + document.body.insertAdjacentHTML("beforeend", "<math style='font-size: 64px !important;'>\ +<mtext mathsize='32px'></mtext>\ +</math>"); + var math = document.body.lastElementChild; + this._has_mathsize = + window.getComputedStyle(math.firstElementChild). + getPropertyValue('font-size') === '32px'; + document.body.removeChild(math); + } + return this._has_mathsize; + }, + + "has_movablelimits": function() { + if (!this.hasOwnProperty("_has_movablelimits")) { + document.body.insertAdjacentHTML("beforeend", "<math>\ +<munder>\ + <mo style='font-size: 30px !important' movablelimits='false'>A</mo>\ + <mspace width='100px'></mspace>\ +</munder>\ +<munder>\ + <mo style='font-size: 30px !important' movablelimits='true'>A</mo>\ + <mspace width='100px'></mspace>\ +</munder>\ +</math>"); + var math = document.body.lastElementChild; + var munder = math.getElementsByTagName("munder"); + // If movablelimits is supported, the <mspace> will be placed next + // to <mo> rather than below it, so width_delta is about the width + // of the <mo>. + var width_delta = + munder[1].getBoundingClientRect().width - + munder[0].getBoundingClientRect().width; + this._has_movablelimits = this.has_munder() && width_delta > 20; + document.body.removeChild(math); + } + return this._has_movablelimits; + }, + + "has_operator_spacing": function() { + // https://w3c.github.io/mathml-core/#dfn-lspace + // https://w3c.github.io/mathml-core/#layout-of-mrow + if (!this.hasOwnProperty("_has_operator_spacing")) { + document.body.insertAdjacentHTML("beforeend", "<math>\ +<mrow>\ + <mn>1</mn><mo lspace='0px' rspace='0px'>+</mo><mn>2</mn>\ +</mrow>\ +<mrow>\ + <mn>1</mn><mo lspace='20px' rspace='20px'>+</mo><mn>2</mn>\ +</mrow>\ +</math>"); + var math = document.body.lastElementChild; + var mrow = math.getElementsByTagName("mrow"); + // lspace/rspace will add 40px per MathML and none if not supported. + this._has_operator_spacing = + mrow[1].getBoundingClientRect().width - + mrow[0].getBoundingClientRect().width > 30; + document.body.removeChild(math); + } + return this._has_operator_spacing; + }, + + ensure_for_match_reftest: function(has_function) { + if (!document.querySelector("link[rel='match']")) + throw "This function must only be used for match reftest"; + // Add a little red square at the top left corner if the feature is not supported in order to make match reftest fail. + if (!this[has_function]()) { + document.body.insertAdjacentHTML("beforeend", "\ +<div style='width: 10px !important; height: 10px !important;\ + position: absolute !important;\ + left: 0 !important; top: 0 !important;\ + background: red !important; z-index: 1000 !important;'></div>"); + } + } +}; diff --git a/testing/web-platform/tests/mathml/support/fonts.js b/testing/web-platform/tests/mathml/support/fonts.js new file mode 100644 index 0000000000..f05d7278ad --- /dev/null +++ b/testing/web-platform/tests/mathml/support/fonts.js @@ -0,0 +1,9 @@ +function loadAllFonts() { + // Use this to wait for all fonts in a testcase to load rather than just using + // `document.fonts.ready.then(...)` in the load event, since there are compat + // issues between browsers as to whether content initiated font loads are + // guaranteed to have been started by this point. + + // FIXME: Use Promise.all() to cause an obvious failure when a font fails to load. + return Promise.allSettled([...document.fonts].map(f => f.load())); +} diff --git a/testing/web-platform/tests/mathml/support/layout-comparison.js b/testing/web-platform/tests/mathml/support/layout-comparison.js new file mode 100644 index 0000000000..452b45006e --- /dev/null +++ b/testing/web-platform/tests/mathml/support/layout-comparison.js @@ -0,0 +1,112 @@ +function getWritingMode(element, reference) { + var style = window.getComputedStyle(reference); + if (style.getPropertyValue("writing-mode") !== "horizontal-tb" || + style.getPropertyValue("direction") !== "ltr") + throw "Reference should have writing mode horizontal-tb and ltr"; + + style = window.getComputedStyle(element); + var param = { + rtl: style.getPropertyValue("direction") === "rtl", + mode: style.getPropertyValue("writing-mode") + }; + + return param; +} + +function compareSize(element, reference, epsilon) { + var param = getWritingMode(element, reference); + var elementBox = element.getBoundingClientRect(); + var referenceBox = reference.getBoundingClientRect(); + + switch(param.mode) { + case "horizontal-tb": + assert_approx_equals(elementBox.width, referenceBox.width, epsilon, + "inline size"); + assert_approx_equals(elementBox.height, referenceBox.height, epsilon, + "block size"); + break; + case "vertical-lr": + case "vertical-rl": + assert_approx_equals(elementBox.width, referenceBox.height, epsilon, + "inline size"); + assert_approx_equals(elementBox.height, referenceBox.width, epsilon, + "block size"); + break; + default: + throw "compareSize: Unrecognized writing-mode value"; + } +} + +function childrenHaveEmptyBoundingClientRects(element) { + Array.from(element.children).forEach(child => { + var childBox = child.getBoundingClientRect(); + assert_true(childBox.left == 0 && childBox.right == 0 && childBox.top == 0 && childBox.bottom == 0); + }) +} + +function participateToParentLayout(child) { + var style = window.getComputedStyle(child); + return style.getPropertyValue("display") !== "none" && + style.getPropertyValue("position") !== "absolute" && + style.getPropertyValue("position") !== "fixed"; +} + +function childrenParticipatingToLayout(element) { + var children = []; + Array.from(element.children).forEach(child => { + if (participateToParentLayout(child)) + children.push(child); + }) + return children; +} + +function compareLayout(element, reference, epsilon) { + // Compare sizes of elements and children. + var param = getWritingMode(element, reference); + + compareSize(element, reference, epsilon); + var elementBox = element.getBoundingClientRect(); + var referenceBox = reference.getBoundingClientRect(); + + var elementChildren = childrenParticipatingToLayout(element); + var referenceChildren = childrenParticipatingToLayout(reference); + if (elementChildren.length != referenceChildren.length) + throw "Reference should have the same number of children participating to layout." + + for (var i = 0; i < elementChildren.length; i++) { + compareSize(elementChildren[i], referenceChildren[i], epsilon); + + var childBox = elementChildren[i].getBoundingClientRect(); + var referenceChildBox = referenceChildren[i].getBoundingClientRect(); + + switch(param.mode) { + case "horizontal-tb": + assert_approx_equals(param.rtl ? + elementBox.right - childBox.right : + childBox.left - elementBox.left, + referenceChildBox.left - referenceBox.left, + epsilon, + `inline position (child ${i})`); + assert_approx_equals(childBox.top - elementBox.top, + referenceChildBox.top - referenceBox.top, + epsilon, + `block position (child ${i})`); + break; + case "vertical-lr": + case "vertical-rl": + assert_approx_equals(param.rtl ? + elementBox.bottom - childBox.bottom : + childBox.top - elementBox.top, + referenceChildBox.left - referenceBox.left, + epsilon, + `inline position (child ${i})`); + assert_approx_equals(elementBox.right - childBox.right, + referenceChildBox.top - referenceBox.top, + epsilon, + `block position (child ${i})`); + break; + default: + throw "compareLayout: Unrecognized writing-mode value"; + } + } +} diff --git a/testing/web-platform/tests/mathml/support/mathml-fragments.js b/testing/web-platform/tests/mathml/support/mathml-fragments.js new file mode 100644 index 0000000000..7e2113e95b --- /dev/null +++ b/testing/web-platform/tests/mathml/support/mathml-fragments.js @@ -0,0 +1,189 @@ +var MathMLFragments = { + "annotation": "\ +<semantics>\ + <mrow></mrow>\ + <annotation class='element text-container'></annotation>\ +</semantics>", + "annotation-xml": "\ +<semantics>\ + <mrow></mrow>\ + <annotation-xml class='element text-container foreign-container'></annotation-xml>\ +</semantics>", + "maction": "\ +<maction class='element' actiontype='statusline'>\ + <mrow class='mathml-container'></mrow>\ + <mtext class='text-container'></mtext>\ +</maction>", + "menclose": "<menclose class='element mathml-container'></menclose>", + "merror": "<merror class='element mathml-container'></merror>", + "mfrac": "\ +<mfrac class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</mfrac>", + "mi": "<mi class='element text-container foreign-container'></mi>", + "mmultiscripts": "\ +<mmultiscripts class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</mmultiscripts>", + "mn": "<mn class='element text-container foreign-container'></mn>", + "mo": "<mo class='element text-container foreign-container'></mo>", + "mover": "\ +<mover class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</mover>", + "mpadded": "<mpadded class='element mathml-container'></mpadded>", + "mphantom": "<mphantom class='element mathml-container'></mphantom>", + "mprescripts": "\ +<mmultiscripts>\ + <mrow class='mathml-container'></mrow>\ + <mprescripts class='element'/>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</mmultiscripts>", + "mroot": "\ +<mroot class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</mroot>", + "mrow": "<mrow class='element mathml-container'></mrow>", + "ms": "<ms class='element text-container foreign-container'></ms>", + "mspace": "<mspace class='element'></mspace>", + "msqrt": "<msqrt class='element mathml-container'></msqrt>", + "mstyle": "<mstyle class='element mathml-container'></mstyle>", + "msub": "\ +<msub class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</msub>", + "msubsup": "\ +<msubsup class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</msubsup>", + "msup": "\ +<msup class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</msup>", + "mtable": "\ +<mtable class='element'>\ + <mtr>\ + <mtd class='mathml-container'>\ + </mtd>\ + </mtr>\ +</mtable>", + "mtd": "\ +<mtable>\ + <mtr>\ + <mtd class='element mathml-container'>\ + </mtd>\ + </mtr>\ +</mtable>", + "mtext": "<mtext class='element text-container foreign-container'></mtext>", + "mtr": "\ +<mtable>\ + <mtr class='element'>\ + <mtd class='mathml-container'>\ + </mtd>\ + </mtr>\ +</mtable>", + "munder": "\ +<munder class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</munder>", + "munderover": "\ +<munderover class='element'>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ + <mrow class='mathml-container'></mrow>\ +</munderover>", + "none": "\ +<mmultiscripts>\ + <mrow class='mathml-container'></mrow>\ + <none class='element'/>\ + <mrow class='mathml-container'></mrow>\ +</mmultiscripts>", + "semantics": "\ +<semantics class='element'>\ + <mrow class='mathml-container'></mrow>\ + <annotation class='text-container'></annotation>\ +</semantics>" +}; + +var FragmentHelper = { + mathml_namespace: "http://www.w3.org/1998/Math/MathML", + + createElement: function(tag) { + return document.createElementNS(this.mathml_namespace, tag); + }, + + isValidChildOfMrow: function(tag) { + return !(tag == "annotation" || + tag == "annotation-xml" || + tag == "mprescripts" || + tag == "none" || + tag == "mtr" || + tag == "mtd"); + }, + + isTokenElement: function(tag) { + return (tag == "mi" || + tag == "mtext" || + tag == "mo" || + tag == "mn" || + tag == "ms") + }, + + isEmpty: function(tag) { + return tag === "mspace" || tag == "mprescripts" || tag == "none"; + }, + + element: function(fragment) { + return fragment.getElementsByClassName('element')[0]; + }, + + appendChild: function(fragment, allowInvalid) { + var element = this.element(fragment) || fragment; + if (element.classList.contains("foreign-container")) { + var el = document.createElement("span"); + el.textContent = "a"; + return element.appendChild(el); + } + if (element.classList.contains("mathml-container") || allowInvalid) { + var el = this.createElement("mi"); + el.textContent = "a"; + return element.appendChild(el); + } + throw "Cannot append child to the element"; + }, + + forceNonEmptyElement: function(fragment) { + var element = this.element(fragment) || fragment; + if (element.firstElementChild) + return element.firstElementChild; + return this.appendChild(fragment); + }, + + forceNonEmptyDescendants: function(fragment) { + var element = this.element(fragment) || fragment; + if (element.classList.contains("mathml-container") || + element.classList.contains("foreign-container")) { + for (var i = 0; i < 10; i++) + this.appendChild(element); + return; + } + var child = element.firstElementChild; + if (child) { + for (; child; child = child.nextElementSibling) { + this.forceNonEmptyDescendants(child); + } + return; + } + }, +} diff --git a/testing/web-platform/tests/mathml/support/operator-dictionary.js b/testing/web-platform/tests/mathml/support/operator-dictionary.js new file mode 100644 index 0000000000..ee1de102fe --- /dev/null +++ b/testing/web-platform/tests/mathml/support/operator-dictionary.js @@ -0,0 +1,42 @@ +async function fetchOperatorDictionary() { + let response = await fetch(`/mathml/support/operator-dictionary.json`); + return response.json(); +} + +function splitKey(key) { + var value = key.split(" ") + return { + characters: value[0], + form: value[1] + }; +} + +function spaceIndexToLength(index) { + // See https://w3c.github.io/mathml-core/#operator-dictionary + return ["0", + "0.05555555555555555em", + "0.1111111111111111em", + "0.16666666666666666em", + "0.2222222222222222em", + "0.2777777777777778em", + "0.3333333333333333em", + "0.3888888888888889em" + ][index]; +} + +function defaultPropertyValue(entry, name) { + switch (name) { + case "lspace": + case "rspace": + return spaceIndexToLength(entry.hasOwnProperty(name) ? entry[name] : 5); + break + case "largeop": + case "movablelimits": + case "stretchy": + case "symmetric": + case "accent": + return entry[name]; + default: + throw `Unknown property ${name}`; + } +} diff --git a/testing/web-platform/tests/mathml/support/operator-dictionary.json b/testing/web-platform/tests/mathml/support/operator-dictionary.json new file mode 100644 index 0000000000..0008f5114e --- /dev/null +++ b/testing/web-platform/tests/mathml/support/operator-dictionary.json @@ -0,0 +1 @@ +{"comment": "This file was automatically generated by operator-dictionary.py. Do not edit.", "dictionary": {"! postfix": {"lspace": 0, "rspace": 0}, "! prefix": {"lspace": 0, "rspace": 0}, "!! postfix": {"lspace": 0, "rspace": 0}, "!= infix": {"lspace": 5, "rspace": 5}, "\" postfix": {"lspace": 0, "rspace": 0}, "% infix": {"lspace": 3, "rspace": 3}, "% postfix": {"lspace": 0, "rspace": 0}, "& postfix": {"lspace": 0, "rspace": 0}, "&& infix": {"lspace": 4, "rspace": 4}, "' postfix": {"lspace": 0, "rspace": 0}, "( prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, ") postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "* infix": {"lspace": 3, "rspace": 3}, "** infix": {"lspace": 3, "rspace": 3}, "*= infix": {"lspace": 5, "rspace": 5}, "+ infix": {"lspace": 4, "rspace": 4}, "+ prefix": {"lspace": 0, "rspace": 0}, "++ postfix": {"lspace": 0, "rspace": 0}, "+= infix": {"lspace": 5, "rspace": 5}, ", infix": {"lspace": 0, "rspace": 3}, "- infix": {"lspace": 4, "rspace": 4}, "- prefix": {"lspace": 0, "rspace": 0}, "-- postfix": {"lspace": 0, "rspace": 0}, "-= infix": {"lspace": 5, "rspace": 5}, "-> infix": {"lspace": 5, "rspace": 5}, ". infix": {"lspace": 3, "rspace": 3}, "/ infix": {"lspace": 4, "rspace": 4}, "// infix": {"lspace": 5, "rspace": 5}, "/= infix": {"lspace": 5, "rspace": 5}, ": infix": {"lspace": 0, "rspace": 3}, ":= infix": {"lspace": 5, "rspace": 5}, "; infix": {"lspace": 0, "rspace": 3}, "< infix": {"lspace": 5, "rspace": 5}, "<= infix": {"lspace": 5, "rspace": 5}, "<> infix": {"lspace": 3, "rspace": 3}, "= infix": {"horizontal": true, "lspace": 5, "rspace": 5}, "== infix": {"lspace": 5, "rspace": 5}, "> infix": {"lspace": 5, "rspace": 5}, ">= infix": {"lspace": 5, "rspace": 5}, "? infix": {"lspace": 3, "rspace": 3}, "@ infix": {"lspace": 3, "rspace": 3}, "[ prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\\ infix": {"lspace": 0, "rspace": 0}, "] postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "^ infix": {"horizontal": true, "lspace": 3, "rspace": 3}, "^ postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "_ infix": {"horizontal": true, "lspace": 0, "rspace": 0}, "_ postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "` postfix": {"lspace": 0, "rspace": 0}, "{ prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "| infix": {"lspace": 5, "rspace": 5}, "| postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "| prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "|| infix": {"lspace": 5, "rspace": 5}, "|| postfix": {"lspace": 0, "rspace": 0}, "|| prefix": {"lspace": 0, "rspace": 0}, "} postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "~ postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u00a0 infix": {}, "\u00a0 prefix": {}, "\u00a0 suffix": {}, "\u00a8 postfix": {"lspace": 0, "rspace": 0}, "\u00ac prefix": {"lspace": 0, "rspace": 0}, "\u00af postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u00b0 postfix": {"lspace": 0, "rspace": 0}, "\u00b1 infix": {"lspace": 4, "rspace": 4}, "\u00b1 prefix": {"lspace": 0, "rspace": 0}, "\u00b2 postfix": {"lspace": 0, "rspace": 0}, "\u00b3 postfix": {"lspace": 0, "rspace": 0}, "\u00b4 postfix": {"lspace": 0, "rspace": 0}, "\u00b7 infix": {"lspace": 3, "rspace": 3}, "\u00b8 postfix": {"lspace": 0, "rspace": 0}, "\u00b9 postfix": {"lspace": 0, "rspace": 0}, "\u00d7 infix": {"lspace": 3, "rspace": 3}, "\u00f7 infix": {"lspace": 4, "rspace": 4}, "\u02c6 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u02c7 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u02c9 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u02ca postfix": {"lspace": 0, "rspace": 0}, "\u02cb postfix": {"lspace": 0, "rspace": 0}, "\u02cd postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u02d8 postfix": {"lspace": 0, "rspace": 0}, "\u02d9 postfix": {"lspace": 0, "rspace": 0}, "\u02da postfix": {"lspace": 0, "rspace": 0}, "\u02dc postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u02dd postfix": {"lspace": 0, "rspace": 0}, "\u02f7 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u0302 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u0311 postfix": {"lspace": 0, "rspace": 0}, "\u2016 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2016 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2018 prefix": {"lspace": 0, "rspace": 0}, "\u2019 postfix": {"lspace": 0, "rspace": 0}, "\u201a postfix": {"lspace": 0, "rspace": 0}, "\u201b postfix": {"lspace": 0, "rspace": 0}, "\u201c prefix": {"lspace": 0, "rspace": 0}, "\u201d postfix": {"lspace": 0, "rspace": 0}, "\u201e postfix": {"lspace": 0, "rspace": 0}, "\u201f postfix": {"lspace": 0, "rspace": 0}, "\u2022 infix": {"lspace": 3, "rspace": 3}, "\u2032 postfix": {"lspace": 0, "rspace": 0}, "\u2033 postfix": {"lspace": 0, "rspace": 0}, "\u2034 postfix": {"lspace": 0, "rspace": 0}, "\u2035 postfix": {"lspace": 0, "rspace": 0}, "\u2036 postfix": {"lspace": 0, "rspace": 0}, "\u2037 postfix": {"lspace": 0, "rspace": 0}, "\u203e postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u2043 infix": {"lspace": 3, "rspace": 3}, "\u2044 infix": {"lspace": 4, "rspace": 4}, "\u2057 postfix": {"lspace": 0, "rspace": 0}, "\u2061 infix": {"lspace": 0, "rspace": 0}, "\u2062 infix": {"lspace": 0, "rspace": 0}, "\u2063 infix": {"lspace": 0, "rspace": 0}, "\u2064 infix": {"lspace": 0, "rspace": 0}, "\u20db postfix": {"lspace": 0, "rspace": 0}, "\u20dc postfix": {"lspace": 0, "rspace": 0}, "\u2145 prefix": {"lspace": 3, "rspace": 0}, "\u2146 prefix": {"lspace": 3, "rspace": 0}, "\u2190 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2191 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2192 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2193 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2194 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2195 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2196 infix": {"lspace": 5, "rspace": 5}, "\u2197 infix": {"lspace": 5, "rspace": 5}, "\u2198 infix": {"horizontal": true, "lspace": 5, "rspace": 5}, "\u2199 infix": {"horizontal": true, "lspace": 5, "rspace": 5}, "\u219a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u219b infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u219c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u219d infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u219e infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u219f infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21a0 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21a1 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21a2 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21a3 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21a4 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21a5 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21a6 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21a7 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21a8 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21a9 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21aa infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21ab infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21ac infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21ad infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21ae infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21af infix": {"lspace": 5, "rspace": 5}, "\u21b0 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21b1 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21b2 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21b3 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21b4 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21b5 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21b6 infix": {"lspace": 5, "rspace": 5}, "\u21b7 infix": {"lspace": 5, "rspace": 5}, "\u21b8 infix": {"lspace": 5, "rspace": 5}, "\u21b9 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21ba infix": {"lspace": 5, "rspace": 5}, "\u21bb infix": {"lspace": 5, "rspace": 5}, "\u21bc infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21bd infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21be infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21bf infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21c0 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21c1 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21c2 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21c3 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21c4 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21c5 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21c6 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21c7 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21c8 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21c9 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21ca infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21cb infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21cc infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21cd infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21ce infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21cf infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21d0 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21d1 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21d2 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21d3 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21d4 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21d5 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21d6 infix": {"lspace": 5, "rspace": 5}, "\u21d7 infix": {"lspace": 5, "rspace": 5}, "\u21d8 infix": {"lspace": 5, "rspace": 5}, "\u21d9 infix": {"lspace": 5, "rspace": 5}, "\u21da infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21db infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21dc infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21dd infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21de infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21df infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21e0 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21e1 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21e2 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21e3 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21e4 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21e5 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21e6 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21e7 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21e8 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21e9 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21ea infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21eb infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21ec infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21ed infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21ee infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21ef infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21f0 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21f1 infix": {"lspace": 5, "rspace": 5}, "\u21f2 infix": {"lspace": 5, "rspace": 5}, "\u21f3 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21f4 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21f5 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u21f6 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21f7 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21f8 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21f9 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21fa infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21fb infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21fc infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21fd infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21fe infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u21ff infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2200 prefix": {"lspace": 0, "rspace": 0}, "\u2201 prefix": {"lspace": 0, "rspace": 0}, "\u2202 prefix": {"lspace": 3, "rspace": 0}, "\u2203 prefix": {"lspace": 0, "rspace": 0}, "\u2204 prefix": {"lspace": 0, "rspace": 0}, "\u2206 infix": {"lspace": 0, "rspace": 0}, "\u2207 prefix": {"lspace": 0, "rspace": 0}, "\u2208 infix": {"lspace": 5, "rspace": 5}, "\u2209 infix": {"lspace": 5, "rspace": 5}, "\u220a infix": {"lspace": 5, "rspace": 5}, "\u220b infix": {"lspace": 5, "rspace": 5}, "\u220c infix": {"lspace": 5, "rspace": 5}, "\u220d infix": {"lspace": 5, "rspace": 5}, "\u220f prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2210 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2211 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2212 infix": {"lspace": 4, "rspace": 4}, "\u2212 prefix": {"lspace": 0, "rspace": 0}, "\u2213 infix": {"lspace": 4, "rspace": 4}, "\u2213 prefix": {"lspace": 0, "rspace": 0}, "\u2214 infix": {"lspace": 4, "rspace": 4}, "\u2215 infix": {"lspace": 4, "rspace": 4}, "\u2216 infix": {"lspace": 4, "rspace": 4}, "\u2217 infix": {"lspace": 3, "rspace": 3}, "\u2218 infix": {"lspace": 3, "rspace": 3}, "\u2219 infix": {"lspace": 3, "rspace": 3}, "\u221a prefix": {"lspace": 3, "rspace": 0}, "\u221b prefix": {"lspace": 3, "rspace": 0}, "\u221c prefix": {"lspace": 3, "rspace": 0}, "\u221d infix": {"lspace": 5, "rspace": 5}, "\u221f prefix": {"lspace": 0, "rspace": 0}, "\u2220 prefix": {"lspace": 0, "rspace": 0}, "\u2221 prefix": {"lspace": 0, "rspace": 0}, "\u2222 prefix": {"lspace": 0, "rspace": 0}, "\u2223 infix": {"lspace": 5, "rspace": 5}, "\u2224 infix": {"lspace": 5, "rspace": 5}, "\u2225 infix": {"lspace": 5, "rspace": 5}, "\u2226 infix": {"lspace": 5, "rspace": 5}, "\u2227 infix": {"lspace": 4, "rspace": 4}, "\u2228 infix": {"lspace": 4, "rspace": 4}, "\u2229 infix": {"lspace": 4, "rspace": 4}, "\u222a infix": {"lspace": 4, "rspace": 4}, "\u222b prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u222c prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u222d prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u222e prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u222f prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2230 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2231 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2232 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2233 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2234 prefix": {"lspace": 0, "rspace": 0}, "\u2235 prefix": {"lspace": 0, "rspace": 0}, "\u2236 infix": {"lspace": 4, "rspace": 4}, "\u2237 infix": {"lspace": 5, "rspace": 5}, "\u2238 infix": {"lspace": 4, "rspace": 4}, "\u2239 infix": {"lspace": 5, "rspace": 5}, "\u223a infix": {"lspace": 5, "rspace": 5}, "\u223b infix": {"lspace": 5, "rspace": 5}, "\u223c infix": {"lspace": 5, "rspace": 5}, "\u223c prefix": {"lspace": 0, "rspace": 0}, "\u223d infix": {"lspace": 5, "rspace": 5}, "\u223e infix": {"lspace": 5, "rspace": 5}, "\u2240 infix": {"lspace": 3, "rspace": 3}, "\u2241 infix": {"lspace": 5, "rspace": 5}, "\u2242 infix": {"lspace": 5, "rspace": 5}, "\u2243 infix": {"lspace": 5, "rspace": 5}, "\u2244 infix": {"lspace": 5, "rspace": 5}, "\u2245 infix": {"lspace": 5, "rspace": 5}, "\u2246 infix": {"lspace": 5, "rspace": 5}, "\u2247 infix": {"lspace": 5, "rspace": 5}, "\u2248 infix": {"lspace": 5, "rspace": 5}, "\u2249 infix": {"lspace": 5, "rspace": 5}, "\u224a infix": {"lspace": 5, "rspace": 5}, "\u224b infix": {"lspace": 5, "rspace": 5}, "\u224c infix": {"lspace": 5, "rspace": 5}, "\u224d infix": {"lspace": 5, "rspace": 5}, "\u224e infix": {"lspace": 5, "rspace": 5}, "\u224f infix": {"lspace": 5, "rspace": 5}, "\u2250 infix": {"lspace": 5, "rspace": 5}, "\u2251 infix": {"lspace": 5, "rspace": 5}, "\u2252 infix": {"lspace": 5, "rspace": 5}, "\u2253 infix": {"lspace": 5, "rspace": 5}, "\u2254 infix": {"lspace": 5, "rspace": 5}, "\u2255 infix": {"lspace": 5, "rspace": 5}, "\u2256 infix": {"lspace": 5, "rspace": 5}, "\u2257 infix": {"lspace": 5, "rspace": 5}, "\u2258 infix": {"lspace": 5, "rspace": 5}, "\u2259 infix": {"lspace": 5, "rspace": 5}, "\u225a infix": {"lspace": 5, "rspace": 5}, "\u225b infix": {"lspace": 5, "rspace": 5}, "\u225c infix": {"lspace": 5, "rspace": 5}, "\u225d infix": {"lspace": 5, "rspace": 5}, "\u225e infix": {"lspace": 5, "rspace": 5}, "\u225f infix": {"lspace": 5, "rspace": 5}, "\u2260 infix": {"lspace": 5, "rspace": 5}, "\u2261 infix": {"lspace": 5, "rspace": 5}, "\u2262 infix": {"lspace": 5, "rspace": 5}, "\u2263 infix": {"lspace": 5, "rspace": 5}, "\u2264 infix": {"lspace": 5, "rspace": 5}, "\u2265 infix": {"lspace": 5, "rspace": 5}, "\u2266 infix": {"lspace": 5, "rspace": 5}, "\u2267 infix": {"lspace": 5, "rspace": 5}, "\u2268 infix": {"lspace": 5, "rspace": 5}, "\u2269 infix": {"lspace": 5, "rspace": 5}, "\u226a infix": {"lspace": 5, "rspace": 5}, "\u226b infix": {"lspace": 5, "rspace": 5}, "\u226c infix": {"lspace": 5, "rspace": 5}, "\u226d infix": {"lspace": 5, "rspace": 5}, "\u226e infix": {"lspace": 5, "rspace": 5}, "\u226f infix": {"lspace": 5, "rspace": 5}, "\u2270 infix": {"lspace": 5, "rspace": 5}, "\u2271 infix": {"lspace": 5, "rspace": 5}, "\u2272 infix": {"lspace": 5, "rspace": 5}, "\u2273 infix": {"lspace": 5, "rspace": 5}, "\u2274 infix": {"lspace": 5, "rspace": 5}, "\u2275 infix": {"lspace": 5, "rspace": 5}, "\u2276 infix": {"lspace": 5, "rspace": 5}, "\u2277 infix": {"lspace": 5, "rspace": 5}, "\u2278 infix": {"lspace": 5, "rspace": 5}, "\u2279 infix": {"lspace": 5, "rspace": 5}, "\u227a infix": {"lspace": 5, "rspace": 5}, "\u227b infix": {"lspace": 5, "rspace": 5}, "\u227c infix": {"lspace": 5, "rspace": 5}, "\u227d infix": {"lspace": 5, "rspace": 5}, "\u227e infix": {"lspace": 5, "rspace": 5}, "\u227f infix": {"lspace": 5, "rspace": 5}, "\u2280 infix": {"lspace": 5, "rspace": 5}, "\u2281 infix": {"lspace": 5, "rspace": 5}, "\u2282 infix": {"lspace": 5, "rspace": 5}, "\u2283 infix": {"lspace": 5, "rspace": 5}, "\u2284 infix": {"lspace": 5, "rspace": 5}, "\u2285 infix": {"lspace": 5, "rspace": 5}, "\u2286 infix": {"lspace": 5, "rspace": 5}, "\u2287 infix": {"lspace": 5, "rspace": 5}, "\u2288 infix": {"lspace": 5, "rspace": 5}, "\u2289 infix": {"lspace": 5, "rspace": 5}, "\u228a infix": {"lspace": 5, "rspace": 5}, "\u228b infix": {"lspace": 5, "rspace": 5}, "\u228c infix": {"lspace": 4, "rspace": 4}, "\u228d infix": {"lspace": 4, "rspace": 4}, "\u228e infix": {"lspace": 4, "rspace": 4}, "\u228f infix": {"lspace": 5, "rspace": 5}, "\u2290 infix": {"lspace": 5, "rspace": 5}, "\u2291 infix": {"lspace": 5, "rspace": 5}, "\u2292 infix": {"lspace": 5, "rspace": 5}, "\u2293 infix": {"lspace": 4, "rspace": 4}, "\u2294 infix": {"lspace": 4, "rspace": 4}, "\u2295 infix": {"lspace": 4, "rspace": 4}, "\u2296 infix": {"lspace": 4, "rspace": 4}, "\u2297 infix": {"lspace": 3, "rspace": 3}, "\u2298 infix": {"lspace": 4, "rspace": 4}, "\u2299 infix": {"lspace": 3, "rspace": 3}, "\u229a infix": {"lspace": 3, "rspace": 3}, "\u229b infix": {"lspace": 3, "rspace": 3}, "\u229c infix": {"lspace": 5, "rspace": 5}, "\u229d infix": {"lspace": 4, "rspace": 4}, "\u229e infix": {"lspace": 4, "rspace": 4}, "\u229f infix": {"lspace": 4, "rspace": 4}, "\u22a0 infix": {"lspace": 3, "rspace": 3}, "\u22a1 infix": {"lspace": 3, "rspace": 3}, "\u22a2 infix": {"lspace": 5, "rspace": 5}, "\u22a3 infix": {"lspace": 5, "rspace": 5}, "\u22a6 infix": {"lspace": 5, "rspace": 5}, "\u22a7 infix": {"lspace": 5, "rspace": 5}, "\u22a8 infix": {"lspace": 5, "rspace": 5}, "\u22a9 infix": {"lspace": 5, "rspace": 5}, "\u22aa infix": {"lspace": 5, "rspace": 5}, "\u22ab infix": {"lspace": 5, "rspace": 5}, "\u22ac infix": {"lspace": 5, "rspace": 5}, "\u22ad infix": {"lspace": 5, "rspace": 5}, "\u22ae infix": {"lspace": 5, "rspace": 5}, "\u22af infix": {"lspace": 5, "rspace": 5}, "\u22b0 infix": {"lspace": 5, "rspace": 5}, "\u22b1 infix": {"lspace": 5, "rspace": 5}, "\u22b2 infix": {"lspace": 5, "rspace": 5}, "\u22b3 infix": {"lspace": 5, "rspace": 5}, "\u22b4 infix": {"lspace": 5, "rspace": 5}, "\u22b5 infix": {"lspace": 5, "rspace": 5}, "\u22b6 infix": {"lspace": 5, "rspace": 5}, "\u22b7 infix": {"lspace": 5, "rspace": 5}, "\u22b8 infix": {"lspace": 5, "rspace": 5}, "\u22ba infix": {"lspace": 3, "rspace": 3}, "\u22bb infix": {"lspace": 4, "rspace": 4}, "\u22bc infix": {"lspace": 4, "rspace": 4}, "\u22bd infix": {"lspace": 4, "rspace": 4}, "\u22be prefix": {"lspace": 0, "rspace": 0}, "\u22bf prefix": {"lspace": 0, "rspace": 0}, "\u22c0 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u22c1 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u22c2 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u22c3 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u22c4 infix": {"lspace": 3, "rspace": 3}, "\u22c5 infix": {"lspace": 3, "rspace": 3}, "\u22c6 infix": {"lspace": 3, "rspace": 3}, "\u22c7 infix": {"lspace": 3, "rspace": 3}, "\u22c8 infix": {"lspace": 5, "rspace": 5}, "\u22c9 infix": {"lspace": 3, "rspace": 3}, "\u22ca infix": {"lspace": 3, "rspace": 3}, "\u22cb infix": {"lspace": 3, "rspace": 3}, "\u22cc infix": {"lspace": 3, "rspace": 3}, "\u22cd infix": {"lspace": 5, "rspace": 5}, "\u22ce infix": {"lspace": 4, "rspace": 4}, "\u22cf infix": {"lspace": 4, "rspace": 4}, "\u22d0 infix": {"lspace": 5, "rspace": 5}, "\u22d1 infix": {"lspace": 5, "rspace": 5}, "\u22d2 infix": {"lspace": 4, "rspace": 4}, "\u22d3 infix": {"lspace": 4, "rspace": 4}, "\u22d4 infix": {"lspace": 5, "rspace": 5}, "\u22d5 infix": {"lspace": 5, "rspace": 5}, "\u22d6 infix": {"lspace": 5, "rspace": 5}, "\u22d7 infix": {"lspace": 5, "rspace": 5}, "\u22d8 infix": {"lspace": 5, "rspace": 5}, "\u22d9 infix": {"lspace": 5, "rspace": 5}, "\u22da infix": {"lspace": 5, "rspace": 5}, "\u22db infix": {"lspace": 5, "rspace": 5}, "\u22dc infix": {"lspace": 5, "rspace": 5}, "\u22dd infix": {"lspace": 5, "rspace": 5}, "\u22de infix": {"lspace": 5, "rspace": 5}, "\u22df infix": {"lspace": 5, "rspace": 5}, "\u22e0 infix": {"lspace": 5, "rspace": 5}, "\u22e1 infix": {"lspace": 5, "rspace": 5}, "\u22e2 infix": {"lspace": 5, "rspace": 5}, "\u22e3 infix": {"lspace": 5, "rspace": 5}, "\u22e4 infix": {"lspace": 5, "rspace": 5}, "\u22e5 infix": {"lspace": 5, "rspace": 5}, "\u22e6 infix": {"lspace": 5, "rspace": 5}, "\u22e7 infix": {"lspace": 5, "rspace": 5}, "\u22e8 infix": {"lspace": 5, "rspace": 5}, "\u22e9 infix": {"lspace": 5, "rspace": 5}, "\u22ea infix": {"lspace": 5, "rspace": 5}, "\u22eb infix": {"lspace": 5, "rspace": 5}, "\u22ec infix": {"lspace": 5, "rspace": 5}, "\u22ed infix": {"lspace": 5, "rspace": 5}, "\u22f2 infix": {"lspace": 5, "rspace": 5}, "\u22f3 infix": {"lspace": 5, "rspace": 5}, "\u22f4 infix": {"lspace": 5, "rspace": 5}, "\u22f5 infix": {"lspace": 5, "rspace": 5}, "\u22f6 infix": {"lspace": 5, "rspace": 5}, "\u22f7 infix": {"lspace": 5, "rspace": 5}, "\u22f8 infix": {"lspace": 5, "rspace": 5}, "\u22f9 infix": {"lspace": 5, "rspace": 5}, "\u22fa infix": {"lspace": 5, "rspace": 5}, "\u22fb infix": {"lspace": 5, "rspace": 5}, "\u22fc infix": {"lspace": 5, "rspace": 5}, "\u22fd infix": {"lspace": 5, "rspace": 5}, "\u22fe infix": {"lspace": 5, "rspace": 5}, "\u22ff infix": {"lspace": 5, "rspace": 5}, "\u2301 infix": {"lspace": 5, "rspace": 5}, "\u2305 infix": {"lspace": 3, "rspace": 3}, "\u2306 infix": {"lspace": 3, "rspace": 3}, "\u2308 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2309 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u230a prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u230b postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2310 prefix": {"lspace": 0, "rspace": 0}, "\u2319 prefix": {"lspace": 0, "rspace": 0}, "\u2322 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u2323 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u2329 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u232a postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u237c infix": {"lspace": 5, "rspace": 5}, "\u238b infix": {"lspace": 5, "rspace": 5}, "\u23b4 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u23b5 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u23cd postfix": {"lspace": 0, "rspace": 0}, "\u23dc postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u23dd postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u23de postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u23df postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u23e0 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u23e1 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\u2772 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2773 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2794 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2795 infix": {"lspace": 4, "rspace": 4}, "\u2795 prefix": {"lspace": 0, "rspace": 0}, "\u2796 infix": {"lspace": 4, "rspace": 4}, "\u2796 prefix": {"lspace": 0, "rspace": 0}, "\u2797 infix": {"lspace": 4, "rspace": 4}, "\u2798 infix": {"lspace": 5, "rspace": 5}, "\u2799 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u279a infix": {"lspace": 5, "rspace": 5}, "\u279b infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u279c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u279d infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u279e infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u279f infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27a0 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27a1 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27a5 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27a6 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27a7 infix": {"lspace": 5, "rspace": 5}, "\u27a8 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27a9 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27aa infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27ab infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27ac infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27ad infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27ae infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27af infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27b1 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27b2 infix": {"lspace": 5, "rspace": 5}, "\u27b3 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27b4 infix": {"lspace": 5, "rspace": 5}, "\u27b5 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27b6 infix": {"lspace": 5, "rspace": 5}, "\u27b7 infix": {"lspace": 5, "rspace": 5}, "\u27b8 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27b9 infix": {"lspace": 5, "rspace": 5}, "\u27ba infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27bb infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27bc infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27bd infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27be infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27c0 prefix": {"lspace": 0, "rspace": 0}, "\u27c2 infix": {"lspace": 5, "rspace": 5}, "\u27cb infix": {"lspace": 3, "rspace": 3}, "\u27cd infix": {"lspace": 3, "rspace": 3}, "\u27e6 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27e7 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27e8 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27e9 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27ea prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27eb postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27ec prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27ed postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27ee prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27ef postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u27f0 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u27f1 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u27f2 infix": {"lspace": 5, "rspace": 5}, "\u27f3 infix": {"lspace": 5, "rspace": 5}, "\u27f4 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27f5 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27f6 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27f7 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27f8 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27f9 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27fa infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27fb infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27fc infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27fd infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27fe infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u27ff infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2900 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2901 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2902 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2903 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2904 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2905 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2906 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2907 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2908 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2909 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u290a infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u290b infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u290c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u290d infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u290e infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u290f infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2910 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2911 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2912 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2913 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2914 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2915 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2916 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2917 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2918 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2919 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u291a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u291b infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u291c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u291d infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u291e infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u291f infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2920 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2921 infix": {"lspace": 5, "rspace": 5}, "\u2922 infix": {"lspace": 5, "rspace": 5}, "\u2923 infix": {"lspace": 5, "rspace": 5}, "\u2924 infix": {"lspace": 5, "rspace": 5}, "\u2925 infix": {"lspace": 5, "rspace": 5}, "\u2926 infix": {"lspace": 5, "rspace": 5}, "\u2927 infix": {"lspace": 5, "rspace": 5}, "\u2928 infix": {"lspace": 5, "rspace": 5}, "\u2929 infix": {"lspace": 5, "rspace": 5}, "\u292a infix": {"lspace": 5, "rspace": 5}, "\u292b infix": {"lspace": 5, "rspace": 5}, "\u292c infix": {"lspace": 5, "rspace": 5}, "\u292d infix": {"lspace": 5, "rspace": 5}, "\u292e infix": {"lspace": 5, "rspace": 5}, "\u292f infix": {"lspace": 5, "rspace": 5}, "\u2930 infix": {"lspace": 5, "rspace": 5}, "\u2931 infix": {"lspace": 5, "rspace": 5}, "\u2932 infix": {"lspace": 5, "rspace": 5}, "\u2933 infix": {"lspace": 5, "rspace": 5}, "\u2934 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2935 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2936 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2937 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2938 infix": {"lspace": 5, "rspace": 5}, "\u2939 infix": {"lspace": 5, "rspace": 5}, "\u293a infix": {"lspace": 5, "rspace": 5}, "\u293b infix": {"lspace": 5, "rspace": 5}, "\u293c infix": {"lspace": 5, "rspace": 5}, "\u293d infix": {"lspace": 5, "rspace": 5}, "\u293e infix": {"lspace": 5, "rspace": 5}, "\u293f infix": {"lspace": 5, "rspace": 5}, "\u2940 infix": {"lspace": 5, "rspace": 5}, "\u2941 infix": {"lspace": 5, "rspace": 5}, "\u2942 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2943 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2944 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2945 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2946 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2947 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2948 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2949 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u294a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u294b infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u294c infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u294d infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u294e infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u294f infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2950 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2951 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2952 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2953 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2954 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2955 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2956 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2957 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2958 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2959 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u295a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u295b infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u295c infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u295d infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u295e infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u295f infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2960 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2961 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2962 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2963 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2964 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2965 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2966 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2967 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2968 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2969 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u296a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u296b infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u296c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u296d infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u296e infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u296f infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2970 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2971 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2972 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2973 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2974 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2975 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2976 infix": {"lspace": 5, "rspace": 5}, "\u2977 infix": {"lspace": 5, "rspace": 5}, "\u2978 infix": {"lspace": 5, "rspace": 5}, "\u2979 infix": {"lspace": 5, "rspace": 5}, "\u297a infix": {"lspace": 5, "rspace": 5}, "\u297b infix": {"lspace": 5, "rspace": 5}, "\u297c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u297d infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u297e infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u297f infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2980 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2980 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2981 infix": {"lspace": 5, "rspace": 5}, "\u2982 infix": {"lspace": 5, "rspace": 5}, "\u2983 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2984 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2985 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2986 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2987 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2988 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2989 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u298a postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u298b prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u298c postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u298d prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u298e postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u298f prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2990 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2991 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2992 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2993 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2994 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2995 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2996 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2997 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2998 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2999 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2999 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u299b prefix": {"lspace": 0, "rspace": 0}, "\u299c prefix": {"lspace": 0, "rspace": 0}, "\u299d prefix": {"lspace": 0, "rspace": 0}, "\u299e prefix": {"lspace": 0, "rspace": 0}, "\u299f prefix": {"lspace": 0, "rspace": 0}, "\u29a0 prefix": {"lspace": 0, "rspace": 0}, "\u29a1 prefix": {"lspace": 0, "rspace": 0}, "\u29a2 prefix": {"lspace": 0, "rspace": 0}, "\u29a3 prefix": {"lspace": 0, "rspace": 0}, "\u29a4 prefix": {"lspace": 0, "rspace": 0}, "\u29a5 prefix": {"lspace": 0, "rspace": 0}, "\u29a6 prefix": {"lspace": 0, "rspace": 0}, "\u29a7 prefix": {"lspace": 0, "rspace": 0}, "\u29a8 prefix": {"lspace": 0, "rspace": 0}, "\u29a9 prefix": {"lspace": 0, "rspace": 0}, "\u29aa prefix": {"lspace": 0, "rspace": 0}, "\u29ab prefix": {"lspace": 0, "rspace": 0}, "\u29ac prefix": {"lspace": 0, "rspace": 0}, "\u29ad prefix": {"lspace": 0, "rspace": 0}, "\u29ae prefix": {"lspace": 0, "rspace": 0}, "\u29af prefix": {"lspace": 0, "rspace": 0}, "\u29b6 infix": {"lspace": 5, "rspace": 5}, "\u29b7 infix": {"lspace": 5, "rspace": 5}, "\u29b8 infix": {"lspace": 4, "rspace": 4}, "\u29b9 infix": {"lspace": 5, "rspace": 5}, "\u29bc infix": {"lspace": 4, "rspace": 4}, "\u29c0 infix": {"lspace": 5, "rspace": 5}, "\u29c1 infix": {"lspace": 5, "rspace": 5}, "\u29c4 infix": {"lspace": 4, "rspace": 4}, "\u29c5 infix": {"lspace": 4, "rspace": 4}, "\u29c6 infix": {"lspace": 3, "rspace": 3}, "\u29c7 infix": {"lspace": 3, "rspace": 3}, "\u29c8 infix": {"lspace": 3, "rspace": 3}, "\u29ce infix": {"lspace": 5, "rspace": 5}, "\u29cf infix": {"lspace": 5, "rspace": 5}, "\u29d0 infix": {"lspace": 5, "rspace": 5}, "\u29d1 infix": {"lspace": 5, "rspace": 5}, "\u29d2 infix": {"lspace": 5, "rspace": 5}, "\u29d3 infix": {"lspace": 5, "rspace": 5}, "\u29d4 infix": {"lspace": 3, "rspace": 3}, "\u29d5 infix": {"lspace": 3, "rspace": 3}, "\u29d6 infix": {"lspace": 3, "rspace": 3}, "\u29d7 infix": {"lspace": 3, "rspace": 3}, "\u29d8 prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u29d9 postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u29da prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u29db postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u29df infix": {"lspace": 5, "rspace": 5}, "\u29e1 infix": {"lspace": 5, "rspace": 5}, "\u29e2 infix": {"lspace": 3, "rspace": 3}, "\u29e3 infix": {"lspace": 5, "rspace": 5}, "\u29e4 infix": {"lspace": 5, "rspace": 5}, "\u29e5 infix": {"lspace": 5, "rspace": 5}, "\u29e6 infix": {"lspace": 5, "rspace": 5}, "\u29f4 infix": {"lspace": 5, "rspace": 5}, "\u29f5 infix": {"lspace": 4, "rspace": 4}, "\u29f6 infix": {"lspace": 4, "rspace": 4}, "\u29f7 infix": {"lspace": 4, "rspace": 4}, "\u29f8 infix": {"lspace": 4, "rspace": 4}, "\u29f9 infix": {"lspace": 4, "rspace": 4}, "\u29fa infix": {"lspace": 4, "rspace": 4}, "\u29fb infix": {"lspace": 4, "rspace": 4}, "\u29fc prefix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u29fd postfix": {"lspace": 0, "rspace": 0, "stretchy": true, "symmetric": true}, "\u2a00 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a01 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a02 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a03 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a04 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a05 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a06 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a07 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a08 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a09 prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a0a prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a0b prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a0c prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a0d prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a0e prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a0f prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a10 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a11 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a12 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a13 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a14 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a15 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a16 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a17 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a18 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a19 prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a1a prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a1b prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a1c prefix": {"largeop": true, "lspace": 3, "rspace": 3, "symmetric": true}, "\u2a1d infix": {"lspace": 3, "rspace": 3}, "\u2a1d prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a1e infix": {"lspace": 3, "rspace": 3}, "\u2a1e prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2a1f infix": {"lspace": 4, "rspace": 4}, "\u2a20 infix": {"lspace": 4, "rspace": 4}, "\u2a21 infix": {"lspace": 4, "rspace": 4}, "\u2a22 infix": {"lspace": 4, "rspace": 4}, "\u2a23 infix": {"lspace": 4, "rspace": 4}, "\u2a24 infix": {"lspace": 4, "rspace": 4}, "\u2a25 infix": {"lspace": 4, "rspace": 4}, "\u2a26 infix": {"lspace": 4, "rspace": 4}, "\u2a27 infix": {"lspace": 4, "rspace": 4}, "\u2a28 infix": {"lspace": 4, "rspace": 4}, "\u2a29 infix": {"lspace": 4, "rspace": 4}, "\u2a2a infix": {"lspace": 4, "rspace": 4}, "\u2a2b infix": {"lspace": 4, "rspace": 4}, "\u2a2c infix": {"lspace": 4, "rspace": 4}, "\u2a2d infix": {"lspace": 4, "rspace": 4}, "\u2a2e infix": {"lspace": 4, "rspace": 4}, "\u2a2f infix": {"lspace": 3, "rspace": 3}, "\u2a30 infix": {"lspace": 3, "rspace": 3}, "\u2a31 infix": {"lspace": 3, "rspace": 3}, "\u2a32 infix": {"lspace": 3, "rspace": 3}, "\u2a33 infix": {"lspace": 3, "rspace": 3}, "\u2a34 infix": {"lspace": 3, "rspace": 3}, "\u2a35 infix": {"lspace": 3, "rspace": 3}, "\u2a36 infix": {"lspace": 3, "rspace": 3}, "\u2a37 infix": {"lspace": 3, "rspace": 3}, "\u2a38 infix": {"lspace": 4, "rspace": 4}, "\u2a39 infix": {"lspace": 4, "rspace": 4}, "\u2a3a infix": {"lspace": 4, "rspace": 4}, "\u2a3b infix": {"lspace": 3, "rspace": 3}, "\u2a3c infix": {"lspace": 3, "rspace": 3}, "\u2a3d infix": {"lspace": 3, "rspace": 3}, "\u2a3e infix": {"lspace": 4, "rspace": 4}, "\u2a3f infix": {"lspace": 3, "rspace": 3}, "\u2a40 infix": {"lspace": 4, "rspace": 4}, "\u2a41 infix": {"lspace": 4, "rspace": 4}, "\u2a42 infix": {"lspace": 4, "rspace": 4}, "\u2a43 infix": {"lspace": 4, "rspace": 4}, "\u2a44 infix": {"lspace": 4, "rspace": 4}, "\u2a45 infix": {"lspace": 4, "rspace": 4}, "\u2a46 infix": {"lspace": 4, "rspace": 4}, "\u2a47 infix": {"lspace": 4, "rspace": 4}, "\u2a48 infix": {"lspace": 4, "rspace": 4}, "\u2a49 infix": {"lspace": 4, "rspace": 4}, "\u2a4a infix": {"lspace": 4, "rspace": 4}, "\u2a4b infix": {"lspace": 4, "rspace": 4}, "\u2a4c infix": {"lspace": 4, "rspace": 4}, "\u2a4d infix": {"lspace": 4, "rspace": 4}, "\u2a4e infix": {"lspace": 4, "rspace": 4}, "\u2a4f infix": {"lspace": 4, "rspace": 4}, "\u2a50 infix": {"lspace": 3, "rspace": 3}, "\u2a51 infix": {"lspace": 4, "rspace": 4}, "\u2a52 infix": {"lspace": 4, "rspace": 4}, "\u2a53 infix": {"lspace": 4, "rspace": 4}, "\u2a54 infix": {"lspace": 4, "rspace": 4}, "\u2a55 infix": {"lspace": 4, "rspace": 4}, "\u2a56 infix": {"lspace": 4, "rspace": 4}, "\u2a57 infix": {"lspace": 4, "rspace": 4}, "\u2a58 infix": {"lspace": 4, "rspace": 4}, "\u2a59 infix": {"lspace": 4, "rspace": 4}, "\u2a5a infix": {"lspace": 4, "rspace": 4}, "\u2a5b infix": {"lspace": 4, "rspace": 4}, "\u2a5c infix": {"lspace": 4, "rspace": 4}, "\u2a5d infix": {"lspace": 4, "rspace": 4}, "\u2a5e infix": {"lspace": 4, "rspace": 4}, "\u2a5f infix": {"lspace": 4, "rspace": 4}, "\u2a60 infix": {"lspace": 4, "rspace": 4}, "\u2a61 infix": {"lspace": 4, "rspace": 4}, "\u2a62 infix": {"lspace": 4, "rspace": 4}, "\u2a63 infix": {"lspace": 4, "rspace": 4}, "\u2a64 infix": {"lspace": 3, "rspace": 3}, "\u2a65 infix": {"lspace": 3, "rspace": 3}, "\u2a66 infix": {"lspace": 5, "rspace": 5}, "\u2a67 infix": {"lspace": 5, "rspace": 5}, "\u2a68 infix": {"lspace": 5, "rspace": 5}, "\u2a69 infix": {"lspace": 5, "rspace": 5}, "\u2a6a infix": {"lspace": 5, "rspace": 5}, "\u2a6b infix": {"lspace": 5, "rspace": 5}, "\u2a6c infix": {"lspace": 5, "rspace": 5}, "\u2a6d infix": {"lspace": 5, "rspace": 5}, "\u2a6e infix": {"lspace": 5, "rspace": 5}, "\u2a6f infix": {"lspace": 5, "rspace": 5}, "\u2a70 infix": {"lspace": 5, "rspace": 5}, "\u2a71 infix": {"lspace": 5, "rspace": 5}, "\u2a72 infix": {"lspace": 5, "rspace": 5}, "\u2a73 infix": {"lspace": 5, "rspace": 5}, "\u2a74 infix": {"lspace": 5, "rspace": 5}, "\u2a75 infix": {"lspace": 5, "rspace": 5}, "\u2a76 infix": {"lspace": 5, "rspace": 5}, "\u2a77 infix": {"lspace": 5, "rspace": 5}, "\u2a78 infix": {"lspace": 5, "rspace": 5}, "\u2a79 infix": {"lspace": 5, "rspace": 5}, "\u2a7a infix": {"lspace": 5, "rspace": 5}, "\u2a7b infix": {"lspace": 5, "rspace": 5}, "\u2a7c infix": {"lspace": 5, "rspace": 5}, "\u2a7d infix": {"lspace": 5, "rspace": 5}, "\u2a7e infix": {"lspace": 5, "rspace": 5}, "\u2a7f infix": {"lspace": 5, "rspace": 5}, "\u2a80 infix": {"lspace": 5, "rspace": 5}, "\u2a81 infix": {"lspace": 5, "rspace": 5}, "\u2a82 infix": {"lspace": 5, "rspace": 5}, "\u2a83 infix": {"lspace": 5, "rspace": 5}, "\u2a84 infix": {"lspace": 5, "rspace": 5}, "\u2a85 infix": {"lspace": 5, "rspace": 5}, "\u2a86 infix": {"lspace": 5, "rspace": 5}, "\u2a87 infix": {"lspace": 5, "rspace": 5}, "\u2a88 infix": {"lspace": 5, "rspace": 5}, "\u2a89 infix": {"lspace": 5, "rspace": 5}, "\u2a8a infix": {"lspace": 5, "rspace": 5}, "\u2a8b infix": {"lspace": 5, "rspace": 5}, "\u2a8c infix": {"lspace": 5, "rspace": 5}, "\u2a8d infix": {"lspace": 5, "rspace": 5}, "\u2a8e infix": {"lspace": 5, "rspace": 5}, "\u2a8f infix": {"lspace": 5, "rspace": 5}, "\u2a90 infix": {"lspace": 5, "rspace": 5}, "\u2a91 infix": {"lspace": 5, "rspace": 5}, "\u2a92 infix": {"lspace": 5, "rspace": 5}, "\u2a93 infix": {"lspace": 5, "rspace": 5}, "\u2a94 infix": {"lspace": 5, "rspace": 5}, "\u2a95 infix": {"lspace": 5, "rspace": 5}, "\u2a96 infix": {"lspace": 5, "rspace": 5}, "\u2a97 infix": {"lspace": 5, "rspace": 5}, "\u2a98 infix": {"lspace": 5, "rspace": 5}, "\u2a99 infix": {"lspace": 5, "rspace": 5}, "\u2a9a infix": {"lspace": 5, "rspace": 5}, "\u2a9b infix": {"lspace": 5, "rspace": 5}, "\u2a9c infix": {"lspace": 5, "rspace": 5}, "\u2a9d infix": {"lspace": 5, "rspace": 5}, "\u2a9e infix": {"lspace": 5, "rspace": 5}, "\u2a9f infix": {"lspace": 5, "rspace": 5}, "\u2aa0 infix": {"lspace": 5, "rspace": 5}, "\u2aa1 infix": {"lspace": 5, "rspace": 5}, "\u2aa2 infix": {"lspace": 5, "rspace": 5}, "\u2aa3 infix": {"lspace": 5, "rspace": 5}, "\u2aa4 infix": {"lspace": 5, "rspace": 5}, "\u2aa5 infix": {"lspace": 5, "rspace": 5}, "\u2aa6 infix": {"lspace": 5, "rspace": 5}, "\u2aa7 infix": {"lspace": 5, "rspace": 5}, "\u2aa8 infix": {"lspace": 5, "rspace": 5}, "\u2aa9 infix": {"lspace": 5, "rspace": 5}, "\u2aaa infix": {"lspace": 5, "rspace": 5}, "\u2aab infix": {"lspace": 5, "rspace": 5}, "\u2aac infix": {"lspace": 5, "rspace": 5}, "\u2aad infix": {"lspace": 5, "rspace": 5}, "\u2aae infix": {"lspace": 5, "rspace": 5}, "\u2aaf infix": {"lspace": 5, "rspace": 5}, "\u2ab0 infix": {"lspace": 5, "rspace": 5}, "\u2ab1 infix": {"lspace": 5, "rspace": 5}, "\u2ab2 infix": {"lspace": 5, "rspace": 5}, "\u2ab3 infix": {"lspace": 5, "rspace": 5}, "\u2ab4 infix": {"lspace": 5, "rspace": 5}, "\u2ab5 infix": {"lspace": 5, "rspace": 5}, "\u2ab6 infix": {"lspace": 5, "rspace": 5}, "\u2ab7 infix": {"lspace": 5, "rspace": 5}, "\u2ab8 infix": {"lspace": 5, "rspace": 5}, "\u2ab9 infix": {"lspace": 5, "rspace": 5}, "\u2aba infix": {"lspace": 5, "rspace": 5}, "\u2abb infix": {"lspace": 5, "rspace": 5}, "\u2abc infix": {"lspace": 5, "rspace": 5}, "\u2abd infix": {"lspace": 5, "rspace": 5}, "\u2abe infix": {"lspace": 5, "rspace": 5}, "\u2abf infix": {"lspace": 5, "rspace": 5}, "\u2ac0 infix": {"lspace": 5, "rspace": 5}, "\u2ac1 infix": {"lspace": 5, "rspace": 5}, "\u2ac2 infix": {"lspace": 5, "rspace": 5}, "\u2ac3 infix": {"lspace": 5, "rspace": 5}, "\u2ac4 infix": {"lspace": 5, "rspace": 5}, "\u2ac5 infix": {"lspace": 5, "rspace": 5}, "\u2ac6 infix": {"lspace": 5, "rspace": 5}, "\u2ac7 infix": {"lspace": 5, "rspace": 5}, "\u2ac8 infix": {"lspace": 5, "rspace": 5}, "\u2ac9 infix": {"lspace": 5, "rspace": 5}, "\u2aca infix": {"lspace": 5, "rspace": 5}, "\u2acb infix": {"lspace": 5, "rspace": 5}, "\u2acc infix": {"lspace": 5, "rspace": 5}, "\u2acd infix": {"lspace": 5, "rspace": 5}, "\u2ace infix": {"lspace": 5, "rspace": 5}, "\u2acf infix": {"lspace": 5, "rspace": 5}, "\u2ad0 infix": {"lspace": 5, "rspace": 5}, "\u2ad1 infix": {"lspace": 5, "rspace": 5}, "\u2ad2 infix": {"lspace": 5, "rspace": 5}, "\u2ad3 infix": {"lspace": 5, "rspace": 5}, "\u2ad4 infix": {"lspace": 5, "rspace": 5}, "\u2ad5 infix": {"lspace": 5, "rspace": 5}, "\u2ad6 infix": {"lspace": 5, "rspace": 5}, "\u2ad7 infix": {"lspace": 5, "rspace": 5}, "\u2ad8 infix": {"lspace": 5, "rspace": 5}, "\u2ad9 infix": {"lspace": 5, "rspace": 5}, "\u2ada infix": {"lspace": 5, "rspace": 5}, "\u2adb infix": {"lspace": 4, "rspace": 4}, "\u2adc infix": {"lspace": 3, "rspace": 3}, "\u2add infix": {"lspace": 3, "rspace": 3}, "\u2ade infix": {"lspace": 5, "rspace": 5}, "\u2adf infix": {"lspace": 5, "rspace": 5}, "\u2ae0 infix": {"lspace": 5, "rspace": 5}, "\u2ae1 infix": {"lspace": 5, "rspace": 5}, "\u2ae2 infix": {"lspace": 5, "rspace": 5}, "\u2ae3 infix": {"lspace": 5, "rspace": 5}, "\u2ae4 infix": {"lspace": 5, "rspace": 5}, "\u2ae5 infix": {"lspace": 5, "rspace": 5}, "\u2ae6 infix": {"lspace": 5, "rspace": 5}, "\u2ae7 infix": {"lspace": 5, "rspace": 5}, "\u2ae8 infix": {"lspace": 5, "rspace": 5}, "\u2ae9 infix": {"lspace": 5, "rspace": 5}, "\u2aea infix": {"lspace": 5, "rspace": 5}, "\u2aeb infix": {"lspace": 5, "rspace": 5}, "\u2aec prefix": {"lspace": 0, "rspace": 0}, "\u2aed prefix": {"lspace": 0, "rspace": 0}, "\u2aee infix": {"lspace": 5, "rspace": 5}, "\u2af2 infix": {"lspace": 5, "rspace": 5}, "\u2af3 infix": {"lspace": 5, "rspace": 5}, "\u2af4 infix": {"lspace": 5, "rspace": 5}, "\u2af5 infix": {"lspace": 5, "rspace": 5}, "\u2af6 infix": {"lspace": 4, "rspace": 4}, "\u2af7 infix": {"lspace": 5, "rspace": 5}, "\u2af8 infix": {"lspace": 5, "rspace": 5}, "\u2af9 infix": {"lspace": 5, "rspace": 5}, "\u2afa infix": {"lspace": 5, "rspace": 5}, "\u2afb infix": {"lspace": 4, "rspace": 4}, "\u2afc prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2afd infix": {"lspace": 4, "rspace": 4}, "\u2afe infix": {"lspace": 3, "rspace": 3}, "\u2aff prefix": {"largeop": true, "lspace": 3, "movablelimits": true, "rspace": 3, "symmetric": true}, "\u2b00 infix": {"lspace": 5, "rspace": 5}, "\u2b01 infix": {"lspace": 5, "rspace": 5}, "\u2b02 infix": {"lspace": 5, "rspace": 5}, "\u2b03 infix": {"lspace": 5, "rspace": 5}, "\u2b04 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b05 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b06 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b07 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b08 infix": {"lspace": 5, "rspace": 5}, "\u2b09 infix": {"lspace": 5, "rspace": 5}, "\u2b0a infix": {"lspace": 5, "rspace": 5}, "\u2b0b infix": {"lspace": 5, "rspace": 5}, "\u2b0c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b0d infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b0e infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b0f infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b10 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b11 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b30 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b31 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b32 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b33 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b34 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b35 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b36 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b37 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b38 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b39 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b3a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b3b infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b3c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b3d infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b3e infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b3f infix": {"lspace": 5, "rspace": 5}, "\u2b40 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b41 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b42 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b43 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b44 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b45 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b46 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b47 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b48 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b49 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b4a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b4b infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b4c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b4d infix": {"lspace": 5, "rspace": 5}, "\u2b4e infix": {"lspace": 5, "rspace": 5}, "\u2b4f infix": {"lspace": 5, "rspace": 5}, "\u2b5a infix": {"lspace": 5, "rspace": 5}, "\u2b5b infix": {"lspace": 5, "rspace": 5}, "\u2b5c infix": {"lspace": 5, "rspace": 5}, "\u2b5d infix": {"lspace": 5, "rspace": 5}, "\u2b5e infix": {"lspace": 5, "rspace": 5}, "\u2b5f infix": {"lspace": 5, "rspace": 5}, "\u2b60 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b61 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b62 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b63 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b64 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b65 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b66 infix": {"lspace": 5, "rspace": 5}, "\u2b67 infix": {"lspace": 5, "rspace": 5}, "\u2b68 infix": {"lspace": 5, "rspace": 5}, "\u2b69 infix": {"lspace": 5, "rspace": 5}, "\u2b6a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b6b infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b6c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b6d infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b6e infix": {"lspace": 5, "rspace": 5}, "\u2b6f infix": {"lspace": 5, "rspace": 5}, "\u2b70 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b71 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b72 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b73 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b76 infix": {"lspace": 5, "rspace": 5}, "\u2b77 infix": {"lspace": 5, "rspace": 5}, "\u2b78 infix": {"lspace": 5, "rspace": 5}, "\u2b79 infix": {"lspace": 5, "rspace": 5}, "\u2b7a infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b7b infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b7c infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b7d infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b80 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b81 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b82 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b83 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b84 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b85 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b86 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2b87 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2b88 infix": {"lspace": 5, "rspace": 5}, "\u2b89 infix": {"lspace": 5, "rspace": 5}, "\u2b8a infix": {"lspace": 5, "rspace": 5}, "\u2b8b infix": {"lspace": 5, "rspace": 5}, "\u2b8c infix": {"lspace": 5, "rspace": 5}, "\u2b8d infix": {"lspace": 5, "rspace": 5}, "\u2b8e infix": {"lspace": 5, "rspace": 5}, "\u2b8f infix": {"lspace": 5, "rspace": 5}, "\u2b94 infix": {"lspace": 5, "rspace": 5}, "\u2b95 infix": {"horizontal": true, "lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba0 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba1 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba2 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba3 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba4 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba5 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba6 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba7 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba8 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2ba9 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2baa infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2bab infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2bac infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2bad infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2bae infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2baf infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2bb0 infix": {"lspace": 5, "rspace": 5}, "\u2bb1 infix": {"lspace": 5, "rspace": 5}, "\u2bb2 infix": {"lspace": 5, "rspace": 5}, "\u2bb3 infix": {"lspace": 5, "rspace": 5}, "\u2bb4 infix": {"lspace": 5, "rspace": 5}, "\u2bb5 infix": {"lspace": 5, "rspace": 5}, "\u2bb6 infix": {"lspace": 5, "rspace": 5}, "\u2bb7 infix": {"lspace": 5, "rspace": 5}, "\u2bb8 infix": {"lspace": 5, "rspace": 5, "stretchy": true}, "\u2bd1 infix": {"lspace": 5, "rspace": 5}, "\ud83b\udef0 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}, "\ud83b\udef1 postfix": {"horizontal": true, "lspace": 0, "rspace": 0, "stretchy": true}}}
\ No newline at end of file diff --git a/testing/web-platform/tests/mathml/tools/axisheight.py b/testing/web-platform/tests/mathml/tools/axisheight.py new file mode 100755 index 0000000000..7640c4f789 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/axisheight.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +verticalArrowCodePoint = 0x21A8 +v1 = 5 * mathfont.em +v2 = 14 * mathfont.em +f = mathfont.create("axisheight%d-verticalarrow%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v1 +f.math.MinConnectorOverlap = 0 +mathfont.createSquareGlyph(f, verticalArrowCodePoint) +g = f.createChar(-1, "size1") +mathfont.drawRectangleGlyph(g, mathfont.em, v2 / 2, 0) +g = f.createChar(-1, "size2") +mathfont.drawRectangleGlyph(g, mathfont.em, v2, 0) +g = f.createChar(-1, "bot") +mathfont.drawRectangleGlyph(g, mathfont.em, v2 + v1, 0) +g = f.createChar(-1, "ext") +mathfont.drawRectangleGlyph(g, mathfont.em, mathfont.em, 0) +f[verticalArrowCodePoint].verticalVariants = "uni21A8 size1 size2" +# Part: (glyphName, isExtender, startConnector, endConnector, fullAdvance) +f[verticalArrowCodePoint].verticalComponents = \ + (("bot", False, 0, mathfont.em, v2 + v1), + ("ext", True, mathfont.em, mathfont.em, mathfont.em)) +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/fractions.py b/testing/web-platform/tests/mathml/tools/fractions.py new file mode 100755 index 0000000000..bd39fc2fdb --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/fractions.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +v1 = 7 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-axisheight%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v1 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 5 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-denominatordisplaystylegapmin%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = 0 +f.math.FractionDenominatorDisplayStyleGapMin = v1 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 6 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-denominatordisplaystyleshiftdown%d-axisheight%d-rulethickness%d" % (v1, v2, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v2 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = v1 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 4 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-denominatorgapmin%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = 0 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = v1 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 3 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-denominatorshiftdown%d-axisheight%d-rulethickness%d" % (v1, v2, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v2 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = v1 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 8 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-numeratordisplaystylegapmin%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = 0 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = v1 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 2 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-numeratordisplaystyleshiftup%d-axisheight%d-rulethickness%d" % (v1, v2, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v2 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = v1 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 9 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-numeratorgapmin%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = 0 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = v1 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 11 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("fraction-numeratorshiftup%d-axisheight%d-rulethickness%d" % (v1, v2, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v2 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = v1 +f.math.FractionRuleThickness = v2 +mathfont.save(f) + +v1 = 10 * mathfont.em +f = mathfont.create("fraction-rulethickness%d" % v1, + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = 0 +f.math.FractionDenominatorDisplayStyleGapMin = 0 +f.math.FractionDenominatorDisplayStyleShiftDown = 0 +f.math.FractionDenominatorGapMin = 0 +f.math.FractionDenominatorShiftDown = 0 +f.math.FractionNumeratorDisplayStyleGapMin = 0 +f.math.FractionNumeratorDisplayStyleShiftUp = 0 +f.math.FractionNumeratorGapMin = 0 +f.math.FractionNumeratorShiftUp = 0 +f.math.FractionRuleThickness = v1 +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/largeop.py b/testing/web-platform/tests/mathml/tools/largeop.py new file mode 100755 index 0000000000..9832ff0039 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/largeop.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +nAryWhiteVerticalBarCodePoint = 0x2AFF +v1 = 5 * mathfont.em +f = mathfont.create("largeop-displayoperatorminheight%d" % v1, + "Copyright (c) 2016 MathML Association") +f.math.DisplayOperatorMinHeight = v1 +mathfont.createSquareGlyph(f, nAryWhiteVerticalBarCodePoint) +g = f.createChar(-1, "uni2AFF.display") +mathfont.drawRectangleGlyph(g, mathfont.em, v1, 0) +f[nAryWhiteVerticalBarCodePoint].verticalVariants = "uni2AFF uni2AFF.display" +mathfont.save(f) + +v1 = 2 * mathfont.em +v2 = 3 * mathfont.em +f = mathfont.create("largeop-displayoperatorminheight%d-2AFF-italiccorrection%d" % (v1, v2), + "Copyright (c) 2018 Igalia S.L.") +f.math.DisplayOperatorMinHeight = v1 +mathfont.createSquareGlyph(f, nAryWhiteVerticalBarCodePoint) +g = f.createChar(-1, "uni2AFF.display") +p = g.glyphPen() +p.moveTo(0, 0) +p.lineTo(v2, v1) +p.lineTo(v2 + mathfont.em, v1) +p.lineTo(mathfont.em, 0) +p.closePath() +g.width = mathfont.em + v2 +g.italicCorrection = v2 +f[nAryWhiteVerticalBarCodePoint].verticalVariants = "uni2AFF uni2AFF.display" +mathfont.save(f) + +v1 = 7 * mathfont.em +v2 = 5 * mathfont.em +f = mathfont.create("largeop-displayoperatorminheight%d-2AFF-italiccorrection%d" % (v1, v2), + "Copyright (c) 2020 Igalia S.L.") +f.math.DisplayOperatorMinHeight = v1 +f.math.MinConnectorOverlap = 0 +mathfont.createSquareGlyph(f, nAryWhiteVerticalBarCodePoint) +g = f.createChar(-1, "uni2AFF.bot") +mathfont.drawRectangleGlyph(g, + width=2 * mathfont.em, + ascent=mathfont.em) +g = f.createChar(-1, "uni2AFF.ext") +mathfont.drawRectangleGlyph(g, + width=mathfont.em, + ascent=2 * mathfont.em, + padding_left=mathfont.em) +g = f.createChar(-1, "uni2AFF.top") +mathfont.drawRectangleGlyph(g, + width=v2 + mathfont.em, + ascent=mathfont.em, + padding_left=mathfont.em) +f[nAryWhiteVerticalBarCodePoint].verticalVariants = "uni2AFF" +# Part: (glyphName, isExtender, startConnector, endConnector, fullAdvance) +f[nAryWhiteVerticalBarCodePoint].verticalComponents = \ + (("uni2AFF.bot", False, 0, mathfont.em // 2, mathfont.em), + ("uni2AFF.ext", True, mathfont.em // 2, mathfont.em // 2, 2 * mathfont.em), + ("uni2AFF.top", False, mathfont.em // 2, 0, mathfont.em) + ) +f[nAryWhiteVerticalBarCodePoint].verticalComponentItalicCorrection = v2 +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/limits.py b/testing/web-platform/tests/mathml/tools/limits.py new file mode 100755 index 0000000000..db4437c1b0 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/limits.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +nArySumCodePoint = 0x2211 # largeop operator + +v = 3 * mathfont.em +f = mathfont.create("limits-lowerlimitbaselinedropmin%d" % v, + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, nArySumCodePoint) +f.math.LowerLimitBaselineDropMin = v +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 11 * mathfont.em +f = mathfont.create("limits-lowerlimitgapmin%d" % v, + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, nArySumCodePoint) +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = v +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 5 * mathfont.em +f = mathfont.create("limits-upperlimitbaselinerisemin%d" % v, + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, nArySumCodePoint) +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = v +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 7 * mathfont.em +f = mathfont.create("limits-upperlimitgapmin%d" % v, + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, nArySumCodePoint) +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = v +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/math-text.py b/testing/web-platform/tests/mathml/tools/math-text.py new file mode 100755 index 0000000000..2c3e3257dc --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/math-text.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +import fontforge + +font = fontforge.font() +font.em = 1000 +lineHeight = 5000 +name = "math-text" +font.fontname = name +font.familyname = name +font.fullname = name +font.copyright = "Copyright (c) 2019 Igalia" + +glyph = font.createChar(ord(" "), "space") +glyph.width = 1000 +glyph = font.createChar(ord("A")) +pen = glyph.glyphPen() +pen.moveTo(0, -500) +pen.lineTo(0, 500) +pen.lineTo(1000, 500) +pen.lineTo(1000, -500) +pen.closePath() + +glyph = font.createChar(ord("B")) +pen = glyph.glyphPen() +pen.moveTo(0, 0) +pen.lineTo(0, 1000) +pen.lineTo(1000, 1000) +pen.lineTo(1000, 0) +pen.closePath() + +glyph = font.createChar(ord("C")) +pen = glyph.glyphPen() +pen.moveTo(0, -1000) +pen.lineTo(0, 0) +pen.lineTo(1000, 0) +pen.lineTo(1000, -1000) +pen.closePath() + +font.os2_typoascent_add = False +font.os2_typoascent = lineHeight // 2 +font.os2_typodescent_add = False +font.os2_typodescent = -lineHeight // 2 +font.os2_typolinegap = 0 +font.hhea_ascent = lineHeight // 2 +font.hhea_ascent_add = False +font.hhea_descent = -lineHeight // 2 +font.hhea_descent_add = False +font.hhea_linegap = 0 +font.os2_winascent = lineHeight // 2 +font.os2_winascent_add = False +font.os2_windescent = lineHeight // 2 +font.os2_windescent_add = False + +font.os2_use_typo_metrics = True + +path = "../../fonts/math/math-text.woff" +print("Generating %s..." % path, end="") +font.generate(path) +if font.validate() == 0: + print(" done.") +else: + print(" validation error!") + exit(1) diff --git a/testing/web-platform/tests/mathml/tools/mathvariant-transforms.py b/testing/web-platform/tests/mathml/tools/mathvariant-transforms.py new file mode 100755 index 0000000000..e4857d2a3e --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/mathvariant-transforms.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python3 + +from lxml import etree +from utils.misc import downloadWithProgressBar, UnicodeXMLURL +from utils import mathfont + +# Retrieve the unicode.xml file if necessary. +unicodeXML = downloadWithProgressBar(UnicodeXMLURL) + +# Extract the mathvariants transformation. +xsltTransform = etree.XSLT(etree.XML('''\ +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + <xsl:strip-space elements="*"/> + <xsl:template match="charlist"> + <root><xsl:apply-templates select="character"/></root> + </xsl:template> + <xsl:template match="character"> + <xsl:if test="surrogate"> + <entry> + <xsl:attribute name="mathvariant"> + <xsl:value-of select="surrogate/@mathvariant"/> + </xsl:attribute> + <xsl:attribute name="baseChar"> + <xsl:value-of select="surrogate/@ref"/> + </xsl:attribute> + <xsl:attribute name="transformedChar"> + <xsl:choose> + <xsl:when test="bmp"> + <xsl:value-of select="bmp/@ref"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="@id"/> + </xsl:otherwise> + </xsl:choose> + </xsl:attribute> + </entry> + </xsl:if> + </xsl:template> +</xsl:stylesheet>''')) + +# Put the mathvariant transforms into a Python structure. +mathvariantTransforms = {} +root = xsltTransform(etree.parse(unicodeXML)).getroot() + + +def parseCodePoint(aHexaString): + return int("0x%s" % aHexaString[1:], 16) + + +for entry in root: + mathvariant = entry.get("mathvariant") + baseChar = parseCodePoint(entry.get("baseChar")) + transformedChar = parseCodePoint(entry.get("transformedChar")) + if mathvariant not in mathvariantTransforms: + mathvariantTransforms[mathvariant] = {} + mathvariantTransforms[mathvariant][baseChar] = transformedChar + +# There is no "isolated" mathvariant. +del mathvariantTransforms["isolated"] + +# Automatic mathvariant uses the same transform as italic. +# It is handled specially (see below). +mathvariantTransforms["auto"] = mathvariantTransforms["italic"] + +# Create a WOFF font for each mathvariant. +for mathvariant in mathvariantTransforms: + if mathvariant == "auto": + continue + font = mathfont.create("mathvariant-%s" % mathvariant, + "Copyright (c) 2016 MathML Association") + for baseChar in mathvariantTransforms[mathvariant]: + if baseChar not in font: + mathfont.createGlyphFromValue(font, baseChar) + transformedChar = mathvariantTransforms[mathvariant][baseChar] + mathfont.createGlyphFromValue(font, transformedChar) + mathfont.save(font) + +# Common function to generate test for MathML mathvariant / CSS text-transform. + + +def generateTestFor(mathvariant, mathml): + assert mathml or mathvariant == "auto", "These tests have been removed!" + print("Generating tests for %s..." % mathvariant, end="") + if mathml: + reftest = open( + "../relations/css-styling/mathvariant-%s.html" % mathvariant, "w") + reftestReference = open( + "../relations/css-styling/mathvariant-%s-ref.html" % mathvariant, "w") + else: + reftest = open( + "../../css/css-text/text-transform/math/text-transform-math-%s-001.html" % mathvariant, "w") + reftestReference = open( + "../../css/css-text/text-transform/math/text-transform-math-%s-001-ref.html" % mathvariant, "w") + source = '\ +<!DOCTYPE html>\n\ +<html>\n\ +<head>\n\ +<meta charset="utf-8"/>\n\ +<title>%s</title>\n' + if mathml: + reftest.write(source % ("mathvariant %s" % mathvariant)) + reftestReference.write( + source % ("mathvariant %s (reference)" % mathvariant)) + else: + reftest.write(source % ("text-transform math-%s" % mathvariant)) + reftestReference.write( + source % ("text-transform math-%s (reference)" % mathvariant)) + if mathvariant == "auto": + mathAssert = "Verify that a single-char <mi> is equivalent to an <mi> with the transformed italic unicode character." + mapping = "italic" + else: + mathAssert = "Verify that a single-char <mtext> with a %s mathvariant is equivalent to an <mtext> with the transformed unicode character." % mathvariant + mapping = mathvariant + if mathml: + source = '\ +<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">\n\ +<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">\n\ +<link rel="help" href="https://w3c.github.io/mathml-core/#new-text-transform-values">\n\ +<link rel="help" href="https://w3c.github.io/mathml-core/#%s-mappings">\n\ +<link rel="match" href="mathvariant-%s-ref.html"/>\n\ +<meta name="assert" content="%s">\n' + reftest.write(source % (mapping, mathvariant, mathAssert)) + else: + source = '\ +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3745"/>\n\ +<link rel="help" href="https://w3c.github.io/mathml-core/#new-text-transform-values">\n\ +<link rel="help" href="https://w3c.github.io/mathml-core/#%s-mappings">\n\ +<link rel="match" href="text-transform-math-%s-001-ref.html"/>\n\ +<meta name="assert" content="Verify that a character with \'text-transform: math-%s\' renders the same as the transformed unicode character.">\n' + reftest.write(source % (mapping, mathvariant, mathvariant)) + WOFFfont = "mathvariant-%s.woff" % mapping + source = '\ +<style>\n\ + @font-face {\n\ + font-family: TestFont;\n\ + src: url("/fonts/math/%s");\n\ + }\n\ + body > span {\n\ + padding: 10px;\n\ + }\n\ + span > span {\n\ + font-family: monospace;\n\ + font-size: 10px;\n\ + }\n\ + .testfont {\n\ + font-family: TestFont;\n\ + font-size: 10px;\n\ + }\n\ +</style>\n\ +<body>\n\ + <!-- Generated by mathml/tools/mathvariant.py; DO NOT EDIT. -->\n\ + <p>Test passes if all the equalities below are true.</p>\n' % WOFFfont + if mathml: + reftest.write(source) + reftestReference.write(source) + else: + reftest.write(source) + reftestReference.write(source) + charIndex = 0 + for baseChar in mathvariantTransforms[mathvariant]: + transformedChar = mathvariantTransforms[mathvariant][baseChar] + if mathvariant == "auto": + tokenTag = '<mi>&#x%0X;</mi>' % baseChar + tokenTagRef = '<mi>&#x%0X;</mi>' % transformedChar + else: + tokenTag = '<mtext mathvariant="%s">&#x%0X;</mtext>' % ( + mathvariant, baseChar) + tokenTagRef = '<mtext>&#x%0X;</mtext>' % transformedChar + if mathml: + reftest.write(' <span><math class="testfont">%s</math>=<span>%05X</span></span>' % + (tokenTag, transformedChar)) + reftestReference.write( + ' <span><math class="testfont">%s</math>=<span>%05X</span></span>' % (tokenTagRef, transformedChar)) + else: + reftest.write(' <span><span class="testfont" style="text-transform: math-%s">&#x%0X;</span>=<span>%05X</span></span>' % + (mathvariant, baseChar, transformedChar)) + reftestReference.write( + ' <span><span class="testfont">&#x%0X;</span>=<span>%05X</span></span>' % (transformedChar, transformedChar)) + charIndex += 1 + if charIndex % 10 == 0: + reftest.write('<br/>') + reftestReference.write('<br/>') + reftest.write('\n') + reftestReference.write('\n') + source = '</body>\n</html>\n' + reftest.write(source) + reftestReference.write(source) + reftest.close() + reftestReference.close() + print(" done.") + + +# Generate css/css-text/text-transform/math/text-transform-math-auto-001.html +generateTestFor(mathvariant="auto", mathml=False) +generateTestFor(mathvariant="auto", mathml=True) + +# Other mathvariant tests can be generated by the following command. They are +# still use internally by browsers implementing full mathvariant support. +# See https://github.com/w3c/mathml-core/issues/182 +# for mathvariant in mathvariantTransforms: +# generateTestFor(mathvariant, mathml=True) diff --git a/testing/web-platform/tests/mathml/tools/operator-dictionary.py b/testing/web-platform/tests/mathml/tools/operator-dictionary.py new file mode 100755 index 0000000000..8de654df15 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/operator-dictionary.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 + +from lxml import etree +from utils.misc import downloadWithProgressBar, UnicodeXMLURL, InlineAxisOperatorsURL +import json +import re +from utils import mathfont + +NonBreakingSpace = 0x00A0 + + +def parseHexaNumber(string): + return int("0x%s" % string, 16) + + +def parseHexaSequence(string): + return tuple(map(parseHexaNumber, string[1:].split("-"))) + + +def parseSpaces(value, entry, names): + for name in names: + attributeValue = entry.get(name) + if attributeValue is not None: + value[name] = int(attributeValue) + + +def parseProperties(value, entry, names): + attributeValue = entry.get("properties") + if attributeValue is not None: + for name in names: + if attributeValue.find(name) >= 0: + value[name] = True + + +def buildKeyAndValueFrom(characters, form): + # Concatenate characters and form to build the key. + key = "" + for c in characters: + key += chr(c) + key += " " + form + # But save characters as an individual property for easier manipulation in + # this Python script. + value = { + "characters": characters, + } + return key, value + + +# Retrieve the spec files. +inlineAxisOperatorsTXT = downloadWithProgressBar(InlineAxisOperatorsURL) +unicodeXML = downloadWithProgressBar(UnicodeXMLURL) + +# Extract the operator dictionary. +xsltTransform = etree.XSLT(etree.parse("./operator-dictionary.xsl")) + +# Put the operator dictionary into a Python structure. +inlineAxisOperators = {} +with open(inlineAxisOperatorsTXT, mode="r") as f: + for line in f: + hexaString = re.match(r"^U\+([0-9A-F]+)", line).group(1) + inlineAxisOperators[parseHexaNumber(hexaString)] = True + +operatorDictionary = {} +root = xsltTransform(etree.parse(unicodeXML)).getroot() +for entry in root: + characters = parseHexaSequence(entry.get("unicode")) + assert characters != (NonBreakingSpace) + key, value = buildKeyAndValueFrom(characters, entry.get("form")) + # There is no dictionary-specified minsize/maxsize values, so no need to + # parse them. + # The fence, separator and priority properties don't have any effect on math + # layout, so they are not added to the JSON file. + parseSpaces(value, entry, ["lspace", "rspace"]) + parseProperties(value, entry, ["stretchy", "symmetric", "largeop", + "movablelimits", "accent"]) + if (len(characters) == 1 and characters[0] in inlineAxisOperators): + value["horizontal"] = True + operatorDictionary[key] = value + +# Create entries for the non-breaking space in all forms in order to test the +# default for operators outside the official dictionary. +for form in ["infix", "prefix", "suffix"]: + key, value = buildKeyAndValueFrom(tuple([NonBreakingSpace]), form) + operatorDictionary[key] = value + +# Create a WOFF font with glyphs for all the operator strings. +font = mathfont.create("operators", "Copyright (c) 2019 Igalia S.L.") + +# Set parameters for largeop and stretchy tests. +font.math.DisplayOperatorMinHeight = 2 * mathfont.em +font.math.MinConnectorOverlap = mathfont.em // 2 + +# Set parameters for accent tests so that we only have large gap when +# overscript is an accent. +font.math.UpperLimitBaselineRiseMin = 0 +font.math.StretchStackTopShiftUp = 0 +font.math.AccentBaseHeight = 2 * mathfont.em +font.math.OverbarVerticalGap = 0 + +mathfont.createSizeVariants(font, True) + +# Ensure a glyph exists for the combining characters that are handled specially +# in the specification: +# U+0338 COMBINING LONG SOLIDUS OVERLAY +# U+20D2 COMBINING LONG VERTICAL LINE OVERLAY +for combining_character in [0x338, 0x20D2]: + mathfont.createSquareGlyph(font, combining_character) + +for key in operatorDictionary: + value = operatorDictionary[key] + for c in value["characters"]: + if c in font: + continue + if c == NonBreakingSpace: + g = font.createChar(c) + mathfont.drawRectangleGlyph(g, mathfont.em, mathfont.em // 3, 0) + else: + mathfont.createSquareGlyph(font, c) + mathfont.createStretchy(font, c, c in inlineAxisOperators) +mathfont.save(font) + +# Generate the python file. +for key in operatorDictionary: + del operatorDictionary[key]["characters"] # Remove this temporary value. +JSON = { + "comment": "This file was automatically generated by operator-dictionary.py. Do not edit.", + "dictionary": operatorDictionary +} +with open('../support/operator-dictionary.json', 'w') as fp: + json.dump(JSON, fp, sort_keys=True, ensure_ascii=True) diff --git a/testing/web-platform/tests/mathml/tools/operator-dictionary.xsl b/testing/web-platform/tests/mathml/tools/operator-dictionary.xsl new file mode 100644 index 0000000000..8c75317672 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/operator-dictionary.xsl @@ -0,0 +1,73 @@ +<!-- -*- Mode: nXML; tab-width: 2; indent-tabs-mode: nil; -*- --> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + + <xsl:strip-space elements="*"/> + + <xsl:template match="charlist"> + <root><xsl:apply-templates select="character"/></root> + </xsl:template> + + <xsl:template match="character"> + <xsl:if test="operator-dictionary"> + <xsl:for-each select="operator-dictionary"> + <entry> + + <xsl:attribute name="unicode"> + <xsl:value-of select="../@id"/> + </xsl:attribute> + + <xsl:attribute name="form"> + <xsl:value-of select="@form"/> + </xsl:attribute> + + <!-- begin operator-dictionary --> + <xsl:if test="@lspace"> + <xsl:attribute name="lspace"> + <xsl:value-of select="@lspace"/> + </xsl:attribute> + </xsl:if> + <xsl:if test="@rspace"> + <xsl:attribute name="rspace"> + <xsl:value-of select="@rspace"/> + </xsl:attribute> + </xsl:if> + <xsl:if test="@minsize"> + <xsl:attribute name="minsize"> + <xsl:value-of select="@minsize"/> + </xsl:attribute> + </xsl:if> + <xsl:if test="@*[.='true']"> + <xsl:attribute name="properties"> + <!-- largeop, movablelimits, stretchy, separator, accent, fence, + symmetric --> + <xsl:for-each select="@*[.='true']"> + <xsl:value-of select="name()"/> + <xsl:text> </xsl:text> + </xsl:for-each> + <xsl:if test="../unicodedata/@mirror = 'Y'"> + <xsl:text>mirrorable </xsl:text> + </xsl:if> + </xsl:attribute> + </xsl:if> + <xsl:if test="@priority"> + <xsl:attribute name="priority"> + <xsl:value-of select="@priority"/> + </xsl:attribute> + </xsl:if> + <xsl:if test="@linebreakstyle"> + <xsl:attribute name="linebreakstyle"> + <xsl:value-of select="@linebreakstyle"/> + </xsl:attribute> + </xsl:if> + <!-- end operator-dictionary --> + + <xsl:attribute name="description"> + <xsl:value-of select="../description"/> + </xsl:attribute> + + </entry> + </xsl:for-each> + </xsl:if> + </xsl:template> + +</xsl:stylesheet> diff --git a/testing/web-platform/tests/mathml/tools/percentscaledown.py b/testing/web-platform/tests/mathml/tools/percentscaledown.py new file mode 100755 index 0000000000..ef40d1fd87 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/percentscaledown.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +v1 = 80 +v2 = 40 +f = mathfont.create("scriptpercentscaledown%d-scriptscriptpercentscaledown%d" % (v1, v2), + "Copyright (c) 2019 Igalia S.L.") +f.math.ScriptPercentScaleDown = v1 +f.math.ScriptScriptPercentScaleDown = v2 +mathfont.save(f) + +f = mathfont.create("scriptpercentscaledown0-scriptscriptpercentscaledown%d" % v2, + "Copyright (c) 2019 Igalia S.L.") +f.math.ScriptPercentScaleDown = 0 +f.math.ScriptScriptPercentScaleDown = v2 +mathfont.save(f) + +f = mathfont.create("scriptpercentscaledown%d-scriptscriptpercentscaledown0" % v1, + "Copyright (c) 2019 Igalia S.L.") +f.math.ScriptPercentScaleDown = v1 +f.math.ScriptScriptPercentScaleDown = 0 +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/radicals.py b/testing/web-platform/tests/mathml/tools/radicals.py new file mode 100755 index 0000000000..c4d9ece813 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/radicals.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + + +def createStretchyRadical(aFont): + radicalCodePoint = 0x221a + mathfont.createSquareGlyph(aFont, radicalCodePoint) + g = aFont.createChar(-1, "size1") + mathfont.drawRectangleGlyph(g, mathfont.em, 2 * mathfont.em, 0) + g = aFont.createChar(-1, "size2") + mathfont.drawRectangleGlyph(g, mathfont.em, 3 * mathfont.em, 0) + g = aFont.createChar(-1, "size3") + mathfont.drawRectangleGlyph(g, mathfont.em, 4 * mathfont.em, 0) + aFont[radicalCodePoint].verticalVariants = "radical size1 size2 size3" + # Part: (glyphName, isExtender, startConnector, endConnector, fullAdvance) + aFont.math.MinConnectorOverlap = 0 + aFont[radicalCodePoint].verticalComponents = \ + (("size2", False, 0, mathfont.em, 3 * mathfont.em), + ("size1", True, mathfont.em, mathfont.em, 2 * mathfont.em)) + + +v1 = 25 +v2 = 1 * mathfont.em +f = mathfont.create("radical-degreebottomraisepercent%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +createStretchyRadical(f) +f.math.RadicalDegreeBottomRaisePercent = v1 +f.math.RadicalDisplayStyleVerticalGap = 0 +f.math.RadicalExtraAscender = 0 +f.math.RadicalKernAfterDegree = 0 +f.math.RadicalKernBeforeDegree = 0 +f.math.RadicalRuleThickness = v2 +f.math.RadicalVerticalGap = 0 +mathfont.save(f) + +v1 = 7 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("radical-displaystyleverticalgap%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +createStretchyRadical(f) +f.math.RadicalDegreeBottomRaisePercent = 0 +f.math.RadicalDisplayStyleVerticalGap = v1 +f.math.RadicalExtraAscender = 0 +f.math.RadicalKernAfterDegree = 0 +f.math.RadicalKernBeforeDegree = 0 +f.math.RadicalRuleThickness = v2 +f.math.RadicalVerticalGap = 0 +mathfont.save(f) + +v1 = 3 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("radical-extraascender%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +createStretchyRadical(f) +f.math.RadicalDegreeBottomRaisePercent = 0 +f.math.RadicalDisplayStyleVerticalGap = 0 +f.math.RadicalExtraAscender = v1 +f.math.RadicalKernAfterDegree = 0 +f.math.RadicalKernBeforeDegree = 0 +f.math.RadicalRuleThickness = v2 +f.math.RadicalVerticalGap = 0 +mathfont.save(f) + +v1 = 5 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("radical-kernafterdegreeminus%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +createStretchyRadical(f) +f.math.RadicalDegreeBottomRaisePercent = 0 +f.math.RadicalDisplayStyleVerticalGap = 0 +f.math.RadicalExtraAscender = 0 +f.math.RadicalKernAfterDegree = -v1 +f.math.RadicalKernBeforeDegree = 0 +f.math.RadicalRuleThickness = v2 +f.math.RadicalVerticalGap = 0 +mathfont.save(f) + +v1 = 4 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("radical-kernbeforedegree%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +createStretchyRadical(f) +f.math.RadicalDegreeBottomRaisePercent = 0 +f.math.RadicalDisplayStyleVerticalGap = 0 +f.math.RadicalExtraAscender = 0 +f.math.RadicalKernAfterDegree = 0 +f.math.RadicalKernBeforeDegree = v1 +f.math.RadicalRuleThickness = v2 +f.math.RadicalVerticalGap = 0 +mathfont.save(f) + +v = 8 * mathfont.em +f = mathfont.create("radical-rulethickness%d" % v, + "Copyright (c) 2016 MathML Association") +createStretchyRadical(f) +f.math.RadicalDegreeBottomRaisePercent = 0 +f.math.RadicalDisplayStyleVerticalGap = 0 +f.math.RadicalExtraAscender = 0 +f.math.RadicalKernAfterDegree = 0 +f.math.RadicalKernBeforeDegree = 0 +f.math.RadicalRuleThickness = v +f.math.RadicalVerticalGap = 0 +mathfont.save(f) + +v1 = 6 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("radical-verticalgap%d-rulethickness%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +createStretchyRadical(f) +f.math.RadicalDegreeBottomRaisePercent = 0 +f.math.RadicalDisplayStyleVerticalGap = 0 +f.math.RadicalExtraAscender = 0 +f.math.RadicalKernAfterDegree = 0 +f.math.RadicalKernBeforeDegree = 0 +f.math.RadicalRuleThickness = v2 +f.math.RadicalVerticalGap = v1 +mathfont.save(f) + +v1 = 1 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("radical-negativekernbeforedegree%d-rulethickness%d" % + (v1, v2), "Copyright (c) 2020 Igalia S.L.") +createStretchyRadical(f) +f.math.RadicalDegreeBottomRaisePercent = 0 +f.math.RadicalDisplayStyleVerticalGap = 0 +f.math.RadicalExtraAscender = 0 +f.math.RadicalKernAfterDegree = 0 +f.math.RadicalKernBeforeDegree = -v1 +f.math.RadicalRuleThickness = v2 +f.math.RadicalVerticalGap = 0 +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/scripts.py b/testing/web-platform/tests/mathml/tools/scripts.py new file mode 100755 index 0000000000..e1da482a00 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/scripts.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +v = 3 * mathfont.em +f = mathfont.create("scripts-spaceafterscript%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = v +f.math.SubSuperscriptGapMin = 0 +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) + +v = 7 * mathfont.em +f = mathfont.create("scripts-superscriptshiftup%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = 0 +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = v +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) + +v = 5 * mathfont.em +f = mathfont.create("scripts-superscriptshiftupcramped%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = 0 +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = v +mathfont.save(f) + +v = 6 * mathfont.em +f = mathfont.create("scripts-subscriptshiftdown%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = 0 +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = v +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) + +v = 11 * mathfont.em +f = mathfont.create("scripts-subsuperscriptgapmin%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = v +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) + +v1 = 11 * mathfont.em +v2 = 3 * mathfont.em +f = mathfont.create("scripts-subsuperscriptgapmin%d-superscriptbottommaxwithsubscript%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = v1 +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = v2 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) + +v = 4 * mathfont.em +f = mathfont.create("scripts-subscripttopmax%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = 0 +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = v +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) + +v = 8 * mathfont.em +f = mathfont.create("scripts-superscriptbottommin%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = 0 +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = v +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) + +v = 9 * mathfont.em +f = mathfont.create("scripts-subscriptbaselinedropmin%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = 0 +f.math.SubscriptBaselineDropMin = v +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = 0 +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) + +v = 10 * mathfont.em +f = mathfont.create("scripts-superscriptbaselinedropmax%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.SpaceAfterScript = 0 +f.math.SubSuperscriptGapMin = 0 +f.math.SubscriptBaselineDropMin = 0 +f.math.SubscriptShiftDown = 0 +f.math.SubscriptTopMax = 0 +f.math.SuperscriptBaselineDropMax = v +f.math.SuperscriptBottomMaxWithSubscript = 0 +f.math.SuperscriptBottomMin = 0 +f.math.SuperscriptShiftUp = 0 +f.math.SuperscriptShiftUpCramped = 0 +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/stacks.py b/testing/web-platform/tests/mathml/tools/stacks.py new file mode 100755 index 0000000000..b2ecec5386 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/stacks.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +v1 = 5 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("stack-bottomdisplaystyleshiftdown%d-axisheight%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v2 +f.math.StackBottomDisplayStyleShiftDown = v1 +f.math.StackBottomShiftDown = 0 +f.math.StackDisplayStyleGapMin = 0 +f.math.StackGapMin = 0 +f.math.StackTopDisplayStyleShiftUp = 0 +f.math.StackTopShiftUp = 0 +mathfont.save(f) + +v1 = 6 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("stack-bottomshiftdown%d-axisheight%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v2 +f.math.StackBottomDisplayStyleShiftDown = 0 +f.math.StackBottomShiftDown = v1 +f.math.StackDisplayStyleGapMin = 0 +f.math.StackGapMin = 0 +f.math.StackTopDisplayStyleShiftUp = 0 +f.math.StackTopShiftUp = 0 +mathfont.save(f) + +v = 4 * mathfont.em +f = mathfont.create("stack-displaystylegapmin%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = 0 +f.math.StackBottomDisplayStyleShiftDown = 0 +f.math.StackBottomShiftDown = 0 +f.math.StackDisplayStyleGapMin = v +f.math.StackGapMin = 0 +f.math.StackTopDisplayStyleShiftUp = 0 +f.math.StackTopShiftUp = 0 +mathfont.save(f) + +v = 8 * mathfont.em +f = mathfont.create("stack-gapmin%d" % v, + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = 0 +f.math.StackBottomDisplayStyleShiftDown = 0 +f.math.StackBottomShiftDown = 0 +f.math.StackDisplayStyleGapMin = 0 +f.math.StackGapMin = v +f.math.StackTopDisplayStyleShiftUp = 0 +f.math.StackTopShiftUp = 0 +mathfont.save(f) + +v1 = 3 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("stack-topdisplaystyleshiftup%d-axisheight%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v2 +f.math.StackBottomDisplayStyleShiftDown = 0 +f.math.StackBottomShiftDown = 0 +f.math.StackDisplayStyleGapMin = 0 +f.math.StackGapMin = 0 +f.math.StackTopDisplayStyleShiftUp = v1 +f.math.StackTopShiftUp = 0 +mathfont.save(f) + +v1 = 9 * mathfont.em +v2 = 1 * mathfont.em +f = mathfont.create("stack-topshiftup%d-axisheight%d" % (v1, v2), + "Copyright (c) 2016 MathML Association") +f.math.AxisHeight = v2 +f.math.StackBottomDisplayStyleShiftDown = 0 +f.math.StackBottomShiftDown = 0 +f.math.StackDisplayStyleGapMin = 0 +f.math.StackGapMin = 0 +f.math.StackTopDisplayStyleShiftUp = 0 +f.math.StackTopShiftUp = v1 +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/stretchstacks.py b/testing/web-platform/tests/mathml/tools/stretchstacks.py new file mode 100755 index 0000000000..e6c0b8b4dd --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/stretchstacks.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +arrowCodePoint = 0x2192 # horizontal stretch operator + +v = 3 * mathfont.em +f = mathfont.create("stretchstack-bottomshiftdown%d" % v, + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, arrowCodePoint) +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = v +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 11 * mathfont.em +f = mathfont.create("stretchstack-gapbelowmin%d" % v, + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, arrowCodePoint) +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = v +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 5 * mathfont.em +f = mathfont.create("stretchstack-topshiftup%d" % v, + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, arrowCodePoint) +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = v +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 7 * mathfont.em +f = mathfont.create("stretchstack-gapabovemin%d" % v, + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, arrowCodePoint) +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = v +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/stretchy-centered-on-baseline.py b/testing/web-platform/tests/mathml/tools/stretchy-centered-on-baseline.py new file mode 100755 index 0000000000..5ccfca3f1e --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/stretchy-centered-on-baseline.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +# Create a WOFF font with glyphs for all the operator strings. +font = mathfont.create("stretchy-centered-on-baseline", + "Copyright (c) 2023 Igalia S.L.") + +# Set parameters for stretchy tests. +font.math.MinConnectorOverlap = mathfont.em // 2 + +# Make sure that underover parameters don't add extra spacing. +font.math.LowerLimitBaselineDropMin = 0 +font.math.LowerLimitGapMin = 0 +font.math.StretchStackBottomShiftDown = 0 +font.math.StretchStackGapAboveMin = 0 +font.math.UnderbarVerticalGap = 0 +font.math.UnderbarExtraDescender = 0 +font.math.UpperLimitBaselineRiseMin = 0 +font.math.UpperLimitGapMin = 0 +font.math.StretchStackTopShiftUp = 0 +font.math.StretchStackGapBelowMin = 0 +font.math.OverbarVerticalGap = 0 +font.math.AccentBaseHeight = 0 +font.math.OverbarExtraAscender = 0 + +# These two characters will be stretchable in both directions. +horizontalArrow = 0x295A # LEFTWARDS HARPOON WITH BARB UP FROM BAR +verticalArrow = 0x295C # UPWARDS HARPOON WITH BARB RIGHT FROM BAR + +mathfont.createSizeVariants(font, aUsePUA=True, aCenterOnBaseline=True) + +# Add stretchy vertical and horizontal constructions for the horizontal arrow. +mathfont.createSquareGlyph(font, horizontalArrow) +mathfont.createStretchy(font, horizontalArrow, True) +mathfont.createStretchy(font, horizontalArrow, False) + +# Add stretchy vertical and horizontal constructions for the vertical arrow. +mathfont.createSquareGlyph(font, verticalArrow) +mathfont.createStretchy(font, verticalArrow, True) +mathfont.createStretchy(font, verticalArrow, False) + +mathfont.save(font) diff --git a/testing/web-platform/tests/mathml/tools/stretchy.py b/testing/web-platform/tests/mathml/tools/stretchy.py new file mode 100755 index 0000000000..34530f5792 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/stretchy.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +# Create a WOFF font with glyphs for all the operator strings. +font = mathfont.create("stretchy", "Copyright (c) 2021 Igalia S.L.") + +# Set parameters for stretchy tests. +font.math.MinConnectorOverlap = mathfont.em // 2 + +# Make sure that underover parameters don't add extra spacing. +font.math.LowerLimitBaselineDropMin = 0 +font.math.LowerLimitGapMin = 0 +font.math.StretchStackBottomShiftDown = 0 +font.math.StretchStackGapAboveMin = 0 +font.math.UnderbarVerticalGap = 0 +font.math.UnderbarExtraDescender = 0 +font.math.UpperLimitBaselineRiseMin = 0 +font.math.UpperLimitGapMin = 0 +font.math.StretchStackTopShiftUp = 0 +font.math.StretchStackGapBelowMin = 0 +font.math.OverbarVerticalGap = 0 +font.math.AccentBaseHeight = 0 +font.math.OverbarExtraAscender = 0 + +# These two characters will be stretchable in both directions. +horizontalArrow = 0x295A # LEFTWARDS HARPOON WITH BARB UP FROM BAR +verticalArrow = 0x295C # UPWARDS HARPOON WITH BARB RIGHT FROM BAR + +mathfont.createSizeVariants(font, aUsePUA=True, aCenterOnBaseline=False) + +# Add stretchy vertical and horizontal constructions for the horizontal arrow. +mathfont.createSquareGlyph(font, horizontalArrow) +mathfont.createStretchy(font, horizontalArrow, True) +mathfont.createStretchy(font, horizontalArrow, False) + +# Add stretchy vertical and horizontal constructions for the vertical arrow. +mathfont.createSquareGlyph(font, verticalArrow) +mathfont.createStretchy(font, verticalArrow, True) +mathfont.createStretchy(font, verticalArrow, False) + +mathfont.save(font) diff --git a/testing/web-platform/tests/mathml/tools/underover.py b/testing/web-platform/tests/mathml/tools/underover.py new file mode 100755 index 0000000000..469829cba2 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/underover.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +breveCodePoint = 0x2D8 # accent operator +degreeCodePoint = 0xB0 # nonaccent operator +accentBaseHeight = 4 * mathfont.em + +v = 3 * mathfont.em +f = mathfont.create("underover-accentbaseheight%d-overbarextraascender%d" % (accentBaseHeight, v), + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, breveCodePoint) +mathfont.createSquareGlyph(f, degreeCodePoint) +f.math.AccentBaseHeight = accentBaseHeight +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = v +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 11 * mathfont.em +f = mathfont.create("underover-accentbaseheight%d-overbarverticalgap%d" % (accentBaseHeight, v), + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, breveCodePoint) +mathfont.createSquareGlyph(f, degreeCodePoint) +f.math.AccentBaseHeight = accentBaseHeight +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = v +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 5 * mathfont.em +f = mathfont.create("underover-accentbaseheight%d-underbarextradescender%d" % (accentBaseHeight, v), + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, breveCodePoint) +mathfont.createSquareGlyph(f, degreeCodePoint) +f.math.AccentBaseHeight = accentBaseHeight +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = v +f.math.UnderbarVerticalGap = 0 +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) + +v = 7 * mathfont.em +f = mathfont.create("underover-accentbaseheight%d-underbarverticalgap%d" % (accentBaseHeight, v), + "Copyright (c) 2016 MathML Association") +mathfont.createSquareGlyph(f, breveCodePoint) +mathfont.createSquareGlyph(f, degreeCodePoint) +f.math.AccentBaseHeight = accentBaseHeight +f.math.LowerLimitBaselineDropMin = 0 +f.math.LowerLimitGapMin = 0 +f.math.OverbarExtraAscender = 0 +f.math.OverbarVerticalGap = 0 +f.math.StretchStackBottomShiftDown = 0 +f.math.StretchStackGapAboveMin = 0 +f.math.StretchStackGapBelowMin = 0 +f.math.StretchStackTopShiftUp = 0 +f.math.UnderbarExtraDescender = 0 +f.math.UnderbarVerticalGap = v +f.math.UpperLimitBaselineRiseMin = 0 +f.math.UpperLimitGapMin = 0 +mathfont.save(f) diff --git a/testing/web-platform/tests/mathml/tools/use-typo-lineheight.py b/testing/web-platform/tests/mathml/tools/use-typo-lineheight.py new file mode 100755 index 0000000000..6509a65175 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/use-typo-lineheight.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +import fontforge + +font = fontforge.font() +font.em = 1000 +typoLineHeight = 2300 +winHeight = 5000 +name = "font-lineheight%d-typolineheight%d" % (winHeight, typoLineHeight) +font.fontname = name +font.familyname = name +font.fullname = name +font.copyright = "Copyright (c) 2016 MathML Association" + +glyph = font.createChar(ord(" "), "space") +glyph.width = 1000 +glyph = font.createChar(ord("O")) +pen = glyph.glyphPen() +pen.moveTo(0, -200) +pen.lineTo(0, 800) +pen.lineTo(1000, 800) +pen.lineTo(1000, -200) +pen.closePath() + +font.os2_typoascent_add = False +font.os2_typoascent = 800 +font.os2_typodescent_add = False +font.os2_typodescent = -200 +font.os2_typolinegap = typoLineHeight - \ + (font.os2_typoascent - font.os2_typodescent) + +font.hhea_ascent = winHeight // 2 +font.hhea_ascent_add = False +font.hhea_descent = -winHeight // 2 +font.hhea_descent_add = False +font.hhea_linegap = 0 + +font.os2_winascent = winHeight // 2 +font.os2_winascent_add = False +font.os2_windescent = winHeight // 2 +font.os2_windescent_add = False + +font.os2_use_typo_metrics = True + +path = "../../fonts/math/lineheight%d-typolineheight%d.woff" % ( + winHeight, typoLineHeight) +print("Generating %s..." % path, end="") +font.generate(path) +if font.validate() == 0: + print(" done.") +else: + print(" validation error!") + exit(1) diff --git a/testing/web-platform/tests/mathml/tools/utils/__init__.py b/testing/web-platform/tests/mathml/tools/utils/__init__.py new file mode 100644 index 0000000000..c1e4c6d32e --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/utils/__init__.py @@ -0,0 +1 @@ +# This file is required for Python to search this directory for modules. diff --git a/testing/web-platform/tests/mathml/tools/utils/mathfont.py b/testing/web-platform/tests/mathml/tools/utils/mathfont.py new file mode 100644 index 0000000000..3eff0ac03d --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/utils/mathfont.py @@ -0,0 +1,232 @@ +import fontforge + +PUA_startCodePoint = 0xE000 +em = 1000 + + +def create(aName, aCopyRight): + print("Generating %s.woff..." % aName, end="") + mathFont = fontforge.font() + mathFont.fontname = aName + mathFont.familyname = aName + mathFont.fullname = aName + mathFont.copyright = aCopyRight + mathFont.encoding = "UnicodeFull" + + # Create a space character. Also force the creation of some MATH subtables + # so that OTS will not reject the MATH table. + g = mathFont.createChar(ord(" "), "space") + g.width = em + g.italicCorrection = 0 + g.topaccent = 0 + g.mathKern.bottomLeft = tuple([(0, 0)]) + g.mathKern.bottomRight = tuple([(0, 0)]) + g.mathKern.topLeft = tuple([(0, 0)]) + g.mathKern.topRight = tuple([(0, 0)]) + mathFont[ord(" ")].horizontalVariants = "space" + mathFont[ord(" ")].verticalVariants = "space" + return mathFont + + +def drawRectangleGlyph(glyph, width, ascent, descent=0, padding_left=0): + p = glyph.glyphPen() + p.moveTo(padding_left, -descent) + p.lineTo(padding_left, ascent) + p.lineTo(padding_left + width, ascent) + p.lineTo(padding_left + width, -descent) + p.closePath() + glyph.width = padding_left + width + + +def createSquareGlyph(aFont, aCodePoint): + g = aFont.createChar(aCodePoint) + drawRectangleGlyph(g, em, em, 0) + + +def drawHexaDigit(aGlyph, aX, aValue): + t = em / 10 + p = aGlyph.glyphPen(replace=False) + if aValue == 0: + p.moveTo(aX + t, t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.closePath() + elif aValue == 1: + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + elif aValue == 2: + p.moveTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + elif aValue == 3: + p.moveTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + t, t) + p.endPath() + p.moveTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 4: + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + p.moveTo(aX + t, em - t) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 5: + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + t, t) + p.endPath() + elif aValue == 6: + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + 2.5 * t, em / 2) + p.endPath() + elif aValue == 7: + p.moveTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + elif aValue == 8: + p.moveTo(aX + t, t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.closePath() + p.moveTo(aX + 2.5 * t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 9: + p.moveTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 10: # A + p.moveTo(aX + t, t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + p.moveTo(aX + 2.5 * t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 11: # b + p.moveTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + 2.5 * t, em / 2) + p.endPath() + elif aValue == 12: # C + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + elif aValue == 13: # d + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + em / 2 - t, t) + p.lineTo(aX + t, t) + p.lineTo(aX + t, em / 2) + p.lineTo(aX + em / 2 - 2.5 * t, em / 2) + p.endPath() + elif aValue == 14: # E + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.lineTo(aX + em / 2 - t, t) + p.endPath() + p.moveTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + 2.5 * t, em / 2) + p.endPath() + elif aValue == 15: # F + p.moveTo(aX + em / 2 - t, em - t) + p.lineTo(aX + t, em - t) + p.lineTo(aX + t, t) + p.endPath() + p.moveTo(aX + em / 2 - t, em / 2) + p.lineTo(aX + 2.5 * t, em / 2) + p.endPath() + + +def createGlyphFromValue(aFont, aCodePoint): + g = aFont.createChar(aCodePoint) + value = aCodePoint + for i in range(0, 5): + drawHexaDigit(g, (5 - (i + 1)) * em / 2, value % 16) + value /= 16 + g.width = 5 * em // 2 + g.stroke("circular", em / 10, "square", "miter", "cleanup") + + +def createSizeVariants(aFont, aUsePUA=False, aCenterOnBaseline=False): + if aUsePUA: + codePoint = PUA_startCodePoint + else: + codePoint = -1 + for size in (0, 1, 2, 3): + g = aFont.createChar(codePoint, "v%d" % size) + if aCenterOnBaseline: + drawRectangleGlyph(g, em, (size + 1) * em / 2, (size + 1) * em / 2) + else: + drawRectangleGlyph(g, em, (size + 1) * em, 0) + if aUsePUA: + codePoint += 1 + g = aFont.createChar(codePoint, "h%d" % size) + if aCenterOnBaseline: + drawRectangleGlyph(g, (size + 1) * em, em / 2, em / 2) + else: + drawRectangleGlyph(g, (size + 1) * em, em, 0) + if aUsePUA: + codePoint += 1 + + +def createStretchy(aFont, codePoint, isHorizontal): + if isHorizontal: + aFont[codePoint].horizontalVariants = "h0 h1 h2 h3" + # Part: (glyphName, isExtender, startConnector, endConnector, fullAdvance) + aFont[codePoint].horizontalComponents = \ + (("h2", False, 0, em, 3 * em), + ("h1", True, em, em, 2 * em)) + else: + aFont[codePoint].verticalVariants = "v0 v1 v2 v3" + # Part: (glyphName, isExtender, startConnector, endConnector, fullAdvance) + aFont[codePoint].verticalComponents = \ + (("v2", False, 0, em, 3 * em), + ("v1", True, em, em, 2 * em)) + + +def save(aFont): + aFont.em = em + aFont.ascent = aFont.hhea_ascent = aFont.os2_typoascent = em + aFont.descent = aFont.hhea_descent = aFont.os2_typodescent = 0 + # aFont.os2_winascent, aFont.os2_windescent should be the maximum of + # ascent/descent for all glyphs. Does fontforge compute them automatically? + aFont.hhea_ascent_add = aFont.hhea_descent_add = 0 + aFont.os2_typoascent_add = aFont.os2_typodescent_add = 0 + aFont.os2_winascent_add = aFont.os2_windescent_add = 0 + aFont.os2_use_typo_metrics = True + aFont.generate("../../fonts/math/%s.woff" % aFont.fontname) + if aFont.validate() == 0: + print(" done.") + else: + print(" validation error!") + exit(1) diff --git a/testing/web-platform/tests/mathml/tools/utils/misc.py b/testing/web-platform/tests/mathml/tools/utils/misc.py new file mode 100644 index 0000000000..cc3b21906e --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/utils/misc.py @@ -0,0 +1,35 @@ +import os +import progressbar +from urllib.request import urlopen + +UnicodeXMLURL = "https://raw.githubusercontent.com/w3c/xml-entities/gh-pages/unicode.xml" +InlineAxisOperatorsURL = "https://w3c.github.io/mathml-core/tables/inline-axis-operators.txt" + + +def downloadWithProgressBar(url, outputDirectory="./", forceDownload=False): + + baseName = os.path.basename(url) + fileName = os.path.join(outputDirectory, baseName) + + if not forceDownload and os.path.exists(fileName): + return fileName + + request = urlopen(url) + totalSize = int(request.info().get('Content-Length').strip()) + bar = progressbar.ProgressBar(maxval=totalSize).start() + + chunkSize = 16 * 1024 + downloaded = 0 + print("Downloading %s" % url) + os.umask(0o002) + with open(fileName, 'wb') as fp: + while True: + chunk = request.read(chunkSize) + downloaded += len(chunk) + bar.update(downloaded) + if not chunk: + break + fp.write(chunk) + bar.finish() + + return fileName diff --git a/testing/web-platform/tests/mathml/tools/xHeight.py b/testing/web-platform/tests/mathml/tools/xHeight.py new file mode 100755 index 0000000000..ad0f8b9e02 --- /dev/null +++ b/testing/web-platform/tests/mathml/tools/xHeight.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 + +from utils import mathfont +import fontforge + +v = mathfont.em / 2 +f = mathfont.create("xheight%d" % v, + "Copyright (c) 2016 MathML Association") +g = f.createChar(ord('x')) +mathfont.drawRectangleGlyph(g, mathfont.em, v, 0) +assert f.xHeight == v, "Bad x-height value!" +mathfont.save(f) |