diff options
Diffstat (limited to 'testing/web-platform/tests/mathml/presentation-markup')
267 files changed, 21472 insertions, 0 deletions
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..657d048211 --- /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"> <mstyle mathvariant="bold"> <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> </mstyle> </math> מודגשים גם הם</p> + + <p>שורשי משוואה מודגשת זו <math id="x2" dir="ltr"> <mstyle mathvariant="bold"> <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> </mstyle> </math> מודגשים גם הם</p> + + <p>שורשי משוואה מודגשת זו <math id="x3" dir="invalid"> <mstyle mathvariant="bold"> <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> </mstyle> </math> מודגשים גם הם</p> + + <p>שורשי משוואה מודגשת זו <math id="x4" dir="rtl"> <mstyle mathvariant="bold"> <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> </mstyle> </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-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/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/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/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> |