summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/mathml/relations
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /testing/web-platform/tests/mathml/relations
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/mathml/relations')
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-001.html111
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-002.html118
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/blur-filter-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/blur-filter.html21
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/clip-path-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/clip-path.html21
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/clip-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/clip.html21
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-001-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-001.html34
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-002-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-002.html29
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-003-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-003.html31
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative.html55
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-005-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/color-005.html88
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/default-font-family.html36
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-semantics-and-maction.html47
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-the-math-root.html57
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/display-1-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/display-1.html18
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/display-2.html139
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/display-contents.html36
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow-ref.html20
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow.html19
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011-ref.html155
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011.html168
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012-ref.html30
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012.html37
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013-ref.html58
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013.html80
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014-ref.html35
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014.html55
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015-ref.html58
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015.html83
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-1.html136
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-2.html208
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/displaystyle-3.html84
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1-ref.html75
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1.html105
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display.html20
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math-ref.html14
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math.html19
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/floats/not-floating-001.html74
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/ignored-properties-001.html79
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute-ref.html27
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute.html32
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute-ref.html27
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute.html32
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/lengths-1-ref.html14
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/lengths-1.html122
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/lengths-2.html266
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001-notref.html9
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001.html14
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002-notref.html9
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002.html14
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003-notref.html7
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003.html11
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004-notref.html9
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004.html14
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001-notref.html9
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001.html13
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002-notref.html9
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002.html14
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003-notref.html7
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003.html11
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004-notref.html9
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004.html14
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css-ref.html23
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css.html27
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html26
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords.html33
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values-ref.html16
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values.html23
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-ref.html19
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute.html22
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto-ref.html139
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto.html145
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight-ref.html44
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight.html49
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight-ref.html22
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight.html27
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/multi-column-layout.html56
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/not-participating-to-parent-layout.html77
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001-ref.html18
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001.html25
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/all-mathml-containers.html103
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001-ref.html28
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001.html35
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/overflow/computed-value-001.html45
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-001.html179
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-002.html72
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-001.html179
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-002.html86
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-003.html93
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-001.html179
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-002.html71
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001-ref.html17
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html22
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002-ref.html18
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002.html34
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003-ref.html18
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003.html33
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001-ref.html62
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001.html63
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002-ref.html59
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002.html84
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/scriptlevel-001.html219
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/transform-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/transform.html21
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-001-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-001.html34
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-002-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-002.html29
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-003-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-003.html31
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative.html55
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-005-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/visibility-005.html88
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/width-height-001.html62
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/width-height-002-ref.html162
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/width-height-002.html135
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/width-height-003-ref.html178
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/width-height-003.html150
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/width-height-004.html133
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/writing-mode/force-horizontal-tb.html50
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property.html20
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-001.html69
-rw-r--r--testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-002.html82
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/class-1-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/class-1.html24
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/class-2.html42
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html119
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1-ref.html26
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1.html38
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/content-editable.html51
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative-ref.html18
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative.html46
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-interface.tentative.html54
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/display-1.html175
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/display-2-ref.html31
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/display-2.html37
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1-ref.html16
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1.html30
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2-ref.html16
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2.html27
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-001.html630
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-002.html119
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/href-click-1-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/href-click-1.html36
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/href-click-2-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/href-click-2.html40
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/href-click-3.html38
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html111
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1.html25
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2.html72
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3-ref.html17
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3.html63
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/integration-point-4.html59
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/integration-point-5.html57
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/math-global-event-handlers.tentative.html155
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2.html23
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/tabindex-001.html58
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/tabindex-002.html71
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-1.html18
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-2.html15
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-ref.html16
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1.html19
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-2.html30
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3.html24
-rw-r--r--testing/web-platform/tests/mathml/relations/text-and-math/basic-mathematical-alphanumeric-symbols-with-default-font.html39
-rw-r--r--testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1-ref.html19
-rw-r--r--testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1.html51
182 files changed, 9826 insertions, 0 deletions
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-001.html b/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-001.html
new file mode 100644
index 0000000000..e423b16fd7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-001.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Attribute mapping</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<meta name="assert" content="Verify that dir, mathcolor, mathbackground and mathsize are mapped to CSS but that deprecated MathML3 attributes are not.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<style>
+ #container {
+ color: blue;
+ font-size: 50px;
+ }
+</style>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+ function runTests() {
+ var container = document.getElementById("container");
+ for (tag in MathMLFragments) {
+ container.insertAdjacentHTML("beforeend", `<math>${MathMLFragments[tag]}</math>`);
+ }
+ Array.from(document.getElementsByClassName("element")).forEach(element => {
+ var tag = element.tagName;
+ var style = window.getComputedStyle(element);
+
+ test(function() {
+ assert_equals(style.getPropertyValue("direction"), "ltr", "no attribute");
+ element.setAttribute("dir", "rtl");
+ assert_equals(style.getPropertyValue("direction"), "rtl", "attribute specified");
+ element.setAttribute("dir", "RtL");
+ assert_equals(style.getPropertyValue("direction"), "rtl", "case insensitive");
+ element.setAttribute("dir", "auto");
+ assert_equals(style.getPropertyValue("direction"), "ltr", "auto");
+ element.setAttribute("dir", "foo");
+ assert_equals(style.getPropertyValue("direction"), "ltr", "random value");
+ }, `dir on the ${tag} element is mapped to CSS direction`)
+
+ test(function() {
+ assert_equals(style.getPropertyValue("color"),
+ "rgb(0, 0, 255)",
+ "no attribute");
+ element.setAttribute("mathcolor", "black");
+ assert_equals(style.getPropertyValue("color"), "rgb(0, 0, 0)", "attribute specified");
+ // The color names are case-insensitive.
+ // See https://www.w3.org/TR/css-color-3/#html4
+ element.setAttribute("mathcolor", "GrEeN");
+ assert_equals(style.getPropertyValue("color"), "rgb(0, 128, 0)", "case insensitive");
+ }, `mathcolor on the ${tag} element is mapped to CSS color`);
+
+ test(function() {
+ assert_equals(style.getPropertyValue("background-color"),
+ tag === "merror" ?
+ "rgb(255, 255, 224)" : "rgba(0, 0, 0, 0)",
+ "no attribute");
+ element.setAttribute("mathbackground", "lightblue");
+ assert_equals(style.getPropertyValue("background-color"), "rgb(173, 216, 230)", "attribute specified");
+ // The color names are case-insensitive.
+ // See https://www.w3.org/TR/css-color-3/#html4
+ element.setAttribute("mathbackground", "YeLlOw");
+ assert_equals(style.getPropertyValue("background-color"), "rgb(255, 255, 0)", "case insensitive");
+ }, `mathbackground on the ${tag} element is mapped to CSS background-color`);
+
+ test(function() {
+ // "none" and "mprescripts" can only be used as non-first children of mmultiscripts so font-size
+ // is incremented and the resulting fraction string is hard to test accurately, skip for now.
+ if (tag === "none" || tag === "mprescripts")
+ return;
+ assert_equals(style.getPropertyValue("font-size"), "50px", "no attribute");
+ element.setAttribute("mathsize", "20px");
+ assert_equals(style.getPropertyValue("font-size"), "20px", "attribute specified");
+ // unit identifiers are ASCII case-insensitive.
+ // https://www.w3.org/TR/css-values-3/#typedef-dimension
+ element.setAttribute("mathsize", "30Px");
+ assert_equals(style.getPropertyValue("font-size"), "30px", "case insensitive");
+ }, `mathsize on the ${tag} element is mapped to CSS font-size`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mathsize(), "Superseding attributes are supported");
+ var properties = ["background-color", "color", "fontfamily", "font-size", "font-style", "font-weight"];
+ var oldStyle = {};
+ properties.forEach(property => {
+ oldStyle[property] = style.getPropertyValue(property);
+ });
+ element.setAttribute("background", "red");
+ element.setAttribute("color", "blue");
+ element.setAttribute("fontfamily", "monospace");
+ element.setAttribute("fontsize", "50px");
+ element.setAttribute("fontstyle", "italic");
+ element.setAttribute("fontweight", "bold");
+ properties.forEach(property => {
+ assert_equals(style.getPropertyValue(property), oldStyle[property], `${property}`);
+ });
+ }, `deprecated MathML3 attributes on the ${tag} element are not mapped to CSS`);
+ });
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="container">
+ <math class="element"></math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-002.html b/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-002.html
new file mode 100644
index 0000000000..baf136f358
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/attribute-mapping-002.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Attribute mapping</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+<meta name="assert" content="Verify that mathvariant, scriptlevel, displaystyle are mapped to CSS">
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ #container {
+ /* Ahem font does not have a MATH table so the font-size scale factor
+ is always 0.71^{computed - inherited math script level} */
+ font: 100px/1 Ahem;
+ }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+ function fontSize(style) {
+ return parseFloat((/(.+)px/).exec(style.getPropertyValue("font-size"))[1]);
+ }
+ function runTests() {
+ var container = document.getElementById("container");
+ for (tag in MathMLFragments) {
+ container.insertAdjacentHTML("beforeend", `<math><mrow>${MathMLFragments[tag]}</mrow></math>`);
+ }
+ Array.from(document.getElementsByClassName("element")).forEach(element => {
+ var tag = element.tagName;
+ var style = window.getComputedStyle(element);
+
+ test(function() {
+ assert_equals(style.getPropertyValue("text-transform"),
+ tag === "mi" ? "math-auto" : "none",
+ "no attribute");
+ element.parentNode.setAttribute("style", "text-transform: uppercase");
+ assert_equals(style.getPropertyValue("text-transform"),
+ tag === "mi" ? "math-auto" : "uppercase",
+ "text-transform on parent");
+ element.setAttribute("mathvariant", "normal");
+ assert_equals(style.getPropertyValue("text-transform"),
+ tag === "mi" ? "none" : "uppercase", "attribute specified");
+ element.setAttribute("mathvariant", "NoRmAl");
+ assert_equals(style.getPropertyValue("text-transform"),
+ tag === "mi" ? "none" : "uppercase", "case insensitive");
+ }, `mathvariant on the ${tag} element is ${tag === "mi" ? "" : "not"} mapped to CSS text-transform`)
+
+ test(function() {
+ // none and mprescripts appear as scripts
+ assert_equals(style.getPropertyValue("math-depth"), tag === "none" || tag === "mprescripts" ? "1" : "0", "no attribute");
+
+ var absoluteScriptlevel = 2;
+ element.setAttribute("scriptlevel", absoluteScriptlevel);
+ assert_equals(style.getPropertyValue("math-depth"), "" + absoluteScriptlevel, "attribute specified <U>");
+
+ var positiveScriptlevelDelta = 1;
+ element.setAttribute("scriptlevel", `+${positiveScriptlevelDelta}`);
+ assert_equals(style.getPropertyValue("math-depth"), "" + positiveScriptlevelDelta, "attribute specified +<U>");
+
+ var negativeScriptlevelDelta = -3;
+ element.setAttribute("scriptlevel", `${negativeScriptlevelDelta}`);
+ assert_equals(style.getPropertyValue("math-depth"), "" + negativeScriptlevelDelta, "attribute specified -<U>");
+
+ element.setAttribute("scriptlevel", absoluteScriptlevel);
+ element.setAttribute("mathsize", "42px");
+ assert_approx_equals(fontSize(style), 42, 1, "mathsize wins over scriptlevel");
+
+ }, `scriptlevel on the ${tag} element is mapped to math-depth(...)`);
+
+ test(function() {
+ // none and mprescripts appear as scripts
+ let expected = 0;
+ element.setAttribute("scriptlevel", "" + expected);
+ assert_equals(style.getPropertyValue("math-depth"), "" + expected, "no attribute");
+
+ element.setAttribute("scriptlevel", " +1");
+ assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value");
+
+ element.setAttribute("scriptlevel", " + 1");
+ assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value");
+
+ element.setAttribute("scriptlevel", "2.0");
+ assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value");
+
+ element.setAttribute("scriptlevel", "-3\"");
+ assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value");
+
+ element.setAttribute("scriptlevel", "200px");
+ assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value");
+
+ element.setAttribute("scriptlevel", "add(2)");
+ assert_equals(style.getPropertyValue("math-depth"), "" + expected, "invalid scriptlevel value");
+
+ }, `invalid scriptlevel values on the ${tag} element are not mapped to math-depth(...)`);
+
+ test(function() {
+ assert_equals(style.getPropertyValue("math-style"), "compact", "no attribute");
+ element.setAttribute("displaystyle", "true");
+ assert_equals(style.getPropertyValue("math-style"), "normal", "attribute specified");
+ element.setAttribute("displaystyle", "TrUe");
+ assert_equals(style.getPropertyValue("math-style"), "normal", "case insensitive");
+ }, `displaystyle on the ${tag} element is mapped to CSS math-style`);
+ });
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="container">
+ <div><math class="element"></math></div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/blur-filter-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/blur-filter-ref.html
new file mode 100644
index 0000000000..21fc165b7d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/blur-filter-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Blur filter (reference)</title>
+</head>
+<body>
+ <p>Rectangles should be blurred.</p>
+ <div style="background: green; filter: blur(5px); width: 200px; height: 200px;"></div>
+ <div style="background: green; filter: blur(5px); width: 200px; height: 200px; position: absolute; top: 300px"></div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/blur-filter.html b/testing/web-platform/tests/mathml/relations/css-styling/blur-filter.html
new file mode 100644
index 0000000000..92a894bf34
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/blur-filter.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Blur filter</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="blur-filter-ref.html"/>
+<meta name="assert" content="Verify that 'filter: blur' works on MathML elements.">
+</head>
+<body>
+ <p>Rectangles should be blurred.</p>
+ <div>
+ <math><mspace width="200px" height="200px" style="background: green; filter: blur(5px)"/></math>
+ </div>
+ <div style="position: absolute; top: 300px">
+ <math style="filter: blur(5px)"><mspace width="200px" height="200px" style="background: green"/></math>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/clip-path-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/clip-path-ref.html
new file mode 100644
index 0000000000..57935564bf
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/clip-path-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Clip property (reference)</title>
+</head>
+<body>
+ <p>Rectangles should be clipped to a polygon.</p>
+ <div style="background: green; width: 200px; height: 200px; clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)"></div>
+ <div style="background: green; width: 200px; height: 200px; position: absolute; top: 300px; clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)"></div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/clip-path.html b/testing/web-platform/tests/mathml/relations/css-styling/clip-path.html
new file mode 100644
index 0000000000..abe58e2261
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/clip-path.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Clip property</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="clip-path-ref.html"/>
+<meta name="assert" content="Verify that the clip property works on MathML elements.">
+</head>
+<body>
+ <p>Rectangles should be clipped to a polygon.</p>
+ <div>
+ <math><mspace width="200px" height="200px" style="background: green; clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)"/></math>
+ </div>
+ <div style="position: absolute; top: 300px; width: 200px; height: 200px">
+ <math style="position: absolute; clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 90%)"><mspace width="200px" height="200px" style="background: green"/></math>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/clip-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/clip-ref.html
new file mode 100644
index 0000000000..7882ac8c31
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/clip-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Clip property (reference)</title>
+</head>
+<body>
+ <p>Rectangles should be clipped.</p>
+ <div style="background: green; width: 200px; height: 200px; position: absolute; top: 100px; clip: rect(0px 100px 100px 0px)"></div>
+ <div style="background: green; width: 200px; height: 200px; position: absolute; top: 300px; clip: rect(0px 100px 100px 0px)"></div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/clip.html b/testing/web-platform/tests/mathml/relations/css-styling/clip.html
new file mode 100644
index 0000000000..48b7753fd8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/clip.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Clip property</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="clip-ref.html"/>
+<meta name="assert" content="Verify that the clip property works on MathML elements.">
+</head>
+<body>
+ <p>Rectangles should be clipped.</p>
+ <div>
+ <math><mspace width="200px" height="200px" style="position:absolute; top:100px; background: green; clip: rect(0px 100px 100px 0px)"/></math>
+ </div>
+ <div style="position: absolute; top: 300px; width: 200px; height: 200px">
+ <math style="position: absolute; clip: rect(0px 100px 100px 0px)"><mspace width="200px" height="200px" style="background: green"/></math>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-001-ref.html
new file mode 100644
index 0000000000..0efca480ee
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-001-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>color (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px; padding: 1px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-001.html b/testing/web-platform/tests/mathml/relations/css-styling/color-001.html
new file mode 100644
index 0000000000..76d65f579c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-001.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>color</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="match" href="color-001-ref.html"/>
+<meta name="assert" content="Verify that the color is used for the text of token elements.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px; padding: 1px;">
+ <math><mi style="color: green">1</mi></math>
+ <math><mn style="color: green">2</mn></math>
+ <math><mo style="color: green">3</mo></math>
+ <math><mtext style="color: green">4</mtext></math>
+ <math><ms style="color: green">5</ms></math>
+ <div id="dynamic">
+ <math><mi>1</mi></math>
+ <math><mn>2</mn></math>
+ <math><mo>3</mo></math>
+ <math><mtext>4</mtext></math>
+ <math><ms>5</ms></math>
+ </div>
+ </div>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("dynamic").style.color = "green";
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-002-ref.html
new file mode 100644
index 0000000000..0efca480ee
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-002-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>color (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px; padding: 1px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-002.html b/testing/web-platform/tests/mathml/relations/css-styling/color-002.html
new file mode 100644
index 0000000000..bce24f54c8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-002.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>color</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#fraction-with-nonzero-line-thickness">
+<link rel="match" href="color-002-ref.html"/>
+<meta name="assert" content="Verify that the color is used for text and fraction bar of the mfrac element.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px; padding: 1px;">
+ <math><mfrac style="color: green"><mn>1</mn><mn>2</mn></mfrac></math>
+ <div id="dynamic">
+ <math><mfrac><mn>1</mn><mn>2</mn></mfrac></math>
+ </div>
+ </div>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("dynamic").style.color = "green";
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-003-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-003-ref.html
new file mode 100644
index 0000000000..0efca480ee
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-003-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>color (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px; padding: 1px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-003.html b/testing/web-platform/tests/mathml/relations/css-styling/color-003.html
new file mode 100644
index 0000000000..dd04b61054
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-003.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>color</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#radical-symbol">
+<link rel="match" href="color-003-ref.html"/>
+<meta name="assert" content="Verify that the color is used for text and radical symbol of the msqrt and mroot elements.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px; padding: 1px;">
+ <math><msqrt style="color: green"><mn>1</mn></msqrt></math>
+ <math><mroot style="color: green"><mn>2</mn><mn>2</mn></mroot></math>
+ <div id="dynamic">
+ <math><msqrt><mn>1</mn></msqrt></math>
+ <math><mroot><mn>2</mn><mn>2</mn></mroot></math>
+ </div>
+ </div>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("dynamic").style.color = "green";
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_msqrt");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative-ref.html
new file mode 100644
index 0000000000..0efca480ee
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>color (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px; padding: 1px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative.html b/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative.html
new file mode 100644
index 0000000000..4bd15e62a0
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-004.tentative.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>color</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://github.com/mathml-refresh/mathml-core/pull/24">
+<link rel="match" href="color-004.tentative-ref.html"/>
+<meta name="assert" content="Verify that the color is used for text and graphical elements of the menclose element.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px; padding: 1px;">
+ <math><menclose notation="left" style="color: green"><mn>1</mn></menclose></math>
+ <math><menclose notation="right" style="color: green"><mn>2</mn></menclose></math>
+ <math><menclose notation="top" style="color: green"><mn>3</mn></menclose></math>
+ <math><menclose notation="bottom" style="color: green"><mn>4</mn></menclose></math>
+ <math><menclose notation="box" style="color: green"><mn>5</mn></menclose></math>
+ <math><menclose notation="roundedbox" style="color: green"><mn>6</mn></menclose></math>
+ <math><menclose notation="actuarial" style="color: green"><mn>7</mn></menclose></math>
+ <math><menclose notation="madruwb" style="color: green"><mn>8</mn></menclose></math>
+ <math><menclose notation="horizontalstrike" style="color: green"><mn>9</mn></menclose></math>
+ <math><menclose notation="verticalstrike" style="color: green"><mn>10</mn></menclose></math>
+ <math><menclose notation="updiagonalstrike" style="color: green"><mn>11</mn></menclose></math>
+ <math><menclose notation="downdiagonalstrike" style="color: green"><mn>12</mn></menclose></math>
+ <math><menclose notation="longdiv" style="color: green"><mn>13</mn></menclose></math>
+ <math><menclose notation="circle" style="color: green"><mn>14</mn></menclose></math>
+ <div id="dynamic">
+ <math><menclose notation="left"><mn>1</mn></menclose></math>
+ <math><menclose notation="right"><mn>2</mn></menclose></math>
+ <math><menclose notation="top"><mn>3</mn></menclose></math>
+ <math><menclose notation="bottom"><mn>4</mn></menclose></math>
+ <math><menclose notation="box"><mn>5</mn></menclose></math>
+ <math><menclose notation="roundedbox"><mn>6</mn></menclose></math>
+ <math><menclose notation="actuarial"><mn>7</mn></menclose></math>
+ <math><menclose notation="madruwb"><mn>8</mn></menclose></math>
+ <math><menclose notation="horizontalstrike"><mn>9</mn></menclose></math>
+ <math><menclose notation="verticalstrike"><mn>10</mn></menclose></math>
+ <math><menclose notation="updiagonalstrike"><mn>11</mn></menclose></math>
+ <math><menclose notation="downdiagonalstrike"><mn>12</mn></menclose></math>
+ <math><menclose notation="longdiv"><mn>13</mn></menclose></math>
+ <math><menclose notation="circle"><mn>14</mn></menclose></math>
+ </div>
+ </div>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("dynamic").style.color = "green";
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_menclose");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-005-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/color-005-ref.html
new file mode 100644
index 0000000000..0efca480ee
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-005-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>color (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px; padding: 1px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/color-005.html b/testing/web-platform/tests/mathml/relations/css-styling/color-005.html
new file mode 100644
index 0000000000..f2660c9e62
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/color-005.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>color</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="match" href="color-005-ref.html"/>
+<meta name="assert" content="Verify that the color is used for normal, stretchy and large operators.">
+<style>
+ math {
+ font: 20px/1 Ahem;
+ }
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ mo {
+ font-family: operators;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div id="square" style="background: green; color: red; width: 200px; height: 200px; padding: 1px;">
+ <math>
+ <!-- unstretched operators -->
+ <mo style="color: green">⥯</mo>
+ <mo style="color: green">+</mo>
+ <mo style="color: green">-</mo>
+ </math>
+ <math displaystyle="true">
+ <!-- large operator -->
+ <mo largeop="true" style="color: green">⥯</mo>
+ </math>
+ <math>
+ <mrow>
+ <!-- stretchy, small size -->
+ <mspace height="2em"/>
+ <mo style="color: green">⥯</mo>
+ </mrow>
+ </math>
+ <math>
+ <mrow>
+ <!-- stretchy, large size -->
+ <mspace height="4em"/>
+ <mo style="color: green">⥯</mo>
+ </mrow>
+ </math>
+ <div id="dynamic">
+ <math>
+ <!-- unstretched operators -->
+ <mo stretchy="false">⥯</mo>
+ <mo>+</mo>
+ <mo>-</mo>
+ </math>
+ <math displaystyle="true">
+ <!-- large operator -->
+ <mo largeop="true">⥯</mo>
+ </math>
+ <math>
+ <mrow>
+ <!-- stretchy, small size -->
+ <mspace height="2em"/>
+ <mo>⥯</mo>
+ </mrow>
+ </math>
+ <math>
+ <mrow>
+ <!-- stretchy, large size -->
+ <mspace height="4em"/>
+ <mo>⥯</mo>
+ </mrow>
+ </math>
+ </div>
+ </div>
+ <script src="/mathml/support/fonts.js"></script>
+ <script>
+ window.addEventListener("load", () => loadAllFonts().then(() => {
+ document.getElementById("dynamic").style.color = "green";
+ document.documentElement.classList.remove("reftest-wait");
+ }));
+ </script>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/default-font-family.html b/testing/web-platform/tests/mathml/relations/css-styling/default-font-family.html
new file mode 100644
index 0000000000..c471b0fc9d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/default-font-family.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Default font-family on the &lt;math&gt; root</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element">
+<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet">
+<meta name="assert" content="Verify that the default font-family is 'math'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <div style="font-family: BB2F7F3E9FEE11EA96DF67A737751C2F;">
+ <div id="inherited-reference"></div>
+ <math id="math-not-inherited"></math>
+ </div>
+ <math id="math-default"></math>
+
+ <script>
+ function getFontFamily(id) {
+ return window.getComputedStyle(document.getElementById(id)).fontFamily;
+ }
+
+ test(function () {
+ assert_equals(getFontFamily("inherited-reference"), "BB2F7F3E9FEE11EA96DF67A737751C2F");
+ assert_not_equals(getFontFamily("math-not-inherited"), getFontFamily("inherited-reference"));
+ }, "Default font-family on <math> is not inherited");
+
+ test(function () {
+ assert_equals(getFontFamily("math-not-inherited"), "math");
+ assert_equals(getFontFamily("math-default"), "math");
+ }, "Default font-family on <math> is 'math'");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-semantics-and-maction.html b/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-semantics-and-maction.html
new file mode 100644
index 0000000000..23f8b62dfa
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-semantics-and-maction.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Default properties on &lt;semantics&gt; and &lt;maction&gt;</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#semantics-and-presentation">
+<link rel="help" href="https://w3c.github.io/mathml-core/#enlivening-expressions">
+<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet">
+<meta name="assert" content="Test that only the first children of semantics/maction are displayed.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <div>
+ <math>
+ <semantics>
+ <mn>1</mn>
+ <mn>2</mn>
+ <mn>3</mn>
+ <mn>4</mn>
+ <mn>5</mn>
+ </semantics>
+ <maction>
+ <mn>1</mn>
+ <mn>2</mn>
+ <mn>3</mn>
+ <mn>4</mn>
+ <mn>5</mn>
+ </maction>
+ </math>
+ </div>
+
+ <script>
+ ["semantics", "maction"].forEach(name => {
+ let element = document.getElementsByTagName(name)[0];
+ test(() => {
+ let child = element.firstElementChild;
+ assert_not_equals(window.getComputedStyle(child).display, "none", `Child ${child.innerText} does not have display: none`);
+ for (child = child.nextElementSibling; child; child = child.nextElementSibling) {
+ assert_equals(window.getComputedStyle(child).display, "none", `Child ${child.innerText} has display: none`);
+ }
+ }, `Display value of children of the <${name}> element`);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-the-math-root.html b/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-the-math-root.html
new file mode 100644
index 0000000000..c329935f2e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/default-properties-on-the-math-root.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Default properties on the &lt;math&gt; root</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element">
+<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet">
+<meta name="assert" content="Test properties on the math root set by the UA stylesheet.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ math {
+ font-size: 100px;
+ }
+ .styled {
+ direction: rtl;
+ writing-mode: vertical-lr;
+ text-indent: .5em;
+ letter-spacing: .5em;
+ line-height: .5em;
+ word-spacing: .5em;
+ font-style: italic;
+ font-weight: bold;
+ }
+</style>
+
+</head>
+<body>
+ <div id="log"></div>
+ <div class="styled">
+ <math id="ua"></math>
+ <math id="author" class="styled"></math>
+ </div>
+
+ <script>
+ function getProperty(id, property) {
+ return window.getComputedStyle(document.getElementById(id))[property];
+ }
+ [
+ // Property name, value when specified from the UA, from the author.
+ ["direction", "ltr", "rtl"],
+ ["writing-mode", "horizontal-tb", "horizontal-tb"], // MathML Core level 1 only supports horizontal mode.
+ ["text-indent", "0px", "50px"],
+ ["letter-spacing", "normal", "50px"],
+ ["line-height", "normal", "50px"],
+ ["word-spacing", "0px", "50px"],
+ ["font-style", "normal", "italic"],
+ ["font-weight", "400", "700"]
+ ].forEach(([name, ua_value, author_value]) => {
+ test(function () {
+ assert_equals(getProperty("ua", name), ua_value, "when specified from the UA sheet");
+ assert_equals(getProperty("author", name), author_value, "when specified by the author");
+ }, `Value of ${name} on the <math> root`);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-1-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/display-1-ref.html
new file mode 100644
index 0000000000..ce65aba18c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/display-1-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>display (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-1.html b/testing/web-platform/tests/mathml/relations/css-styling/display-1.html
new file mode 100644
index 0000000000..5a9e4db687
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/display-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>display</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="display-1-ref.html"/>
+<meta name="assert" content="Verify that the 'display: none' property works on MathML elements.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px;">
+ <math style="display: none;"><mspace width="200px" height="200px" style="background: red"/></math>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-2.html b/testing/web-platform/tests/mathml/relations/css-styling/display-2.html
new file mode 100644
index 0000000000..36a02952eb
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/display-2.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Verify that one can override the layout of MathML elements with the CSS display property</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that one can override the display of a MathML element.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ math {
+ font-family: inherit;
+ }
+ mfrac {
+ padding: 0;
+ }
+</style>
+<script>
+ const Xsize = 25;
+ const templates = {
+ "block display": `<math style="display: block;">XXX</math>`,
+ "block display with contrained width": `<math style="display: block; width: ${2*Xsize}px;">XXX</math>`,
+ "list display inside display block": `<math style="display: block">\
+ <mmultiscripts style="display: list-item;">X</mmultiscripts>\
+ <maction style="display: list-item;">X</maction>\
+ <mpadded style="display: list-item;">X</mpadded>\
+</math>`,
+ "inline display": `<math style="display: inline;">XXX</math>`,
+ "inline-block display": `<math style="display: inline-block">XXX</math>`,
+ "table display (math)": `<math style="display: table">\
+ <mfrac style='display: table-row'>\
+ <msub style='display: table-cell'>X</msub>\
+ <msup style='display: table-cell'>X</msup>\
+ <msubsup style='display: table-cell'>X</msubsup>\
+ </mfrac>\
+ <mtable style='display: table-row'>\
+ <munder style='display: table-cell'>X</munder>\
+ <mover style='display: table-cell'>X</mover>\
+ <munderover style='display: table-cell'>X</munderover>\
+ </mtable>\
+</math>`,
+ "table display (mrow)": `<math display="block">\
+<mrow style="display: table">\
+ <mfrac style='display: table-row'>\
+ <msub style='display: table-cell'>X</msub>\
+ <msup style='display: table-cell'>X</msup>\
+ <msubsup style='display: table-cell'>X</msubsup>\
+ </mfrac>\
+ <mtable style='display: table-row'>\
+ <munder style='display: table-cell'>X</munder>\
+ <mover style='display: table-cell'>X</mover>\
+ <munderover style='display: table-cell'>X</munderover>\
+ </mtable>\
+</mrow></math>`,
+ "inline-table display (math)": `<math style="display: inline-table">\
+ <mfrac style='display: table-row'>\
+ <msub style='display: table-cell'>X</msub>\
+ <msup style='display: table-cell'>X</msup>\
+ <msubsup style='display: table-cell'>X</msubsup>\
+ </mfrac>\
+ <mtable style='display: table-row'>\
+ <munder style='display: table-cell'>X</munder>\
+ <mover style='display: table-cell'>X</mover>\
+ <munderover style='display: table-cell'>X</munderover>\
+ </mtable>\
+</math>`,
+ "inline-table display (mrow)": `<math display="block">\
+<mrow style="display: inline-table">\
+ <mfrac style='display: table-row'>\
+ <msub style='display: table-cell'>X</msub>\
+ <msup style='display: table-cell'>X</msup>\
+ <msubsup style='display: table-cell'>X</msubsup>\
+ </mfrac>\
+ <mtable style='display: table-row'>\
+ <munder style='display: table-cell'>X</munder>\
+ <mover style='display: table-cell'>X</mover>\
+ <munderover style='display: table-cell'>X</munderover>\
+ </mtable>\
+</mrow></math>`,
+ "flexbox display (math)": `<math style="display: flex; flex-direction: column;">XXX</math>`,
+ "flexbox display (mrow)": `<math display="block"><mrow style="display: flex; flex-direction: column;">XXX</mrow></math>`,
+ "grid display (math)": `<math style="display: grid; grid-gap: 2px; grid-template-columns: ${Xsize}px ${Xsize}px ${Xsize}px;>">XXXXXXXXX</math>`,
+ "grid display (mrow)": `<math display="block"><mrow style="display: grid; grid-gap: 2px; grid-template-columns: ${Xsize}px ${Xsize}px ${Xsize}px;>">XXXXXXXXX</mrow></math>`,
+ "ruby display (math)": `<math style="display: ruby;">\
+<mrow style="display: ruby-base;">X</mrow>\
+<mrow style="display: ruby-text">XX</mrow>\
+</math>`,
+ "ruby display (mrow)": `<math display="block"><mrow style="display: ruby;">\
+<mrow style="display: ruby-base;">X</mrow>\
+<mrow style="display: ruby-text">XX</mrow>\
+</mrow></math>`,
+ "block display with column width (math)": `<math style="display: block; column-width: ${2*Xsize}px">\
+ <mrow>XXXX</mrow><mrow>XXXX</mrow><mrow>XXXX</mrow>\
+</math>`,
+ "block display with column width (mrow)": `<math style="display: block"><mrow style="display: block; column-width: ${2*Xsize}px">\
+ <mrow>XXXX</mrow><mrow>XXXX</mrow><mrow>XXXX</mrow>\
+</mrow></math>`,
+ };
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+
+ for (let key in templates) {
+ if (!templates.hasOwnProperty(key))
+ continue;
+ let mathtest = templates[key].
+ replace(/X/g, `<mspace style="display: inline-block; width: ${Xsize}px; height: ${Xsize}px; background: black"></mspace>`);
+ let reference = mathtest.
+ replace(/maction|math|mfrac|mmultiscripts|mover|mover|mpadded|mrow|mspace|msubsup|msub|msup|mtable|munderover|munder/g, "div");
+ document.body.insertAdjacentHTML("beforeend", `<div style="font: 20px/1 Ahem; position: absolute;">\
+<div><span>${key}:</span>${mathtest}</div>\
+<div><span>${key}:</span>${reference}</div>\
+</div>`);
+ let div = document.body.lastElementChild;
+ let elementDiv = div.firstElementChild;
+ let referenceDiv = div.lastElementChild;
+
+ test(function() {
+ const epsilon = 1;
+ compareLayout(elementDiv, referenceDiv, epsilon);
+ }, `${key}`);
+
+ div.style = "display: none;"; // Hide the div after measurement.
+ }
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-contents.html b/testing/web-platform/tests/mathml/relations/css-styling/display-contents.html
new file mode 100644
index 0000000000..b18fdd6c8b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/display-contents.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>display: contents</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<meta name="assert" content="Verify that display: contents computes to display: none">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+ function runTests() {
+ var container = document.getElementById("container");
+ for (tag in MathMLFragments) {
+ container.insertAdjacentHTML("beforeend", `<math>${MathMLFragments[tag]}</math>`);
+ }
+ test(function() {
+ Array.from(document.getElementsByClassName("element")).forEach(element => {
+ var style = window.getComputedStyle(element);
+ element.setAttribute("style", "display: contents");
+ assert_equals(style.getPropertyValue("display"), "none", `${tag}`);
+ });
+ }, "display: contents computes to display: none");
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="container">
+ <math class="element"></math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow-ref.html
new file mode 100644
index 0000000000..b359414dc2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 20px;
+ padding: 5px;
+ font-size: 40px;
+ overflow-x: scroll;
+ overflow-y: hidden;
+}
+</style>
+<div>
+ <math display="block" style="width: min-content;">
+ <mn>text</mn>
+ </math>
+</div>
+<div style="direction: rtl;">
+ <math display="block" style="width: min-content;">
+ <mn>text</mn>
+ </math>
+</div>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow.html b/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow.html
new file mode 100644
index 0000000000..33df26c3ee
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/display-with-overflow.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1416539">
+<link rel="match" href="display-with-overflow-ref.html">
+<meta name="assert" content="Use safe centering (so that content is reachable with scroll) for display=block centering.">
+<style>
+math {
+ width: 20px;
+ padding: 5px;
+ font-size: 40px;
+ overflow-x: scroll;
+ overflow-y: hidden;
+}
+</style>
+<math display="block">
+ <mn>text</mn>
+</math>
+<math display="block" style="direction: rtl;">
+ <mn>text</mn>
+</math>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011-ref.html
new file mode 100644
index 0000000000..400c46a245
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011-ref.html
@@ -0,0 +1,155 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>displaystyle</title>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="/fonts/ahem.css">
+ <style>
+ math {
+ font: 25px Ahem;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- Test displaystyle on mstyle -->
+ <math>
+ <mstyle displaystyle="true">
+ <munder><mo>O</mo><mo>O</mo></munder>
+ </mstyle>
+ <mstyle displaystyle="false">
+ <msub><mo>O</mo><mo>O</mo></munder>
+ </mstyle>
+ </math>
+
+ <!-- The mfrac element sets displaystyle to "false", or if it was already
+ false increments scriptlevel by 1, within numerator and denominator.
+ -->
+ <math>
+ <mstyle displaystyle="true">
+ <mfrac>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </mfrac>
+ </mstyle>
+ </math>
+
+ <!-- The mroot element increments scriptlevel by 2, and sets
+ displaystyle to "false", within index, but leaves both attributes
+ unchanged within base.
+ The msqrt element leaves both attributes unchanged within its
+ argument. -->
+ <math>
+ <mstyle displaystyle="true">
+ <mroot>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </mroot>
+ <msqrt>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ </msqrt>
+ </mstyle>
+ </math>
+
+<!--
+ The msub element [...] increments scriptlevel by 1, and sets displaystyle to
+ "false", within subscript, but leaves both attributes unchanged within base.
+
+ The msup element [...] increments scriptlevel by 1, and sets displaystyle to
+ "false", within superscript, but leaves both attributes unchanged within
+ base.
+
+ The msubsup element [...] increments scriptlevel by 1, and sets displaystyle
+ to "false", within subscript and superscript, but leaves both attributes
+ unchanged within base.
+
+ The mmultiscripts element increments scriptlevel by 1, and sets displaystyle
+ to "false", within each of its arguments except base, but leaves both
+ attributes unchanged within base.
+ -->
+ <math>
+ <mstyle displaystyle="true">
+ <msub>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </msub>
+ <msup>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </msup>
+ <msubsup>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </msubsup>
+ <mmultiscripts>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <mprescripts/>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </mmultiscripts>
+ </mstyle>
+ </math>
+
+<!--
+ The munder element [...] always sets displaystyle to "false" within the
+ underscript, but increments scriptlevel by 1 only when accentunder is
+ "false". Within base, it always leaves both attributes unchanged.
+
+ The mover element [...] always sets displaystyle to "false" within
+ overscript, but increments scriptlevel by 1 only when accent is "false".
+ Within base, it always leaves both attributes unchanged.
+
+ The munderover [..] always sets displaystyle to "false" within underscript
+ and overscript, but increments scriptlevel by 1 only when accentunder or
+ accent, respectively, are "false". Within base, it always leaves both
+ attributes unchanged.
+-->
+ <math>
+ <mstyle displaystyle="true">
+ <munder>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </munder>
+ <mover>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </mover>
+ <munderover>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </munderover>
+ </mstyle>
+ </math>
+
+<!--
+ The displaystyle attribute is allowed on the mtable element to set the
+ inherited value of the attribute. If the attribute is not present, the
+ mtable element sets displaystyle to "false" within the table elements.
+-->
+ <math>
+ <mstyle displaystyle="false">
+ <mtable displaystyle="true">
+ <mtr>
+ <mtd>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ </mtd>
+ </mtr>
+ </mtable>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mtable>
+ <mtr>
+ <mtd>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ </mtd>
+ </mtr>
+ </mtable>
+ </mstyle>
+ </math>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011.html
new file mode 100644
index 0000000000..a0bfc29ae5
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-011.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>displaystyle</title>
+ <meta charset="utf-8">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="match" href="displaystyle-011-ref.html"/>
+ <meta name="assert" content="Test the effect on displaystyle and movablelimits">
+ <link rel="stylesheet" href="/fonts/ahem.css">
+ <style>
+ math {
+ font: 25px Ahem;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- Test displaystyle on mstyle -->
+ <math>
+ <mstyle displaystyle="true">
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </mstyle>
+ <mstyle displaystyle="false">
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </mstyle>
+ </math>
+
+ <!-- The mfrac element sets displaystyle to "false", or if it was already
+ false increments scriptlevel by 1, within numerator and denominator.
+ -->
+ <math>
+ <mstyle displaystyle="true">
+ <mfrac>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </mfrac>
+ </mstyle>
+ </math>
+
+ <!-- The mroot element increments scriptlevel by 2, and sets
+ displaystyle to "false", within index, but leaves both attributes
+ unchanged within base.
+ The msqrt element leaves both attributes unchanged within its
+ argument. -->
+ <math>
+ <mstyle displaystyle="true">
+ <mroot>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </mroot>
+ <msqrt>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </msqrt>
+ </mstyle>
+ </math>
+
+<!--
+ The msub element [...] increments scriptlevel by 1, and sets displaystyle to
+ "false", within subscript, but leaves both attributes unchanged within base.
+
+ The msup element [...] increments scriptlevel by 1, and sets displaystyle to
+ "false", within superscript, but leaves both attributes unchanged within
+ base.
+
+ The msubsup element [...] increments scriptlevel by 1, and sets displaystyle
+ to "false", within subscript and superscript, but leaves both attributes
+ unchanged within base.
+
+ The mmultiscripts element increments scriptlevel by 1, and sets displaystyle
+ to "false", within each of its arguments except base, but leaves both
+ attributes unchanged within base.
+ -->
+ <math>
+ <mstyle displaystyle="true">
+ <msub>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </msub>
+ <msup>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </msup>
+ <msubsup>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </msubsup>
+ <mmultiscripts>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mprescripts/>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </mmultiscripts>
+ </mstyle>
+ </math>
+
+<!--
+ The munder element [...] always sets displaystyle to "false" within the
+ underscript, but increments scriptlevel by 1 only when accentunder is
+ "false". Within base, it always leaves both attributes unchanged.
+
+ The mover element [...] always sets displaystyle to "false" within
+ overscript, but increments scriptlevel by 1 only when accent is "false".
+ Within base, it always leaves both attributes unchanged.
+
+ The munderover [..] always sets displaystyle to "false" within underscript
+ and overscript, but increments scriptlevel by 1 only when accentunder or
+ accent, respectively, are "false". Within base, it always leaves both
+ attributes unchanged.
+-->
+ <math>
+ <mstyle displaystyle="true">
+ <munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </munder>
+ <mover>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </mover>
+ <munderover>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </munderover>
+ </mstyle>
+ </math>
+
+<!--
+ The displaystyle attribute is allowed on the mtable element to set the
+ inherited value of the attribute. If the attribute is not present, the
+ mtable element sets displaystyle to "false" within the table elements.
+-->
+ <math>
+ <mstyle displaystyle="false">
+ <mtable displaystyle="true">
+ <mtr>
+ <mtd>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </mtd>
+ </mtr>
+ </mtable>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mtable>
+ <mtr>
+ <mtd>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ </mtd>
+ </mtr>
+ </mtable>
+ </mstyle>
+ </math>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012-ref.html
new file mode 100644
index 0000000000..96042b696f
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>displaystyle</title>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="/fonts/ahem.css">
+ <style>
+ math {
+ font: 25px Ahem;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- Test the effect of displaystyle on munder, mover and munderover -->
+ <math>
+ <mstyle displaystyle="true">
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <mover><mo>O</mo><mo>O</mo></mover>
+ <munderover><mo>O</mo><mo>O</mo><mo>O</mo></munderover>
+ </mstyle>
+ <mstyle displaystyle="false">
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <msup><mo>O</mo><mo>O</mo></msup>
+ <msubsup><mo>O</mo><mo>O</mo><mo>O</mo></msubsup>
+ </mstyle>
+ </math>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012.html
new file mode 100644
index 0000000000..9fd4c784dd
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-012.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>displaystyle</title>
+ <meta charset="utf-8">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="match" href="displaystyle-012-ref.html"/>
+ <meta name="assert" content="Test the effect on displaystyle on munder, mover and munderover">
+ <link rel="stylesheet" href="/fonts/ahem.css">
+ <style>
+ math {
+ font: 25px Ahem;
+ }
+ </style>
+ </head>
+ <body>
+
+ <math>
+ <mstyle displaystyle="true">
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mover><mo movablelimits="true">O</mo><mo>O</mo></mover>
+ <munderover><mo movablelimits="true">O</mo><mo>O</mo><mo>O</mo></munderover>
+ </mstyle>
+ <mstyle displaystyle="false">
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mover><mo movablelimits="true">O</mo><mo>O</mo></mover>
+ <munderover><mo movablelimits="true">O</mo><mo>O</mo><mo>O</mo></munderover>
+ </mstyle>
+ </math>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013-ref.html
new file mode 100644
index 0000000000..9a580350de
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>displaystyle</title>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="/fonts/ahem.css">
+ <style>
+ math {
+ font: 25px Ahem;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- Test dynamic change of displaystyle -->
+ <math id="m1" displaystyle="true">
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </math>
+ <math>
+ <mstyle id="m2" displaystyle="true">
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </mstyle>
+ </math>
+ <math>
+ <mtable id="m3" displaystyle="true">
+ <mtr>
+ <mtd>
+ <munder><mo>O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </mtd>
+ </mtr>
+ </mtable>
+ </math>
+ <math id="m4" displaystyle="false">
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </math>
+ <math>
+ <mstyle id="m5" displaystyle="false">
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </mstyle>
+ </math>
+ <math>
+ <mtable id="m6" displaystyle="false">
+ <mtr>
+ <mtd>
+ <msub><mo>O</mo><mo>O</mo></msub>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </mtd>
+ </mtr>
+ </mtable>
+ </math>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013.html
new file mode 100644
index 0000000000..3ce9fff062
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-013.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <title>displaystyle</title>
+ <meta charset="utf-8">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#table-or-matrix-mtable">
+ <link rel="match" href="displaystyle-013-ref.html"/>
+ <meta name="assert" content="Test dynamic change of displaystyle">
+ <script src="/mathml/support/fonts.js"></script>
+ <script type="text/javascript">
+ function doTest() {
+ document.body.offsetTop; // Update layout
+ document.getElementById("m1").setAttribute("displaystyle", "true");
+ document.getElementById("m2").setAttribute("displaystyle", "true");
+ document.getElementById("m3").setAttribute("displaystyle", "true");
+ document.getElementById("m4").removeAttribute("displaystyle");
+ document.getElementById("m5").removeAttribute("displaystyle");
+ document.getElementById("m6").removeAttribute("displaystyle");
+ document.documentElement.removeAttribute("class");
+ }
+ window.addEventListener("load", () => { loadAllFonts().then(doTest); });
+ </script>
+ <link rel="stylesheet" href="/fonts/ahem.css">
+ <style>
+ math {
+ font: 25px Ahem;
+ }
+ </style>
+ </head>
+ <body>
+
+ <math id="m1">
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </math>
+ <math>
+ <mstyle id="m2">
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </mstyle>
+ </math>
+ <math>
+ <mtable id="m3">
+ <mtr>
+ <mtd>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </mtd>
+ </mtr>
+ </mtable>
+ </math>
+ <math id="m4" displaystyle="true">
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </math>
+ <math>
+ <mstyle id="m5" displaystyle="true">
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </mstyle>
+ </math>
+ <math>
+ <mtable id="m6" displaystyle="true">
+ <mtr>
+ <mtd>
+ <munder><mo movablelimits="true">O</mo><mo>O</mo></munder>
+ <mfrac><mn>1</mn><mn>2</mn></mfrac>
+ </mtd>
+ </mtr>
+ </mtable>
+ </math>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014-ref.html
new file mode 100644
index 0000000000..085e2c429d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>displaystyle</title>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="/fonts/ahem.css">
+ <style>
+ math {
+ font: 25px Ahem;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- See https://bugzilla.mozilla.org/show_bug.cgi?id=832800 -->
+ <math>
+ <mstyle displaystyle="true">
+ <mfrac>
+ <mrow>
+ <mn>X</mn>
+ <mo id="mathOperator" mathbackground="red">+</mo>
+ <mfrac>
+ <mrow><mn>X</mn></mrow>
+ <mrow><mn>X</mn></mrow>
+ </mfrac>
+ </mrow>
+ <mrow>
+ <mn>X</mn>
+ </mrow>
+ </mfrac>
+ </mstyle>
+ </math>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014.html
new file mode 100644
index 0000000000..a4f1208e35
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-014.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <title>displaystyle</title>
+ <meta charset="utf-8">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac">
+ <link rel="match" href="displaystyle-014-ref.html"/>
+ <meta name="assert" content="Test dynamic change of mathbackground on an operator does not interfer with its displaystyle">
+ <script src="/mathml/support/fonts.js"></script>
+ <script type="text/javascript">
+ function doTest() {
+ document.body.offsetTop; // Update layout
+ document.getElementById('mathOperator').
+ setAttribute('mathbackground', 'red');
+ document.documentElement.removeAttribute("class");
+ }
+ window.addEventListener("load", () => { loadAllFonts().then(doTest); });
+ </script>
+ <link rel="stylesheet" href="/fonts/ahem.css">
+ <style>
+ math {
+ font: 25px Ahem;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- See https://bugzilla.mozilla.org/show_bug.cgi?id=832800 -->
+ <math>
+ <mstyle displaystyle="true">
+ <mfrac>
+ <mrow>
+ <mn>X</mn>
+ <mo id="mathOperator">+</mo>
+ <mfrac>
+ <mrow><mn>X</mn></mrow>
+ <mrow><mn>X</mn></mrow>
+ </mfrac>
+ </mrow>
+ <mrow>
+ <mn>X</mn>
+ </mrow>
+ </mfrac>
+ </mstyle>
+ </math>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015-ref.html
new file mode 100644
index 0000000000..2e375c6886
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>displaystyle and display</title>
+ </head>
+ <body>
+ <math>
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </math>
+ <math displaystyle="true">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </math>
+ <math display="inline" displaystyle="true">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </math>
+ <math display="block" displaystyle="true">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </math>
+ <math displaystyle="false">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </math>
+ <math display="inline" displaystyle="false">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </math>
+ <math display="block" displaystyle="false">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015.html
new file mode 100644
index 0000000000..e4a747fb20
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-015.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>displaystyle and display</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+ <link rel="match" href="displaystyle-015-ref.html"/>
+ <meta name="assert" content="Test interaction of math@display and displaystyle on an operator with movablelimits">
+ </head>
+ <body>
+ <math>
+ <mstyle displaystyle="false">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </mstyle>
+ </math>
+ <math>
+ <mstyle displaystyle="true">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </mstyle>
+ </math>
+ <math display="inline">
+ <mstyle displaystyle="true">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </mstyle>
+ </math>
+ <math display="block">
+ <mstyle displaystyle="true">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </mstyle>
+ </math>
+ <math>
+ <mstyle displaystyle="false">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </mstyle>
+ </math>
+ <math display="inline">
+ <mstyle displaystyle="false">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </mstyle>
+ </math>
+ <math display="block">
+ <mstyle displaystyle="false">
+ <munderover>
+ <mo>∑</mo>
+ <mi>b</mi>
+ <mi>c</mi>
+ </munderover>
+ </mstyle>
+ </math>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-1.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-1.html
new file mode 100644
index 0000000000..26aed81d03
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-1.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>displaystyle</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-math-style-property">
+<meta name="assert" content="Verify that the correct inheritance of the displaystyle value by measuring the size of large operators.">
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/largeop-displayoperatorminheight5000.woff");
+ }
+ math {
+ font-family: TestFont;
+ font-size: 10px;
+ }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/attribute-values.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script>
+ setup({ explicit_done: true });
+ var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000
+ var epsilon = 5;
+ function verify_displaystyle(elementId, displaystyle, description) {
+ var expectedSize = (displaystyle ? 5000 : 1000) * emToPx;
+ var elementSize = document.getElementById(elementId).
+ getBoundingClientRect().height;
+ assert_approx_equals(elementSize, expectedSize, epsilon, description);
+ }
+
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+ for (transform in AttributeValueTransforms) {
+ TransformAttributeValues(transform, ["display", "displaystyle"]);
+ test(function() {
+ verify_displaystyle("math_default", false, "default");
+ verify_displaystyle("math_false", false, "explicit displaystyle false");
+ verify_displaystyle("math_true", true, "explicit displaystyle true");
+ }, `math element (${transform})`);
+ test(function() {
+ verify_displaystyle("math_inline", false, "explicit display inline");
+ verify_displaystyle("math_block", true, "explicit display block");
+ verify_displaystyle("math_block_false", false, "explicit display block and displaystyle false");
+ verify_displaystyle("math_block_true", true, "explicit display block and displaystyle true");
+ verify_displaystyle("math_inline_false", false, "explicit display inline and displaystyle false");
+ verify_displaystyle("math_inline_true", true, "explicit display inline and displaystyle true");
+ }, `math element (explicit display, ${transform})`);
+ test(function() {
+ verify_displaystyle("mstyle_false", false, "explicit displaystyle false");
+ verify_displaystyle("mstyle_true", true, "explicit displaystyle true");
+ }, `mstyle element (${transform})`);
+ test(function() {
+ verify_displaystyle("mtable_default", false, "default");
+ verify_displaystyle("mtable_false", false, "explicit displaystyle false");
+ verify_displaystyle("mtable_true", true, "explicit displaystyle true");
+ }, `mtable element (${transform})`);
+ test(function() {
+ verify_displaystyle("mfrac_sibling", true, "sibling");
+ verify_displaystyle("mfrac_numerator", false, "numerator");
+ verify_displaystyle("mfrac_denominator", false, "denominator");
+ }, `mfrac element (${transform})`);
+ test(function() {
+ verify_displaystyle("mroot_base", true, "base");
+ verify_displaystyle("mroot_index", false, "index");
+ }, `mroot element (${transform})`);
+ test(function() {
+ verify_displaystyle("msub_base", true, "base");
+ verify_displaystyle("msub_subscript", false, "subscript");
+ }, `msub element (${transform})`);
+ test(function() {
+ verify_displaystyle("msup_base", true, "base");
+ verify_displaystyle("msup_supscript", false, "supscript");
+ }, `msup element (${transform})`);
+ test(function() {
+ verify_displaystyle("msubsup_base", true, "base");
+ verify_displaystyle("msubsup_subscript", false, "subscript");
+ verify_displaystyle("msubsup_supscript", false, "supscript");
+ }, `msubsup element (${transform})`);
+ test(function() {
+ verify_displaystyle("munder_base", true, "base");
+ verify_displaystyle("munder_underscript", false, "underscript");
+ }, `munder element (${transform})`);
+ test(function() {
+ verify_displaystyle("mover_base", true, "base");
+ verify_displaystyle("mover_overscript", false, "overscript");
+ }, `mover element (${transform})`);
+ test(function() {
+ verify_displaystyle("munderover_base", true, "base");
+ verify_displaystyle("munderover_underscript", false, "underscript");
+ verify_displaystyle("munderover_overscript", false, "overscript");
+ }, `munderover element (${transform})`);
+ }
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <math><mo id="math_default">&#x2AFF;</mo></math>
+ <math display="inline"><mo id="math_inline">&#x2AFF;</mo></math>
+ <math display="block"><mo id="math_block">&#x2AFF;</mo></math>
+ <math displaystyle="false"><mo id="math_false">&#x2AFF;</mo></math>
+ <math displaystyle="true"><mo id="math_true">&#x2AFF;</mo></math>
+ <math display="block" displaystyle="false">
+ <mo id="math_block_false">&#x2AFF;</mo>
+ </math>
+ <math display="block" displaystyle="true">
+ <mo id="math_block_true">&#x2AFF;</mo>
+ </math>
+ <math display="inline" displaystyle="false">
+ <mo id="math_inline_false">&#x2AFF;</mo>
+ </math>
+ <math display="inline" displaystyle="true">
+ <mo id="math_inline_true">&#x2AFF;</mo>
+ </math>
+ <math><mstyle displaystyle="false"><mo id="mstyle_false">&#x2AFF;</mo></mstyle></math>
+ <math><mstyle displaystyle="true"><mo id="mstyle_true">&#x2AFF;</mo></mstyle></math>
+ <math displaystyle="true"><mtable><mtr><mtd><mo id="mtable_default">&#x2AFF;</mo></mtd></mtr></mtable></math>
+ <math><mtable displaystyle="true"><mtr><mtd><mo id="mtable_true">&#x2AFF;</mo></mtd></mtr></mtable></math>
+ <math displaystyle="true"><mtable displaystyle="false"><mtr><mtd><mo id="mtable_false">&#x2AFF;</mo></mtd></mtr></mtable></math>
+ <math displaystyle="true"><mo id="mfrac_sibling">&#x2AFF;</mo><mfrac><mo id="mfrac_numerator">&#x2AFF;</mo><mo id="mfrac_denominator">&#x2AFF;</mo></mfrac></math>
+ <math displaystyle="true"><mroot><mo id="mroot_base">&#x2AFF;</mo><mo id="mroot_index">&#x2AFF;</mo></mroot></math>
+ <math displaystyle="true"><msub><mo id="msub_base">&#x2AFF;</mo><mo id="msub_subscript">&#x2AFF;</mo></msub></math>
+ <math displaystyle="true"><msup><mo id="msup_base">&#x2AFF;</mo><mo id="msup_supscript">&#x2AFF;</mo></msup></math>
+ <math displaystyle="true"><msubsup><mo id="msubsup_base">&#x2AFF;</mo><mo id="msubsup_subscript">&#x2AFF;</mo><mo id="msubsup_supscript">&#x2AFF;</mo></msubsup></math>
+ <math displaystyle="true"><mmultiscripts><mo id="mmultiscripts_base">&#x2AFF;</mo><mo id="mmultiscripts_subscript">&#x2AFF;</mo><mo id="mmultiscripts_supscript">&#x2AFF;</mo><mprescripts/><mo id="mmultiscripts_presubscript">&#x2AFF;</mo><mo id="mmultiscripts_presupscript">&#x2AFF;</mo></mmultiscripts></math>
+ <math displaystyle="true"><munder><mo id="munder_base">&#x2AFF;</mo><mo id="munder_underscript">&#x2AFF;</mo></munder></math>
+ <math displaystyle="true"><mover><mo id="mover_base">&#x2AFF;</mo><mo id="mover_overscript">&#x2AFF;</mo></mover></math>
+ <math displaystyle="true"><munderover><mo id="munderover_base">&#x2AFF;</mo><mo id="munderover_underscript">&#x2AFF;</mo><mo id="munderover_overscript">&#x2AFF;</mo></munderover></math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-2.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-2.html
new file mode 100644
index 0000000000..68566cfc25
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-2.html
@@ -0,0 +1,208 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>displaystyle</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-math-style-property">
+<meta name="assert" content="Verify interaction between automatic displaystyle and specified displaystyle on descendants.">
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/largeop-displayoperatorminheight5000.woff");
+ }
+ math, math * {
+ font-family: TestFont;
+ font-size: 10px;
+ }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/attribute-values.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script>
+ setup({ explicit_done: true });
+ var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000
+ var epsilon = 5;
+ function verify_displaystyle(elementId, displaystyle, description) {
+ var expectedSize = (displaystyle ? 5000 : 1000) * emToPx;
+ var elementSize = document.getElementById(elementId).
+ getBoundingClientRect().height;
+ assert_approx_equals(elementSize, expectedSize, epsilon, description);
+ }
+
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+ for (transform in AttributeValueTransforms) {
+ TransformAttributeValues(transform, ["display", "displaystyle"]);
+ test(function() {
+ verify_displaystyle("cell_false", false, "cell with displaystyle false");
+ verify_displaystyle("cell_true", true, "cell with displaystyle true");
+ }, `mtable element (${transform})`);
+ test(function() {
+ verify_displaystyle("mfrac_numerator", true, "numerator");
+ verify_displaystyle("mfrac_denominator", true, "denominator");
+ }, `mfrac element (${transform})`);
+ test(function() {
+ verify_displaystyle("mroot_base", false, "base");
+ verify_displaystyle("mroot_index", true, "index");
+ }, `mroot element (${transform})`);
+ test(function() {
+ verify_displaystyle("msub_base", false, "base");
+ verify_displaystyle("msub_subscript", true, "subscript");
+ }, `msub element (${transform})`);
+ test(function() {
+ verify_displaystyle("msup_base", false, "base");
+ verify_displaystyle("msup_superscript", true, "superscript");
+ }, `msup element (${transform})`);
+ test(function() {
+ verify_displaystyle("msubsup_base", false, "base");
+ verify_displaystyle("msubsup_subscript", true, "subscript");
+ verify_displaystyle("msubsup_superscript", true, "superscript");
+ }, `msubsup element (${transform})`);
+ test(function() {
+ verify_displaystyle("munder_base", false, "base");
+ verify_displaystyle("munder_underscript", true, "underscript");
+ }, `munder element (${transform})`);
+ test(function() {
+ verify_displaystyle("mover_base", false, "base");
+ verify_displaystyle("mover_overscript", true, "overscript");
+ }, `mover element (${transform})`);
+ test(function() {
+ verify_displaystyle("munderover_base", false, "base");
+ verify_displaystyle("munderover_underscript", true, "underscript");
+ verify_displaystyle("munderover_overscript", true, "overscript");
+ }, `munderover element (${transform})`);
+ }
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <math displaystyle="true">
+ <mtable>
+ <mtr>
+ <mtd>
+ <mstyle displaystyle="false">
+ <mo id="cell_false">&#x2AFF;</mo>
+ </mstyle>
+ </mtd>
+ <mtd>
+ <mstyle displaystyle="true">
+ <mo id="cell_true">&#x2AFF;</mo>
+ </mstyle>
+ </mtd>
+ </mtr>
+ </mtable>
+ </math>
+ <math>
+ <mfrac>
+ <mstyle displaystyle="true">
+ <mo id="mfrac_numerator">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="mfrac_denominator">&#x2AFF;</mo>
+ </mstyle>
+ </mfrac>
+ </math>
+ <math displaystyle="true">
+ <mroot>
+ <mstyle displaystyle="false">
+ <mo id="mroot_base">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="mroot_index">&#x2AFF;</mo>
+ </mstyle>
+ </mroot>
+ </math>
+ <math displaystyle="true">
+ <msub>
+ <mstyle displaystyle="false">
+ <mo id="msub_base">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="msub_subscript">&#x2AFF;</mo>
+ </mstyle>
+ </msub>
+ </math>
+ <math displaystyle="true">
+ <msup>
+ <mstyle displaystyle="false">
+ <mo id="msup_base">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="msup_superscript">&#x2AFF;</mo>
+ </mstyle>
+ </msup>
+ </math>
+ <math displaystyle="true">
+ <msubsup>
+ <mstyle displaystyle="false">
+ <mo id="msubsup_base">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="msubsup_subscript">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="msubsup_superscript">&#x2AFF;</mo>
+ </mstyle>
+ </msubsup>
+ </math>
+ <math displaystyle="true">
+ <mmultiscripts>
+ <mstyle displaystyle="false">
+ <mo id="mmultiscripts_base">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="mmultiscripts_subscript">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="mmultiscripts_superscript">&#x2AFF;</mo>
+ </mstyle>
+ <mprescripts/>
+ <mstyle displaystyle="true">
+ <mo id="mmultiscripts_presubscript">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="mmultiscripts_presuperscript">&#x2AFF;</mo>
+ </mstyle>
+ </mmultiscripts>
+ </math>
+ <math displaystyle="true">
+ <munder>
+ <mstyle displaystyle="false">
+ <mo id="munder_base">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="munder_underscript">&#x2AFF;</mo>
+ </mstyle>
+ </munder>
+ </math>
+ <math displaystyle="true">
+ <mover>
+ <mstyle displaystyle="false">
+ <mo id="mover_base">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="mover_overscript">&#x2AFF;</mo>
+ </mstyle>
+ </mover>
+ </math>
+ <math displaystyle="true">
+ <munderover>
+ <mstyle displaystyle="false">
+ <mo id="munderover_base">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="munderover_underscript">&#x2AFF;</mo>
+ </mstyle>
+ <mstyle displaystyle="true">
+ <mo id="munderover_overscript">&#x2AFF;</mo>
+ </mstyle>
+ </munderover>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-3.html b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-3.html
new file mode 100644
index 0000000000..a5bcab2aaa
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/displaystyle-3.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>displaystyle</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-math-style-property">
+<meta name="assert" content="Verify the displaystyle of the underover element is considered (not the one of its base) to determine whether to move limits.">
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ math, math * {
+ font-family: Ahem;
+ font-size: 20px;
+ }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ function runTests() {
+ ["munder", "mover", "munderover"].forEach((tag) => {
+ Array.from(document.getElementsByTagName(tag)).forEach(e => {
+ var displaystyle = e.getAttribute('displaystyle') === "true";
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_movablelimits());
+ var elementRight = e.getBoundingClientRect().right;
+ var baseRight = e.firstElementChild.getBoundingClientRect().right;
+ if (displaystyle)
+ assert_approx_equals(elementRight, baseRight, 1);
+ else
+ assert_greater_than(elementRight, baseRight + 10);
+ }, `movablelimits for ${tag} element (displaystyle=${displaystyle})`);
+ });
+ });
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <math>
+ <munder displaystyle="false">
+ <mo displaystyle="true" movablelimits="true">XX</mo>
+ <mtext>X</mtext>
+ </munder>
+ </math>
+ <math>
+ <mover displaystyle="false">
+ <mo displaystyle="true" movablelimits="true">XX</mo>
+ <mtext>X</mtext>
+ </mover>
+ </math>
+ <math>
+ <munderover displaystyle="false">
+ <mo displaystyle="true" movablelimits="true">XX</mo>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munderover>
+ </math>
+ <math>
+ <munder displaystyle="true">
+ <mo displaystyle="false" movablelimits="true">XX</mo>
+ <mtext>X</mtext>
+ </munder>
+ </math>
+ <math>
+ <mover displaystyle="true">
+ <mo displaystyle="false" movablelimits="true">XX</mo>
+ <mtext>X</mtext>
+ </mover>
+ </math>
+ <math>
+ <munderover displaystyle="true">
+ <mo displaystyle="false" movablelimits="true">XX</mo>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munderover>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1-ref.html
new file mode 100644
index 0000000000..111ea79e24
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1-ref.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test dynamically changing dir attribute</title>
+</head>
+<body>
+ <p>
+ math:
+ <math dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </math>
+ <math dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </math>
+ <math>
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </math>
+ </p>
+ <p>
+ mstyle:
+ <math>
+ <mstyle dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mstyle>
+ </math>
+ <math>
+ <mstyle dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mstyle>
+ </math>
+ <math>
+ <mstyle>
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mstyle>
+ </math>
+ </p>
+ <p>
+ mrow:
+ <math>
+ <mrow dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mrow>
+ </math>
+ <math>
+ <mrow dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mrow>
+ </math>
+ <math>
+ <mrow>
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mrow>
+ </math>
+ </p>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1.html b/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1.html
new file mode 100644
index 0000000000..d97505eff1
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/dynamic-dir-1.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+ <meta charset="utf-8">
+ <title>Test dynamically changing dir attribute</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+ <meta name="assert" content="The dir attribute should update direction map to css properties dynamically">
+ <link rel="match" href="dynamic-dir-1-ref.html">
+ <script>
+ window.addEventListener("load", () => {
+
+ // force initial layout so we're sure what we're testing against
+ document.documentElement.getBoundingClientRect();
+
+ ["math", "mstyle", "mrow"].forEach((tag) => {
+ let elements = document.getElementsByTagName(tag);
+
+ // set an explicit rtl where there was none
+ elements[0].setAttribute("dir", "rtl");
+
+ // change explicit ltr to rtl
+ elements[1].setAttribute("dir", "rtl");
+
+ // remove an explicitly set dir="rtl"
+ elements[2].removeAttribute("dir");
+
+ })
+
+ document.documentElement.classList.remove('reftest-wait');
+ })
+ </script>
+</head>
+<body>
+ <p>
+ math:
+ <math>
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </math>
+ <math dir="ltr">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </math>
+ <math dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </math>
+ </p>
+ <p>
+ mstyle:
+ <math>
+ <mstyle>
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mstyle>
+ </math>
+ <math>
+ <mstyle dir="ltr">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mstyle>
+ </math>
+ <math>
+ <mstyle dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mstyle>
+ </math>
+ </p>
+ <p>
+ mrow:
+ <math>
+ <mrow>
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mrow>
+ </math>
+ <math>
+ <mrow dir="ltr">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mrow>
+ </math>
+ <math>
+ <mrow dir="rtl">
+ <mi>a</mi>
+ <mi>b</mi>
+ <mi>c</mi>
+ </mrow>
+ </math>
+ </p>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_dir");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display-ref.html
new file mode 100644
index 0000000000..8f25c9db06
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>floating inside display: block MathML (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a blue square on the left and a smaller magenta square on the right.</p>
+ <div>
+ <div style="display: block">
+ <div style="display: inline-block; width: 50px; height: 50px; background: magenta"></div><div style="float: left; display: inline-block; width: 100px; height: 100px; background: blue"></div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display.html
new file mode 100644
index 0000000000..f398094e15
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-inside-mathml-with-block-display.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>floating inside display: block MathML</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="floating-inside-mathml-with-block-display-ref.html"/>
+<meta name="assert" content="Verify that float works within a display: block MathML element.">
+</head>
+<body>
+ <p>Test passes if you see a blue square on the left and a smaller magenta square on the right.</p>
+ <math>
+ <mrow style="display: block">
+ <mspace style="display: inline-block; width: 50px; height: 50px; background: magenta"/><mspace style="float: left; display: inline-block; width: 100px; height: 100px; background: blue"/>
+ </mrow>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math-ref.html
new file mode 100644
index 0000000000..c82f395644
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>floating math (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a blue square on the left and a smaller magenta square on the right.</p>
+ <div>
+ <div style="display: inline-block; width: 50px; height: 50px; background: magenta"></div>
+ <div style="float: left"><div style="width: 100px; height: 100px; background: blue"></div></div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math.html
new file mode 100644
index 0000000000..1de54ccdcf
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/floating-math.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>floating math</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="floating-math-ref.html"/>
+<meta name="assert" content="Verify that float applies to the <math> element.">
+</head>
+<body>
+ <p>Test passes if you see a blue square on the left and a smaller magenta square on the right.</p>
+ <div>
+ <div style="display: inline-block; width: 50px; height: 50px; background: magenta"></div>
+ <math style="float: left"><mspace width="100px" height="100px" style="background: blue"/></math>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/floats/not-floating-001.html b/testing/web-platform/tests/mathml/relations/css-styling/floats/not-floating-001.html
new file mode 100644
index 0000000000..7166dea5f8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/floats/not-floating-001.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>float property in math layout</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet">
+<meta name="assert" content="Assert that float property is ignored for most math layout">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<style>
+ /* .element class defined in mathml-fragments.js */
+ .element > * {
+ padding: 10px;
+ background: black;
+ }
+ /* override display: none on children of maction/semantics */
+ maction > *, semantics > * {
+ display: math;
+ }
+</style>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="container"></div>
+
+ <script>
+ let container = document.getElementById("container");
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag) ||
+ FragmentHelper.isEmpty(tag))
+ continue;
+
+ // Skip mtable since it does not use display: math.
+ if (tag == "mtable")
+ continue;
+
+ document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\
+<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\
+<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\
+</div>`);
+ let div = document.body.lastElementChild;
+ let element =
+ FragmentHelper.element(div.firstElementChild);
+ let reference =
+ FragmentHelper.element(div.lastElementChild);
+ [element, reference].forEach(parent => {
+ if (parent.classList.contains("mathml-container") ||
+ parent.classList.contains("foreign-container")) {
+ FragmentHelper.appendChild(parent);
+ FragmentHelper.appendChild(parent);
+ FragmentHelper.appendChild(parent);
+ }
+ });
+
+ // Try to use float to invert the order in which children are normally
+ // laid out.
+ function layoutChildrenFromLeftToRight(tag) { tag != 'mroot'; }
+ element.firstElementChild.style =
+ `float: ${layoutChildrenFromLeftToRight(tag) ? 'right' : 'left'};`;
+ element.lastElementChild.style =
+ `float: ${layoutChildrenFromLeftToRight(tag) ? 'left' : 'right'};`;
+
+ test(function () {
+ let epsilon = 1;
+ compareLayout(element, reference, epsilon);
+ }, `float child ignored in ${tag}`);
+
+ div.style = "display: none;"; // Hide the div after measurement.
+ }
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/ignored-properties-001.html b/testing/web-platform/tests/mathml/relations/css-styling/ignored-properties-001.html
new file mode 100644
index 0000000000..34de5836ea
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/ignored-properties-001.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Ignored CSS properties</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<meta name="assert" content="Verify style with ignored properties does not affect MathML layout.">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag))
+ continue;
+
+ var ignoredProperties = [
+ "writing-mode: vertical-rl;",
+ "white-space: normal;",
+ "float: right;",
+ "align-content: end; justify-content: end;",
+ "align-self: end; justify-self: end;",
+ ];
+
+ ignoredProperties.forEach(ignoredStyle => {
+ document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\
+<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\
+<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\
+</div>`);
+ var div = document.body.lastElementChild;
+
+ // Create MathML structure with ignored style properties.
+ var elementContainer = div.firstElementChild;
+ var elementContainerWidth = elementContainer.getBoundingClientRect().width;
+ var element = FragmentHelper.element(elementContainer);
+ if (!FragmentHelper.isEmpty(tag))
+ FragmentHelper.forceNonEmptyDescendants(element);
+ element.setAttribute("style", ignoredStyle);
+ Array.from(element.getElementsByTagNameNS("*", FragmentHelper.mathml_namespace)).forEach(descendant => {
+ descendant.setAttribute("style", ignoredStyle);
+ });
+
+ var referenceContainer = div.lastElementChild;
+ var referenceContainerWidth = referenceContainer.getBoundingClientRect().width;
+ var reference = FragmentHelper.element(referenceContainer);
+ if (!FragmentHelper.isEmpty(tag))
+ FragmentHelper.forceNonEmptyDescendants(reference);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ assert_approx_equals(elementContainerWidth, referenceContainerWidth, epsilon);
+ }, `${tag} preferred width calculation is not affected by ${ignoredStyle}`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ compareLayout(element, reference, epsilon);
+ }, `${tag} layout is not affected by ${ignoredStyle}`);
+
+ div.style = "display: none;"; // Hide the div after measurement.
+ });
+ }
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute-ref.html
new file mode 100644
index 0000000000..8e3d7b1c21
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>legacy scriptminsize attribute (reference)</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ math {
+ /* Ahem font does not have a MATH table so the font-size scale factor
+ is always 0.71^{computed - inherited math script level} */
+ font: 100px/1 Ahem;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if you see a square of size 71px.</p>
+ <div>
+ <math>
+ <mstyle>
+ <mstyle scriptlevel="1">
+ <mn>X</mn>
+ </mstyle>
+ </mstyle>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute.html b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute.html
new file mode 100644
index 0000000000..0ce87b6147
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptminsize-attribute.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>legacy scriptminsize attribute</title>
+<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mstyle.attrs">
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="match" href="legacy-scriptminsize-attribute-ref.html"/>
+<meta name="assert" content="Verify scriptminsize attribute is no longer parsed.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ math {
+ /* Ahem font does not have a MATH table so the font-size scale factor
+ is always 0.71^{computed - inherited math script level} */
+ font: 100px/1 Ahem;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if you see a square of size 71px.</p>
+ <div>
+ <math>
+ <mstyle scriptminsize="100px">
+ <mstyle scriptlevel="1">
+ <mn>X</mn>
+ </mstyle>
+ </mstyle>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute-ref.html
new file mode 100644
index 0000000000..422325da28
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>legacy scriptsizemultiplier attribute (reference)</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ math {
+ /* Ahem font does not have a MATH table so the font-size scale factor
+ is always 0.71^{computed - inherited math script level} */
+ font: 100px/1 Ahem;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if you see a square of size 71px.</p>
+ <div>
+ <math>
+ <mstyle>
+ <mstyle scriptlevel="1">
+ <mn>X</mn>
+ </mstyle>
+ </mstyle>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute.html b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute.html
new file mode 100644
index 0000000000..9a955612bc
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/legacy-scriptsizemultiplier-attribute.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>legacy scriptsizemultiplier attribute</title>
+<link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mstyle.attrs">
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="match" href="legacy-scriptsizemultiplier-attribute-ref.html"/>
+<meta name="assert" content="Verify scriptsizemultiplier attribute is no longer parsed.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ math {
+ /* Ahem font does not have a MATH table so the font-size scale factor
+ is always 0.71^{computed - inherited math script level} */
+ font: 100px/1 Ahem;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if you see a square of size 71px.</p>
+ <div>
+ <math>
+ <mstyle scriptsizemultiplier="1">
+ <mstyle scriptlevel="1">
+ <mn>X</mn>
+ </mstyle>
+ </mstyle>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/lengths-1-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/lengths-1-ref.html
new file mode 100644
index 0000000000..9fca6f4963
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/lengths-1-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML lengths (reference)</title>
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+ <div>
+ <div id="red" style="position: absolute; width: 200px; height: 200px; background: green;">
+ </div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/lengths-1.html b/testing/web-platform/tests/mathml/relations/css-styling/lengths-1.html
new file mode 100644
index 0000000000..896f08d111
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/lengths-1.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML lengths</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values">
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace">
+<link rel="match" href="lengths-1-ref.html"/>
+<meta name="assert" content="Verify whether the different units are accepted for MathML lengths.">
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/xheight500.woff");
+ }
+ span, math {
+ font-family: TestFont;
+ font-size: 10px; /* 1em = 10px, 1ex is about 5px */
+ }
+ span {
+ position: absolute;
+ display: inline-block;
+ height: 10px;
+ }
+ #red > span {
+ background: red;
+ }
+ #green > span {
+ background: green;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+ <div>
+ <div id="red" style="position: absolute; width: 200px; height: 200px; background: green;">
+ <!-- px -->
+ <span style="top: 0px"><math><mspace width="200px"/></math></span>
+ <span style="top: 10px; width: 200px"></span>
+
+ <!-- cm -->
+ <span style="top: 20px"><math><mspace width="5.08cm"/></math></span>
+ <span style="top: 30px; width: 192px"></span>
+
+ <!-- em -->
+ <span style="top: 40px"><math><mspace width="20em"/></math></span>
+ <span style="top: 50px; width: 200px"></span>
+
+ <!-- ex -->
+ <span style="top: 60px"><math><mspace width="30ex"/></math></span>
+ <span style="top: 70px; width: 30ex"></span>
+
+ <!-- in -->
+ <span style="top: 80px"><math><mspace width="2in"/></math></span>
+ <span style="top: 90px; width: 192px"></span>
+
+ <!-- mm -->
+ <span style="top: 100px"><math><mspace width="50.8mm"/></math></span>
+ <span style="top: 110px; width: 192px"></span>
+
+ <!-- pc -->
+ <span style="top: 120px"><math><mspace width="12.5pc"/></math></span>
+ <span style="top: 130px; width: 200px"></span>
+
+ <!-- pt -->
+ <span style="top: 140px"><math><mspace width="150pt"/></math></span>
+ <span style="top: 150px; width: 200px"></span>
+
+ <!-- % -->
+ <span style="top: 160px"><math><mstyle mathsize="2000%"><mspace width="1em"/></mstyle></math></span>
+ <span style="top: 170px; width: 200px"></span>
+
+ <!-- unitless nonzero values should be ignored -->
+ <span style="top: 180px"><math><mstyle mathsize="20.0"><mspace width="1em"/></mstyle></math></span>
+ <span style="top: 190px; width: 10px"></span>
+ </div>
+
+ <div id="green" style="position: absolute; width: 200px; height: 200px;">
+ <!-- px -->
+ <span style="top: 10px"><math><mspace width="200px"/></math></span>
+ <span style="top: 0px; width: 200px"></span>
+
+ <!-- cm -->
+ <span style="top: 30px"><math><mspace width="5.08cm"/></math></span>
+ <span style="top: 20px; width: 192px"></span>
+
+ <!-- em -->
+ <span title="em" style="top: 50px"><math><mspace width="20em"/></math></span>
+ <span title="em" style="top: 40px; width: 200px"></span>
+
+ <!-- ex -->
+ <span title="ex" style="top: 70px"><math><mspace width="30ex"/></math></span>
+ <span title="ex" style="top: 60px; width: 30ex"></span>
+
+ <!-- in -->
+ <span style="top: 90px"><math><mspace width="2in"/></math></span>
+ <span style="top: 80px; width: 192px"></span>
+
+ <!-- mm -->
+ <span style="top: 110px"><math><mspace width="50.8mm"/></math></span>
+ <span style="top: 100px; width: 192px"></span>
+
+ <!-- pc -->
+ <span style="top: 130px"><math><mspace width="12.5pc"/></math></span>
+ <span style="top: 120px; width: 200px"></span>
+
+ <!-- pt -->
+ <span style="top: 150px"><math><mspace width="150pt"/></math></span>
+ <span style="top: 140px; width: 200px"></span>
+
+ <!-- % -->
+ <span style="top: 170px"><math><mstyle mathsize="2000%"><mspace width="1em"/></mstyle></math></span>
+ <span style="top: 160px; width: 200px"></span>
+
+ <!-- unitless nonzero values should be ignored -->
+ <span style="top: 190px"><math><mstyle mathsize="20.0"><mspace width="1em"/></mstyle></math></span>
+ <span style="top: 180px; width: 10px"></span>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/lengths-2.html b/testing/web-platform/tests/mathml/relations/css-styling/lengths-2.html
new file mode 100644
index 0000000000..942611a8da
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/lengths-2.html
@@ -0,0 +1,266 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>MathML lengths</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values">
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace">
+<meta name="assert" content="Verify various cases of the MathML length syntax.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/xheight500.woff");
+ }
+ math {
+ font-family: TestFont;
+ font-size: 10px;
+ }
+</style>
+<script>
+ var epsilon = .5;
+
+ function getBox(aId) {
+ return document.getElementById(aId).getBoundingClientRect();
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_equals(getBox("unitCm").width, 96, "cm");
+ assert_equals(getBox("unitEm").width, 120, "em");
+ assert_equals(getBox("unitEx").width, 500, "ex");
+ assert_equals(getBox("unitIn").width, 288, "in");
+ assert_equals(getBox("unitMm").width, 576, "mm");
+ assert_equals(getBox("unitPc").width, 96, "pc");
+ assert_equals(getBox("unitPercentage").width, 60, "%");
+ assert_equals(getBox("unitPt").width, 96, "pt");
+ assert_equals(getBox("unitPx").width, 123, "px");
+ }, "Units");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_equals(getBox("spaceCm").width, 96, "cm");
+ assert_equals(getBox("spaceEm").width, 120, "em");
+ assert_equals(getBox("spaceEx").width, 500, "ex");
+ assert_equals(getBox("spaceIn").width, 288, "in");
+ assert_equals(getBox("spaceMm").width, 576, "mm");
+ assert_equals(getBox("spacePc").width, 96, "pc");
+ assert_equals(getBox("spacePercentage").width, 60, "%");
+ assert_equals(getBox("spacePt").width, 96, "pt");
+ assert_equals(getBox("spacePx").width, 123, "px");
+ }, "Trimming of space");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_approx_equals(getBox("n0").width, 0, epsilon, "n0");
+ assert_approx_equals(getBox("n1").width, 90, epsilon, "n1");
+ assert_approx_equals(getBox("n2").width, 8, epsilon, "n2");
+ assert_approx_equals(getBox("n4").width, 650, epsilon, "n4");
+ assert_approx_equals(getBox("n5").width, 4320, epsilon, "n5");
+ assert_approx_equals(getBox("n6").width, 1, epsilon, "n6");
+ assert_approx_equals(getBox("n7").width, 8, epsilon, "n7");
+ assert_approx_equals(getBox("n8").width, 65, epsilon, "n8");
+ assert_approx_equals(getBox("n9").width, 432, epsilon, "n9");
+ assert_approx_equals(getBox("n10").width, 123, epsilon, "n10");
+ }, "Non-negative numbers");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var topRef = getBox("ref").top;
+ assert_approx_equals(getBox("N0").top - topRef, -0, epsilon, "N0");
+ assert_approx_equals(topRef - getBox("N1").top, -90, epsilon, "N1");
+ assert_approx_equals(topRef - getBox("N2").top, -8, epsilon, "N2");
+ assert_approx_equals(topRef - getBox("N4").top, -650, epsilon, "N4");
+ assert_approx_equals(topRef - getBox("N5").top, -4320, epsilon, "N5");
+ assert_approx_equals(topRef - getBox("N6").top, -1, epsilon, "N6");
+ assert_approx_equals(topRef - getBox("N7").top, -8, epsilon, "N7");
+ assert_approx_equals(topRef - getBox("N8").top, -65, epsilon, "N8");
+ assert_approx_equals(topRef - getBox("N9").top, -432, epsilon, "N9");
+ assert_approx_equals(topRef - getBox("N10").top, -123, epsilon, "N10");
+ }, "Non-positive numbers");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ // Namedspace values are invalid in MathML Core.
+ ["veryverythinmathspace",
+ "verythinmathspace",
+ "thinmathspace",
+ "mediummathspace",
+ "thickmathspace",
+ "verythickmathspace",
+ "veryverythickmathspace",
+ "negativeveryverythinmathspace",
+ "negativeverythinmathspace",
+ "negativethinmathspace",
+ "negativemediummathspace",
+ "negativethickmathspace",
+ "negativeverythickmathspace",
+ "negativeveryverythickmathspace"
+ ].forEach(function(space) {
+ var mrow = document.getElementById(space);
+ var boxBefore = mrow.firstElementChild.getBoundingClientRect();
+ var boxAfter = mrow.lastElementChild.getBoundingClientRect();
+ assert_equals(boxAfter.left - boxBefore.right, 0, space);
+ });
+ }, "Legacy namedspaces");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ // These values are invalid in MathML Core.
+ assert_equals(getBox("unitNone").width, 30, "Unitless");
+ assert_approx_equals(getBox("n3").width, 0, epsilon, "n3");
+ var topRef = getBox("ref").top;
+ assert_approx_equals(topRef - getBox("N3").top, 0, epsilon, "N3");
+ }, "Legacy numbers");
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mspace id="unitCm" width="2.54cm"/>
+ <mspace id="unitEm" width="12em"/>
+ <mspace id="unitEx" width="100ex"/>
+ <mspace id="unitIn" width="3in"/>
+ <mspace id="unitMm" width="152.4mm"/>
+ <mspace id="unitPc" width="6pc"/>
+ <mstyle mathsize="200%"><mspace id="unitPercentage" width="3em"/></mstyle>
+ <mspace id="unitPt" width="72pt"/>
+ <mspace id="unitPx" width="123px"/>
+ <mstyle mathsize="5"><mspace id="unitNone" width="3em"/></mstyle>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mspace id="spaceCm" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;2.54cm&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceEm" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;12em&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceEx" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;100ex&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceIn" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;3in&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceMm" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;152.4mm&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spacePc" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;6pc&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mstyle mathsize="200%"><mspace id="spacePercentage" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;3em&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/></mstyle>
+ <mspace id="spacePt" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;72pt&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spacePx" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;123px&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mspace id="n0" width="0em"/>
+ <mspace id="n1" width="9em"/>
+ <mspace id="n2" width=".8em"/>
+ <mspace id="n3" width="7.em"/>
+ <mspace id="n4" width="65em"/>
+ <mspace id="n5" width="432em"/>
+ <mspace id="n6" width=".10em"/>
+ <mspace id="n7" width=".789em"/>
+ <mspace id="n8" width="6.5em"/>
+ <mspace id="n9" width="43.21em"/>
+ <mspace id="n10" width="012.345em"/>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mspace id="ref"></mspace>
+ <mpadded voffset="-0em"><mspace id="N0"/></mpadded>
+ <mpadded voffset="-9em"><mspace id="N1"/></mpadded>
+ <mpadded voffset="-.8em"><mspace id="N2"/></mpadded>
+ <mpadded voffset="-7.em"><mspace id="N3"/></mpadded>
+ <mpadded voffset="-65em"><mspace id="N4"/></mpadded>
+ <mpadded voffset="-432em"><mspace id="N5"/></mpadded>
+ <mpadded voffset="-.10em"><mspace id="N6"/></mpadded>
+ <mpadded voffset="-.789em"><mspace id="N7"/></mpadded>
+ <mpadded voffset="-6.5em"><mspace id="N8"/></mpadded>
+ <mpadded voffset="-43.21em"><mspace id="N9"/></mpadded>
+ <mpadded voffset="-012.345em"><mspace id="N10"/></mpadded>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow id="veryverythinmathspace">
+ <mspace width="1em"/>
+ <mspace width="veryverythinmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="verythinmathspace">
+ <mspace width="1em"/>
+ <mspace width="verythinmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="thinmathspace">
+ <mspace width="1em"/>
+ <mspace width="thinmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="mediummathspace">
+ <mspace width="1em"/>
+ <mspace width="mediummathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="thickmathspace">
+ <mspace width="1em"/>
+ <mspace width="thickmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="verythickmathspace">
+ <mspace width="1em"/>
+ <mspace width="verythickmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="veryverythickmathspace">
+ <mspace width="1em"/>
+ <mspace width="veryverythickmathspace"/>
+ <mspace/>
+ </mrow>
+ </math>
+ <math>
+ <mrow id="negativeveryverythinmathspace">
+ <mspace width="1em"/>
+ <mspace width="veryverythinmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="negativeverythinmathspace">
+ <mspace width="1em"/>
+ <mspace width="verythinmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="negativethinmathspace">
+ <mspace width="1em"/>
+ <mspace width="thinmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="negativemediummathspace">
+ <mspace width="1em"/>
+ <mspace width="mediummathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="negativethickmathspace">
+ <mspace width="1em"/>
+ <mspace width="thickmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="negativeverythickmathspace">
+ <mspace width="1em"/>
+ <mspace width="verythickmathspace"/>
+ <mspace/>
+ </mrow>
+ <mrow id="negativeveryverythickmathspace">
+ <mspace width="1em"/>
+ <mspace width="veryverythickmathspace"/>
+ <mspace/>
+ </mrow>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001-notref.html
new file mode 100644
index 0000000000..65e2781c5e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001-notref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathbackground on mrow (reference)</title>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow mathbackground="green">
+ <mtext>□■□■□■□</mtext>
+ </mrow>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001.html
new file mode 100644
index 0000000000..e71fc53eaa
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-001.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathbackground on mrow</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow">
+<link rel="mismatch" href="mathbackground-001-notref.html"/>
+<meta name="assert" content="mathbackground on a mrow has a visual effect.">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow mathbackground="red">
+ <mtext>□■□■□■□</mtext>
+ </mrow>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002-notref.html
new file mode 100644
index 0000000000..8c984c2619
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002-notref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathbackground on mstyle (reference)</title>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mstyle mathbackground="green">
+ <mtext>□■□■□■□</mtext>
+ </mstyle>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002.html
new file mode 100644
index 0000000000..09407d9269
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-002.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathbackground on mstyle</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle">
+<link rel="mismatch" href="mathbackground-002-notref.html"/>
+<meta name="assert" content="mathbackground on a mstyle has a visual effect.">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mstyle mathbackground="red">
+ <mtext>□■□■□■□</mtext>
+ </mstyle>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003-notref.html
new file mode 100644
index 0000000000..b6adaa8d4e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003-notref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathbackground on mtext (reference)</title>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mtext mathbackground="green">□■□■□■□</mtext>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003.html
new file mode 100644
index 0000000000..8cb11889db
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-003.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathbackground on mtext</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="mismatch" href="mathbackground-003-notref.html"/>
+<meta name="assert" content="mathbackground on a mtext has a visual effect.">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mtext mathbackground="red">□■□■□■□</mtext>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004-notref.html
new file mode 100644
index 0000000000..75465a6c38
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004-notref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathbackground on semantics (reference)</title>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <semantics mathbackground="red">
+ <mtext>□■□■□■□</mtext>
+ </semantics>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004.html b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004.html
new file mode 100644
index 0000000000..be174cdbde
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathbackground-004.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathbackground on semantics</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#semantics-and-presentation">
+<link rel="mismatch" href="mathbackground-004-notref.html"/>
+<meta name="assert" content="mathbackground on a semantics has a visual effect.">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <semantics mathbackground="green">
+ <mtext>□■□■□■□</mtext>
+ </semantics>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001-notref.html
new file mode 100644
index 0000000000..9bc1ba5436
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001-notref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathcolor on mrow (reference)</title>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow mathcolor="green">
+ <mtext>□■□■□■□</mtext>
+ </mrow>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001.html
new file mode 100644
index 0000000000..2c463cac87
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-001.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathcolor on mrow</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#horizontally-group-sub-expressions-mrow">
+<link rel="mismatch" href="mathcolor-001-notref.html"/>
+<meta name="assert" content="mathcolor on a mrow has a visual effect.">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow mathcolor="red">
+ <mtext>□■□■□■□</mtext>
+ </mrow>
+</math>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002-notref.html
new file mode 100644
index 0000000000..5f9fd2bb9b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002-notref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathcolor on mstyle (reference)</title>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mstyle mathcolor="green">
+ <mtext>□■□■□■□</mtext>
+ </mstyle>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002.html
new file mode 100644
index 0000000000..147d41b46d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-002.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathcolor on mstyle</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#style-change-mstyle">
+<link rel="mismatch" href="mathcolor-002-notref.html"/>
+<meta name="assert" content="mathcolor on a mstyle has a visual effect.">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mstyle mathcolor="red">
+ <mtext>□■□■□■□</mtext>
+ </mstyle>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003-notref.html
new file mode 100644
index 0000000000..11e018ebc1
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003-notref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathcolor on mtext (reference)</title>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mtext mathcolor="green">□■□■□■□</mtext>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003.html
new file mode 100644
index 0000000000..5565b0d837
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-003.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathcolor on mtext</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="mismatch" href="mathcolor-003-notref.html"/>
+<meta name="assert" content="mathcolor on a mtext has a visual effect.">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mtext mathcolor="red">□■□■□■□</mtext>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004-notref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004-notref.html
new file mode 100644
index 0000000000..67a45249e5
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004-notref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathcolor on semantics (reference)</title>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <semantics mathcolor="red">
+ <mtext>□■□■□■□</mtext>
+ </semantics>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004.html
new file mode 100644
index 0000000000..3ea37fecdb
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-004.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>mathcolor on semantics</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#semantics-and-presentation">
+<link rel="mismatch" href="mathcolor-004-notref.html"/>
+<meta name="assert" content="mathcolor on a semantics has a visual effect.">
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+ <semantics mathcolor="green">
+ <mtext>□■□■□■□</mtext>
+ </semantics>
+</math>
+
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css-ref.html
new file mode 100644
index 0000000000..682fa64233
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS color (reference)</title>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ math {
+ font-family: Ahem;
+ font-size: 20px;
+ }
+</style>
+</style>
+</head>
+<body>
+ <p>Test passes if you see a green rectangle:</p>
+ <p>
+ <math mathbackground="#0f0" mathcolor="#0f0">
+ <mtext>X X</mtext>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css.html b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css.html
new file mode 100644
index 0000000000..2f53215346
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathcolor-mathbackground-css.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS color</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values">
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="match" href="mathcolor-mathbackground-css-ref.html"/>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<meta name="assert" content="Verify that the mathcolor and mathbackground attributes use the CSS definition of colors.">
+<style>
+ math {
+ font-family: Ahem;
+ font-size: 20px;
+ }
+</style>
+</style>
+</head>
+<body>
+ <p>Test passes if you see a green rectangle:</p>
+ <p style="color: red">
+ <math mathbackground="rgb(0,255,0)" mathcolor="rgb(0,255,0)">
+ <mtext>X X</mtext>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html
new file mode 100644
index 0000000000..ebb12a6c6c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>mathsize and css keywords</title>
+ </head>
+ <body>
+ <p>Test passes if you see 14 "A" of equal size:</p>
+ <math>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords.html
new file mode 100644
index 0000000000..2daed4cdea
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-css-keywords.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>mathsize and css keywords</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+ <meta name="assert" content="Verify that CSS font-size keywords are invalid for the mathsize attribute.">
+ <link rel="match" href="mathsize-attribute-css-keywords-ref.html">
+ <script src="/mathml/support/feature-detection.js"></script>
+ </head>
+ <body>
+ <p>Test passes if you see 14 "A" of equal size:</p>
+ <math>
+ <mtext>A</mtext>
+ <mtext mathsize="xx-small">A</mtext>
+ <mtext mathsize="x-small">A</mtext>
+ <mtext mathsize="small">A</mtext>
+ <mtext mathsize="medium">A</mtext>
+ <mtext mathsize="large">A</mtext>
+ <mtext mathsize="x-large">A</mtext>
+ <mtext mathsize="xx-large">A</mtext>
+ <mtext mathsize="larger">A</mtext>
+ <mtext mathsize="smaller">A</mtext>
+ <mtext mathsize="xx-ſmall">A</mtext>
+ <mtext mathsize="x-ſmall">A</mtext>
+ <mtext mathsize="ſmall">A</mtext>
+ <mtext mathsize="ſmaller">A</mtext>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mathsize");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values-ref.html
new file mode 100644
index 0000000000..687efa49be
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Legacy mathsize values</title>
+ </head>
+ <body>
+ <p>Test passes if you see four "A" of equal size:</p>
+ <math>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ <mtext>A</mtext>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values.html
new file mode 100644
index 0000000000..aebf09f9b8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-legacy-values.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Legacy mathsize values</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+ <meta name="assert" content="Verify that legacy values for mathsize have no effect.">
+ <link rel="match" href="mathsize-attribute-legacy-values-ref.html">
+ <script src="/mathml/support/feature-detection.js"></script>
+ </head>
+ <body>
+ <p>Test passes if you see four "A" of equal size:</p>
+ <math>
+ <mtext>A</mtext>
+ <mtext mathsize="small">A</mtext>
+ <mtext mathsize="medium">A</mtext>
+ <mtext mathsize="big">A</mtext>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mathsize");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-ref.html
new file mode 100644
index 0000000000..7a0450e51e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Verify mathsize attribute</title>
+ </head>
+ <body>
+
+ <!-- The style attribute should have the same effect as the mathsize
+ attribute. -->
+ <div>
+ <math>
+ <mi style="font-size: 200%;">x</mi>
+ <mi style="font-size: 3em;">x</mi>
+ </math>
+ </div>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute.html b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute.html
new file mode 100644
index 0000000000..66bcb6dd25
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathsize-attribute.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Verify mathsize attribute</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+ <meta name="assert" content="Verify mathsize attribute values.">
+ <link rel="match" href="mathsize-attribute-ref.html">
+ </head>
+ <body>
+
+ <!-- This verifies the effect of the mathsize attribute. -->
+ <div>
+ <math>
+ <mi mathsize="200%">x</mi>
+ <mi mathsize="3em">x</mi>
+ </math>
+ </div>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto-ref.html
new file mode 100644
index 0000000000..105ba412e6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto-ref.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>mathvariant auto (reference)</title>
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/mathvariant-italic.woff");
+ }
+ body > span {
+ padding: 10px;
+ }
+ span > span {
+ font-family: monospace;
+ font-size: 10px;
+ }
+ .testfont {
+ font-family: TestFont;
+ font-size: 10px;
+ }
+</style>
+<body>
+ <!-- Generated by mathml/tools/mathvariant.py; DO NOT EDIT. -->
+ <p>Test passes if all the equalities below are true.</p>
+ <span><math class="testfont"><mi>&#x1D434;</mi></math>=<span>1D434</span></span>
+ <span><math class="testfont"><mi>&#x1D435;</mi></math>=<span>1D435</span></span>
+ <span><math class="testfont"><mi>&#x1D436;</mi></math>=<span>1D436</span></span>
+ <span><math class="testfont"><mi>&#x1D437;</mi></math>=<span>1D437</span></span>
+ <span><math class="testfont"><mi>&#x1D438;</mi></math>=<span>1D438</span></span>
+ <span><math class="testfont"><mi>&#x1D439;</mi></math>=<span>1D439</span></span>
+ <span><math class="testfont"><mi>&#x1D43A;</mi></math>=<span>1D43A</span></span>
+ <span><math class="testfont"><mi>&#x1D43B;</mi></math>=<span>1D43B</span></span>
+ <span><math class="testfont"><mi>&#x1D43C;</mi></math>=<span>1D43C</span></span>
+ <span><math class="testfont"><mi>&#x1D43D;</mi></math>=<span>1D43D</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D43E;</mi></math>=<span>1D43E</span></span>
+ <span><math class="testfont"><mi>&#x1D43F;</mi></math>=<span>1D43F</span></span>
+ <span><math class="testfont"><mi>&#x1D440;</mi></math>=<span>1D440</span></span>
+ <span><math class="testfont"><mi>&#x1D441;</mi></math>=<span>1D441</span></span>
+ <span><math class="testfont"><mi>&#x1D442;</mi></math>=<span>1D442</span></span>
+ <span><math class="testfont"><mi>&#x1D443;</mi></math>=<span>1D443</span></span>
+ <span><math class="testfont"><mi>&#x1D444;</mi></math>=<span>1D444</span></span>
+ <span><math class="testfont"><mi>&#x1D445;</mi></math>=<span>1D445</span></span>
+ <span><math class="testfont"><mi>&#x1D446;</mi></math>=<span>1D446</span></span>
+ <span><math class="testfont"><mi>&#x1D447;</mi></math>=<span>1D447</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D448;</mi></math>=<span>1D448</span></span>
+ <span><math class="testfont"><mi>&#x1D449;</mi></math>=<span>1D449</span></span>
+ <span><math class="testfont"><mi>&#x1D44A;</mi></math>=<span>1D44A</span></span>
+ <span><math class="testfont"><mi>&#x1D44B;</mi></math>=<span>1D44B</span></span>
+ <span><math class="testfont"><mi>&#x1D44C;</mi></math>=<span>1D44C</span></span>
+ <span><math class="testfont"><mi>&#x1D44D;</mi></math>=<span>1D44D</span></span>
+ <span><math class="testfont"><mi>&#x1D44E;</mi></math>=<span>1D44E</span></span>
+ <span><math class="testfont"><mi>&#x1D44F;</mi></math>=<span>1D44F</span></span>
+ <span><math class="testfont"><mi>&#x1D450;</mi></math>=<span>1D450</span></span>
+ <span><math class="testfont"><mi>&#x1D451;</mi></math>=<span>1D451</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D452;</mi></math>=<span>1D452</span></span>
+ <span><math class="testfont"><mi>&#x1D453;</mi></math>=<span>1D453</span></span>
+ <span><math class="testfont"><mi>&#x1D454;</mi></math>=<span>1D454</span></span>
+ <span><math class="testfont"><mi>&#x210E;</mi></math>=<span>0210E</span></span>
+ <span><math class="testfont"><mi>&#x1D456;</mi></math>=<span>1D456</span></span>
+ <span><math class="testfont"><mi>&#x1D457;</mi></math>=<span>1D457</span></span>
+ <span><math class="testfont"><mi>&#x1D458;</mi></math>=<span>1D458</span></span>
+ <span><math class="testfont"><mi>&#x1D459;</mi></math>=<span>1D459</span></span>
+ <span><math class="testfont"><mi>&#x1D45A;</mi></math>=<span>1D45A</span></span>
+ <span><math class="testfont"><mi>&#x1D45B;</mi></math>=<span>1D45B</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D45C;</mi></math>=<span>1D45C</span></span>
+ <span><math class="testfont"><mi>&#x1D45D;</mi></math>=<span>1D45D</span></span>
+ <span><math class="testfont"><mi>&#x1D45E;</mi></math>=<span>1D45E</span></span>
+ <span><math class="testfont"><mi>&#x1D45F;</mi></math>=<span>1D45F</span></span>
+ <span><math class="testfont"><mi>&#x1D460;</mi></math>=<span>1D460</span></span>
+ <span><math class="testfont"><mi>&#x1D461;</mi></math>=<span>1D461</span></span>
+ <span><math class="testfont"><mi>&#x1D462;</mi></math>=<span>1D462</span></span>
+ <span><math class="testfont"><mi>&#x1D463;</mi></math>=<span>1D463</span></span>
+ <span><math class="testfont"><mi>&#x1D464;</mi></math>=<span>1D464</span></span>
+ <span><math class="testfont"><mi>&#x1D465;</mi></math>=<span>1D465</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D466;</mi></math>=<span>1D466</span></span>
+ <span><math class="testfont"><mi>&#x1D467;</mi></math>=<span>1D467</span></span>
+ <span><math class="testfont"><mi>&#x1D6A4;</mi></math>=<span>1D6A4</span></span>
+ <span><math class="testfont"><mi>&#x1D6A5;</mi></math>=<span>1D6A5</span></span>
+ <span><math class="testfont"><mi>&#x1D6E2;</mi></math>=<span>1D6E2</span></span>
+ <span><math class="testfont"><mi>&#x1D6E3;</mi></math>=<span>1D6E3</span></span>
+ <span><math class="testfont"><mi>&#x1D6E4;</mi></math>=<span>1D6E4</span></span>
+ <span><math class="testfont"><mi>&#x1D6E5;</mi></math>=<span>1D6E5</span></span>
+ <span><math class="testfont"><mi>&#x1D6E6;</mi></math>=<span>1D6E6</span></span>
+ <span><math class="testfont"><mi>&#x1D6E7;</mi></math>=<span>1D6E7</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D6E8;</mi></math>=<span>1D6E8</span></span>
+ <span><math class="testfont"><mi>&#x1D6E9;</mi></math>=<span>1D6E9</span></span>
+ <span><math class="testfont"><mi>&#x1D6EA;</mi></math>=<span>1D6EA</span></span>
+ <span><math class="testfont"><mi>&#x1D6EB;</mi></math>=<span>1D6EB</span></span>
+ <span><math class="testfont"><mi>&#x1D6EC;</mi></math>=<span>1D6EC</span></span>
+ <span><math class="testfont"><mi>&#x1D6ED;</mi></math>=<span>1D6ED</span></span>
+ <span><math class="testfont"><mi>&#x1D6EE;</mi></math>=<span>1D6EE</span></span>
+ <span><math class="testfont"><mi>&#x1D6EF;</mi></math>=<span>1D6EF</span></span>
+ <span><math class="testfont"><mi>&#x1D6F0;</mi></math>=<span>1D6F0</span></span>
+ <span><math class="testfont"><mi>&#x1D6F1;</mi></math>=<span>1D6F1</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D6F2;</mi></math>=<span>1D6F2</span></span>
+ <span><math class="testfont"><mi>&#x1D6F3;</mi></math>=<span>1D6F3</span></span>
+ <span><math class="testfont"><mi>&#x1D6F4;</mi></math>=<span>1D6F4</span></span>
+ <span><math class="testfont"><mi>&#x1D6F5;</mi></math>=<span>1D6F5</span></span>
+ <span><math class="testfont"><mi>&#x1D6F6;</mi></math>=<span>1D6F6</span></span>
+ <span><math class="testfont"><mi>&#x1D6F7;</mi></math>=<span>1D6F7</span></span>
+ <span><math class="testfont"><mi>&#x1D6F8;</mi></math>=<span>1D6F8</span></span>
+ <span><math class="testfont"><mi>&#x1D6F9;</mi></math>=<span>1D6F9</span></span>
+ <span><math class="testfont"><mi>&#x1D6FA;</mi></math>=<span>1D6FA</span></span>
+ <span><math class="testfont"><mi>&#x1D6FB;</mi></math>=<span>1D6FB</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D6FC;</mi></math>=<span>1D6FC</span></span>
+ <span><math class="testfont"><mi>&#x1D6FD;</mi></math>=<span>1D6FD</span></span>
+ <span><math class="testfont"><mi>&#x1D6FE;</mi></math>=<span>1D6FE</span></span>
+ <span><math class="testfont"><mi>&#x1D6FF;</mi></math>=<span>1D6FF</span></span>
+ <span><math class="testfont"><mi>&#x1D700;</mi></math>=<span>1D700</span></span>
+ <span><math class="testfont"><mi>&#x1D701;</mi></math>=<span>1D701</span></span>
+ <span><math class="testfont"><mi>&#x1D702;</mi></math>=<span>1D702</span></span>
+ <span><math class="testfont"><mi>&#x1D703;</mi></math>=<span>1D703</span></span>
+ <span><math class="testfont"><mi>&#x1D704;</mi></math>=<span>1D704</span></span>
+ <span><math class="testfont"><mi>&#x1D705;</mi></math>=<span>1D705</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D706;</mi></math>=<span>1D706</span></span>
+ <span><math class="testfont"><mi>&#x1D707;</mi></math>=<span>1D707</span></span>
+ <span><math class="testfont"><mi>&#x1D708;</mi></math>=<span>1D708</span></span>
+ <span><math class="testfont"><mi>&#x1D709;</mi></math>=<span>1D709</span></span>
+ <span><math class="testfont"><mi>&#x1D70A;</mi></math>=<span>1D70A</span></span>
+ <span><math class="testfont"><mi>&#x1D70B;</mi></math>=<span>1D70B</span></span>
+ <span><math class="testfont"><mi>&#x1D70C;</mi></math>=<span>1D70C</span></span>
+ <span><math class="testfont"><mi>&#x1D70D;</mi></math>=<span>1D70D</span></span>
+ <span><math class="testfont"><mi>&#x1D70E;</mi></math>=<span>1D70E</span></span>
+ <span><math class="testfont"><mi>&#x1D70F;</mi></math>=<span>1D70F</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D710;</mi></math>=<span>1D710</span></span>
+ <span><math class="testfont"><mi>&#x1D711;</mi></math>=<span>1D711</span></span>
+ <span><math class="testfont"><mi>&#x1D712;</mi></math>=<span>1D712</span></span>
+ <span><math class="testfont"><mi>&#x1D713;</mi></math>=<span>1D713</span></span>
+ <span><math class="testfont"><mi>&#x1D714;</mi></math>=<span>1D714</span></span>
+ <span><math class="testfont"><mi>&#x1D715;</mi></math>=<span>1D715</span></span>
+ <span><math class="testfont"><mi>&#x1D716;</mi></math>=<span>1D716</span></span>
+ <span><math class="testfont"><mi>&#x1D717;</mi></math>=<span>1D717</span></span>
+ <span><math class="testfont"><mi>&#x1D718;</mi></math>=<span>1D718</span></span>
+ <span><math class="testfont"><mi>&#x1D719;</mi></math>=<span>1D719</span></span><br/>
+ <span><math class="testfont"><mi>&#x1D71A;</mi></math>=<span>1D71A</span></span>
+ <span><math class="testfont"><mi>&#x1D71B;</mi></math>=<span>1D71B</span></span>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto.html b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto.html
new file mode 100644
index 0000000000..affb02f0c9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-auto.html
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>mathvariant auto</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">
+<link rel="help" href="https://w3c.github.io/mathml-core/#new-text-transform-values">
+<link rel="help" href="https://w3c.github.io/mathml-core/#italic-mappings">
+<link rel="match" href="mathvariant-auto-ref.html"/>
+<meta name="assert" content="Verify that a single-char <mi> is equivalent to an <mi> with the transformed italic unicode character.">
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/mathvariant-italic.woff");
+ }
+ body > span {
+ padding: 10px;
+ }
+ span > span {
+ font-family: monospace;
+ font-size: 10px;
+ }
+ .testfont {
+ font-family: TestFont;
+ font-size: 10px;
+ }
+</style>
+<body>
+ <!-- Generated by mathml/tools/mathvariant.py; DO NOT EDIT. -->
+ <p>Test passes if all the equalities below are true.</p>
+ <span><math class="testfont"><mi>&#x41;</mi></math>=<span>1D434</span></span>
+ <span><math class="testfont"><mi>&#x42;</mi></math>=<span>1D435</span></span>
+ <span><math class="testfont"><mi>&#x43;</mi></math>=<span>1D436</span></span>
+ <span><math class="testfont"><mi>&#x44;</mi></math>=<span>1D437</span></span>
+ <span><math class="testfont"><mi>&#x45;</mi></math>=<span>1D438</span></span>
+ <span><math class="testfont"><mi>&#x46;</mi></math>=<span>1D439</span></span>
+ <span><math class="testfont"><mi>&#x47;</mi></math>=<span>1D43A</span></span>
+ <span><math class="testfont"><mi>&#x48;</mi></math>=<span>1D43B</span></span>
+ <span><math class="testfont"><mi>&#x49;</mi></math>=<span>1D43C</span></span>
+ <span><math class="testfont"><mi>&#x4A;</mi></math>=<span>1D43D</span></span><br/>
+ <span><math class="testfont"><mi>&#x4B;</mi></math>=<span>1D43E</span></span>
+ <span><math class="testfont"><mi>&#x4C;</mi></math>=<span>1D43F</span></span>
+ <span><math class="testfont"><mi>&#x4D;</mi></math>=<span>1D440</span></span>
+ <span><math class="testfont"><mi>&#x4E;</mi></math>=<span>1D441</span></span>
+ <span><math class="testfont"><mi>&#x4F;</mi></math>=<span>1D442</span></span>
+ <span><math class="testfont"><mi>&#x50;</mi></math>=<span>1D443</span></span>
+ <span><math class="testfont"><mi>&#x51;</mi></math>=<span>1D444</span></span>
+ <span><math class="testfont"><mi>&#x52;</mi></math>=<span>1D445</span></span>
+ <span><math class="testfont"><mi>&#x53;</mi></math>=<span>1D446</span></span>
+ <span><math class="testfont"><mi>&#x54;</mi></math>=<span>1D447</span></span><br/>
+ <span><math class="testfont"><mi>&#x55;</mi></math>=<span>1D448</span></span>
+ <span><math class="testfont"><mi>&#x56;</mi></math>=<span>1D449</span></span>
+ <span><math class="testfont"><mi>&#x57;</mi></math>=<span>1D44A</span></span>
+ <span><math class="testfont"><mi>&#x58;</mi></math>=<span>1D44B</span></span>
+ <span><math class="testfont"><mi>&#x59;</mi></math>=<span>1D44C</span></span>
+ <span><math class="testfont"><mi>&#x5A;</mi></math>=<span>1D44D</span></span>
+ <span><math class="testfont"><mi>&#x61;</mi></math>=<span>1D44E</span></span>
+ <span><math class="testfont"><mi>&#x62;</mi></math>=<span>1D44F</span></span>
+ <span><math class="testfont"><mi>&#x63;</mi></math>=<span>1D450</span></span>
+ <span><math class="testfont"><mi>&#x64;</mi></math>=<span>1D451</span></span><br/>
+ <span><math class="testfont"><mi>&#x65;</mi></math>=<span>1D452</span></span>
+ <span><math class="testfont"><mi>&#x66;</mi></math>=<span>1D453</span></span>
+ <span><math class="testfont"><mi>&#x67;</mi></math>=<span>1D454</span></span>
+ <span><math class="testfont"><mi>&#x68;</mi></math>=<span>0210E</span></span>
+ <span><math class="testfont"><mi>&#x69;</mi></math>=<span>1D456</span></span>
+ <span><math class="testfont"><mi>&#x6A;</mi></math>=<span>1D457</span></span>
+ <span><math class="testfont"><mi>&#x6B;</mi></math>=<span>1D458</span></span>
+ <span><math class="testfont"><mi>&#x6C;</mi></math>=<span>1D459</span></span>
+ <span><math class="testfont"><mi>&#x6D;</mi></math>=<span>1D45A</span></span>
+ <span><math class="testfont"><mi>&#x6E;</mi></math>=<span>1D45B</span></span><br/>
+ <span><math class="testfont"><mi>&#x6F;</mi></math>=<span>1D45C</span></span>
+ <span><math class="testfont"><mi>&#x70;</mi></math>=<span>1D45D</span></span>
+ <span><math class="testfont"><mi>&#x71;</mi></math>=<span>1D45E</span></span>
+ <span><math class="testfont"><mi>&#x72;</mi></math>=<span>1D45F</span></span>
+ <span><math class="testfont"><mi>&#x73;</mi></math>=<span>1D460</span></span>
+ <span><math class="testfont"><mi>&#x74;</mi></math>=<span>1D461</span></span>
+ <span><math class="testfont"><mi>&#x75;</mi></math>=<span>1D462</span></span>
+ <span><math class="testfont"><mi>&#x76;</mi></math>=<span>1D463</span></span>
+ <span><math class="testfont"><mi>&#x77;</mi></math>=<span>1D464</span></span>
+ <span><math class="testfont"><mi>&#x78;</mi></math>=<span>1D465</span></span><br/>
+ <span><math class="testfont"><mi>&#x79;</mi></math>=<span>1D466</span></span>
+ <span><math class="testfont"><mi>&#x7A;</mi></math>=<span>1D467</span></span>
+ <span><math class="testfont"><mi>&#x131;</mi></math>=<span>1D6A4</span></span>
+ <span><math class="testfont"><mi>&#x237;</mi></math>=<span>1D6A5</span></span>
+ <span><math class="testfont"><mi>&#x391;</mi></math>=<span>1D6E2</span></span>
+ <span><math class="testfont"><mi>&#x392;</mi></math>=<span>1D6E3</span></span>
+ <span><math class="testfont"><mi>&#x393;</mi></math>=<span>1D6E4</span></span>
+ <span><math class="testfont"><mi>&#x394;</mi></math>=<span>1D6E5</span></span>
+ <span><math class="testfont"><mi>&#x395;</mi></math>=<span>1D6E6</span></span>
+ <span><math class="testfont"><mi>&#x396;</mi></math>=<span>1D6E7</span></span><br/>
+ <span><math class="testfont"><mi>&#x397;</mi></math>=<span>1D6E8</span></span>
+ <span><math class="testfont"><mi>&#x398;</mi></math>=<span>1D6E9</span></span>
+ <span><math class="testfont"><mi>&#x399;</mi></math>=<span>1D6EA</span></span>
+ <span><math class="testfont"><mi>&#x39A;</mi></math>=<span>1D6EB</span></span>
+ <span><math class="testfont"><mi>&#x39B;</mi></math>=<span>1D6EC</span></span>
+ <span><math class="testfont"><mi>&#x39C;</mi></math>=<span>1D6ED</span></span>
+ <span><math class="testfont"><mi>&#x39D;</mi></math>=<span>1D6EE</span></span>
+ <span><math class="testfont"><mi>&#x39E;</mi></math>=<span>1D6EF</span></span>
+ <span><math class="testfont"><mi>&#x39F;</mi></math>=<span>1D6F0</span></span>
+ <span><math class="testfont"><mi>&#x3A0;</mi></math>=<span>1D6F1</span></span><br/>
+ <span><math class="testfont"><mi>&#x3A1;</mi></math>=<span>1D6F2</span></span>
+ <span><math class="testfont"><mi>&#x3F4;</mi></math>=<span>1D6F3</span></span>
+ <span><math class="testfont"><mi>&#x3A3;</mi></math>=<span>1D6F4</span></span>
+ <span><math class="testfont"><mi>&#x3A4;</mi></math>=<span>1D6F5</span></span>
+ <span><math class="testfont"><mi>&#x3A5;</mi></math>=<span>1D6F6</span></span>
+ <span><math class="testfont"><mi>&#x3A6;</mi></math>=<span>1D6F7</span></span>
+ <span><math class="testfont"><mi>&#x3A7;</mi></math>=<span>1D6F8</span></span>
+ <span><math class="testfont"><mi>&#x3A8;</mi></math>=<span>1D6F9</span></span>
+ <span><math class="testfont"><mi>&#x3A9;</mi></math>=<span>1D6FA</span></span>
+ <span><math class="testfont"><mi>&#x2207;</mi></math>=<span>1D6FB</span></span><br/>
+ <span><math class="testfont"><mi>&#x3B1;</mi></math>=<span>1D6FC</span></span>
+ <span><math class="testfont"><mi>&#x3B2;</mi></math>=<span>1D6FD</span></span>
+ <span><math class="testfont"><mi>&#x3B3;</mi></math>=<span>1D6FE</span></span>
+ <span><math class="testfont"><mi>&#x3B4;</mi></math>=<span>1D6FF</span></span>
+ <span><math class="testfont"><mi>&#x3B5;</mi></math>=<span>1D700</span></span>
+ <span><math class="testfont"><mi>&#x3B6;</mi></math>=<span>1D701</span></span>
+ <span><math class="testfont"><mi>&#x3B7;</mi></math>=<span>1D702</span></span>
+ <span><math class="testfont"><mi>&#x3B8;</mi></math>=<span>1D703</span></span>
+ <span><math class="testfont"><mi>&#x3B9;</mi></math>=<span>1D704</span></span>
+ <span><math class="testfont"><mi>&#x3BA;</mi></math>=<span>1D705</span></span><br/>
+ <span><math class="testfont"><mi>&#x3BB;</mi></math>=<span>1D706</span></span>
+ <span><math class="testfont"><mi>&#x3BC;</mi></math>=<span>1D707</span></span>
+ <span><math class="testfont"><mi>&#x3BD;</mi></math>=<span>1D708</span></span>
+ <span><math class="testfont"><mi>&#x3BE;</mi></math>=<span>1D709</span></span>
+ <span><math class="testfont"><mi>&#x3BF;</mi></math>=<span>1D70A</span></span>
+ <span><math class="testfont"><mi>&#x3C0;</mi></math>=<span>1D70B</span></span>
+ <span><math class="testfont"><mi>&#x3C1;</mi></math>=<span>1D70C</span></span>
+ <span><math class="testfont"><mi>&#x3C2;</mi></math>=<span>1D70D</span></span>
+ <span><math class="testfont"><mi>&#x3C3;</mi></math>=<span>1D70E</span></span>
+ <span><math class="testfont"><mi>&#x3C4;</mi></math>=<span>1D70F</span></span><br/>
+ <span><math class="testfont"><mi>&#x3C5;</mi></math>=<span>1D710</span></span>
+ <span><math class="testfont"><mi>&#x3C6;</mi></math>=<span>1D711</span></span>
+ <span><math class="testfont"><mi>&#x3C7;</mi></math>=<span>1D712</span></span>
+ <span><math class="testfont"><mi>&#x3C8;</mi></math>=<span>1D713</span></span>
+ <span><math class="testfont"><mi>&#x3C9;</mi></math>=<span>1D714</span></span>
+ <span><math class="testfont"><mi>&#x2202;</mi></math>=<span>1D715</span></span>
+ <span><math class="testfont"><mi>&#x3F5;</mi></math>=<span>1D716</span></span>
+ <span><math class="testfont"><mi>&#x3D1;</mi></math>=<span>1D717</span></span>
+ <span><math class="testfont"><mi>&#x3F0;</mi></math>=<span>1D718</span></span>
+ <span><math class="testfont"><mi>&#x3D5;</mi></math>=<span>1D719</span></span><br/>
+ <span><math class="testfont"><mi>&#x3F1;</mi></math>=<span>1D71A</span></span>
+ <span><math class="testfont"><mi>&#x3D6;</mi></math>=<span>1D71B</span></span>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight-ref.html
new file mode 100644
index 0000000000..c3e586f4dd
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight-ref.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>mathvariant attribute and font-style/font-weight (reference)</title>
+ <style>
+ .italic { font-style: italic; }
+ .bold { font-weight: bold; }
+ </style>
+ </head>
+ <body>
+ <p>This test passes if you see six lines of text (italic, italic, bold, bold, bold italic and bold italic) with the corresponding style applied:</p>
+ <p>
+ <math>
+ <mtext class="italic">italic</mtext>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mtext class="italic">italic</mtext>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mtext class="bold">bold</mtext>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mtext class="bold">bold</mtext>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mtext class="bold italic">bold italic</mtext>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mtext class="bold italic">bold italic</mtext>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight.html b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight.html
new file mode 100644
index 0000000000..793c687b09
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mathvariant-font-style-font-weight.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>mathvariant attribute and font-style/font-weight</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1788645">
+ <link rel="match" href="mathvariant-font-style-font-weight-ref.html"/>
+ <meta name="assert" content="Verify that a mathvariant attribute does not cancel the effect of font-style/font-weight.">
+ <style>
+ .italic { font-style: italic; }
+ .bold { font-weight: bold; }
+ </style>
+ </head>
+ <body>
+ <p>This test passes if you see six lines of text (italic, italic, bold, bold, bold italic and bold italic) with the corresponding style applied:</p>
+ <p>
+ <math mathvariant="normal">
+ <mtext class="italic">italic</mtext>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mtext mathvariant="normal" class="italic">italic</mtext>
+ </math>
+ </p>
+ <p>
+ <math mathvariant="normal">
+ <mtext class="bold">bold</mtext>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mtext mathvariant="normal" class="bold">bold</mtext>
+ </math>
+ </p>
+ <p>
+ <math mathvariant="normal">
+ <mtext class="bold italic">bold italic</mtext>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mtext mathvariant="normal" class="bold italic">bold italic</mtext>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight-ref.html
new file mode 100644
index 0000000000..63e6e2ba9c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>single-char mi and fontstyle/fontweight attributes (reference)</title>
+ <style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/mathvariant-italic.woff");
+ }
+ .testfont {
+ font-family: TestFont;
+ font-size: 32px;
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if you see <span class="testfont">&#x1D715;</span> rendered twice, without any bold or italic style applied:</p>
+ <p><math class="testfont"><mi mathvariant="normal">&#x1D715;</mi></math></p>
+ <p><math class="testfont"><mi mathvariant="normal">&#x1D715;</mi></math></p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight.html b/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight.html
new file mode 100644
index 0000000000..b6dd05ea20
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/mi-fontstyle-fontweight.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>single-char mi and fontstyle/fontweight attributes</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1789081">
+ <link rel="match" href="mi-fontstyle-fontweight-ref.html"/>
+ <meta name="assert" content="Verify that fontstyle/fontweight don't cancel the mathvariant transform on single-char mi elements.">
+ <style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/mathvariant-italic.woff");
+ }
+ .testfont {
+ font-family: TestFont;
+ font-size: 32px;
+ }
+ </style>
+ </head>
+ <body>
+ <p>Test passes if you see <span class="testfont">&#x1D715;</span> rendered twice, without any bold or italic style applied:</p>
+ <p><math class="testfont"><mi fontweight="bold">&#x2202;</mi></math></p>
+ <p><math class="testfont"><mi fontstyle="normal">&#x2202;</mi></math></p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/multi-column-layout.html b/testing/web-platform/tests/mathml/relations/css-styling/multi-column-layout.html
new file mode 100644
index 0000000000..88db5047e9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/multi-column-layout.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML inside multi-column</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg">
+<meta name="assert" content="Verify that putting MathML inside a multi-column list shouldn't affect its layout.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("DOMContentLoaded", function() {
+ var epsilon = 1;
+ var mfrac = document.getElementById("mfrac");
+ var num = mfrac.firstElementChild.getBoundingClientRect();
+ var denom = mfrac.lastElementChild.getBoundingClientRect();
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_approx_equals(num.width, 30, epsilon, "numerator width");
+ assert_approx_equals(num.height, 40, epsilon, "numerator height");
+ assert_approx_equals(denom.width, 50, epsilon, "numerator width");
+ assert_approx_equals(denom.height, 60, epsilon, "numerator height");
+ }, "mspace layout in multicol");
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mfrac());
+ assert_greater_than_equal(denom.bottom - num.top,
+ (40 + 60),
+ "numerator is above the denominator");
+ assert_approx_equals((num.left + num.right) / 2,
+ (denom.left + denom.right) / 2,
+ epsilon, "numerator and denominator are horizontally aligned");
+ }, "mfrac layout in multicol");
+ done();
+ });
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <div style="column-width: 10em; list-style-type: decimal;">
+ <ol>
+ <li>blah</li>
+ <li>
+ <math>
+ <mfrac id="mfrac">
+ <mspace width="30px" height="40px" style="background: cyan"></mspace>
+ <mspace width="50px" height="60px" style="background: yellow"></mspace>
+ </mfrac>
+ </li>
+ <li>blah</li>
+ <li>blah</li>
+ <li>blah</li>
+ </ol>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/not-participating-to-parent-layout.html b/testing/web-platform/tests/mathml/relations/css-styling/not-participating-to-parent-layout.html
new file mode 100644
index 0000000000..0952679c62
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/not-participating-to-parent-layout.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Elements not participating to the layout of their parent</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that display: none and out-of-flow positioned elements do not participate to layout of their parent.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag) ||
+ FragmentHelper.isEmpty(tag))
+ continue;
+ ["display: none",
+ "display: contents",
+ "position: absolute",
+ "position: fixed"
+ ].forEach(style => {
+ document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\
+<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\
+<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\
+</div>`);
+ var div = document.body.lastElementChild;
+
+ var elementContainer = div.firstElementChild;
+ var elementContainerWidth = elementContainer.getBoundingClientRect().width;
+ var element = FragmentHelper.element(elementContainer);
+ if (style === "display: contents" &&
+ !element.classList.contains("mathml-container")) {
+ // A "display: contents" MathML child is not participating to
+ // parent layout because its computed style is "display: none".
+ // If we cannot append a MathML child then skip that test.
+ return;
+ }
+ FragmentHelper.forceNonEmptyElement(element);
+ var allowInvalid = true;
+ var child = FragmentHelper.appendChild(element, allowInvalid);
+ child.setAttribute("style", style);
+
+ var referenceContainer = div.lastElementChild;
+ var referenceContainerWidth = referenceContainer.getBoundingClientRect().width;
+ var reference = FragmentHelper.element(referenceContainer);
+ FragmentHelper.forceNonEmptyElement(reference);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ assert_approx_equals(elementContainerWidth, referenceContainerWidth, epsilon);
+ }, `${tag} preferred width calculation is not affected by children with "${style}" style`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ compareLayout(element, reference, epsilon);
+ }, `${tag} layout is not affected by children with "${style}" style`);
+
+ div.style = "display: none;"; // Hide the div after measurement.
+ });
+ }
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001-ref.html
new file mode 100644
index 0000000000..447c5b722a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Absolutely positioned (reference)</title>
+<body>
+ <p>Test passes if you see a green square and no red.</p>
+ <div style="position: absolute; left: 100px; top: 100px;">
+ <math>
+ <mrow>
+ <mspace width="100px" height="300px" style="background: green"/>
+ <mspace width="100px" height="300px" style="background: green"/>
+ <mspace width="100px" height="300px" style="background: green"/>
+ </mrow>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001.html
new file mode 100644
index 0000000000..9a7851ba23
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/absolutely-positioned-001.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Absolutely positioned</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<link rel="match" href="absolutely-positioned-001-ref.html"/>
+<meta name="assert" content="Verify visual rendering of absolutely positioned mtext elements.">
+<body>
+ <p>Test passes if you see a green square and no red.</p>
+ <div style="position: absolute; left: 100px; top: 100px;">
+ <math>
+ <mrow>
+ <mspace width="100px" height="300px" style="background: green"/>
+ <mspace width="100px" height="300px" style="background: red"/>
+ <mspace width="100px" height="300px" style="background: green"/>
+ <mtext style="position: absolute; left: 100px; top: 0px;"><span style="display: inline-block; width: 50px; height: 300px; background: green"></span></mtext>
+ <mtext style="position: absolute; left: 150px; top: 0px;"><span style="display: inline-block; width: 50px; height: 150px; background: green"></span></mtext>
+ <mtext style="position: absolute; left: 150px; top: 150px;"><span style="display: inline-block; width: 50px; height: 150px; background: green"></span></mtext>
+ </mrow>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/all-mathml-containers.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/all-mathml-containers.html
new file mode 100644
index 0000000000..9069b92637
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/all-mathml-containers.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>absolutely positioned in all MathML elements</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that absolutely positioned node works in all MathML elements.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<style>
+ /* override display: none on children of maction/semantics */
+ maction > *, semantics > * {
+ display: math;
+ }
+</style>
+<script>
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ ["absolute", "fixed"].forEach(positionValue => {
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag) ||
+ FragmentHelper.isEmpty(tag))
+ continue;
+ document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\
+<math>${MathMLFragments[tag]}</math>\
+</div>`);
+ let div = document.body.lastElementChild;
+ let element = FragmentHelper.element(div.firstElementChild);
+ FragmentHelper.forceNonEmptyElement(element);
+ if (element.classList.contains("mathml-container") ||
+ element.classList.contains("foreign-container")) {
+ for (let i = 0; i < 5; i++) {
+ FragmentHelper.appendChild(element);
+ }
+ }
+
+ let middleChild;
+ if (element.children.length >= 2) {
+ middleChild = FragmentHelper.appendChild(element, true /*allowInvalid*/);
+ middleChild.setAttribute("style", `position: ${positionValue}; left: 300px; top: 400px`);
+ let middlePosition = Math.floor(element.children.length/2);
+ element.insertBefore(middleChild, element.children[middlePosition]);
+ }
+
+ let firstChild = FragmentHelper.appendChild(element, true /*allowInvalid*/);
+ firstChild.setAttribute("style", `position: ${positionValue}; left: 100px; top: 200px`);
+ element.insertBefore(firstChild, element.firstElementChild);
+
+ let lastChild = FragmentHelper.appendChild(element, true /*allowInvalid*/);
+ lastChild.setAttribute("style", `position: ${positionValue}; left: 500px; top: 600px`);
+
+ let referenceBox;
+ switch (positionValue) {
+ case "absolute":
+ // Use the absolutely positioned div ancestor.
+ referenceBox = div.getBoundingClientRect();
+ break
+ case "fixed":
+ // Use the viewport.
+ referenceBox = {left: 0, top: 0};
+ break;
+ default:
+ throw "reference box not defined";
+ }
+
+ let firstChildBox = firstChild.getBoundingClientRect();
+ let lastChildBox = lastChild.getBoundingClientRect();
+ let middleChildBox;
+ if (middleChild) {
+ middleChildBox = middleChild.getBoundingClientRect();
+ }
+
+ let epsilon = 1;
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ assert_approx_equals(firstChildBox.left - referenceBox.left, 100, epsilon);
+ assert_approx_equals(firstChildBox.top - referenceBox.top, 200, epsilon);
+ if (middleChildBox) {
+ assert_approx_equals(middleChildBox.left - referenceBox.left, 300, epsilon);
+ assert_approx_equals(middleChildBox.top - referenceBox.top, 400, epsilon);
+ }
+ assert_approx_equals(lastChildBox.left - referenceBox.left, 500, epsilon);
+ assert_approx_equals(lastChildBox.top - referenceBox.top, 600, epsilon);
+ }, `position: ${positionValue}; children in ${tag}`);
+
+ div.style = "display: none;"; // Hide the div after measurement.
+ }
+ });
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001-ref.html
new file mode 100644
index 0000000000..03b9f56698
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8"/>
+<title>Fixed positioned (reference)</title>
+<style>
+ body { overflow: hidden; }
+</style>
+<body>
+ <div style="position: absolute; left: 100px; top: 200px;
+ height: 3000px; width: 3000px;">
+ <math>
+ <mrow>
+ <mspace width="100px" height="300px" style="background: green"/>
+ <mspace width="100px" height="300px" style="background: green"/>
+ <mspace width="100px" height="300px" style="background: green"/>
+ </mrow>
+ </math>
+ <p>Test passes if you see a green square and no red.</p>
+ </div>
+ <script>
+ requestAnimationFrame(() => {
+ window.scrollTo(50, 100);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001.html b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001.html
new file mode 100644
index 0000000000..994174162c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/out-of-flow/fixed-positioned-001.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8"/>
+<title>Fixed positioned</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<link rel="match" href="fixed-positioned-001-ref.html"/>
+<meta name="assert" content="Verify visual rendering of fixed positioned mtext elements.">
+<style>
+ body { overflow: hidden; }
+</style>
+<body>
+ <div style="position: absolute; left: 100px; top: 200px;
+ height: 3000px; width: 3000px;">
+ <math>
+ <mrow>
+ <mspace width="100px" height="300px" style="background: green"/>
+ <mspace width="100px" height="300px" style="background: red"/>
+ <mspace width="100px" height="300px" style="background: green"/>
+ <mtext style="position: fixed; left: 150px; top: 100px;"><span style="display: inline-block; width: 50px; height: 300px; background: green"></span></mtext>
+ <mtext style="position: fixed; left: 200px; top: 100px;"><span style="display: inline-block; width: 50px; height: 150px; background: green"></span></mtext>
+ <mtext style="position: fixed; left: 200px; top: 250px;"><span style="display: inline-block; width: 50px; height: 150px; background: green"></span></mtext>
+ </mrow>
+ </math>
+ <p>Test passes if you see a green square and no red.</p>
+ </div>
+ <script>
+ requestAnimationFrame(() => {
+ window.scrollTo(50, 100);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/overflow/computed-value-001.html b/testing/web-platform/tests/mathml/relations/css-styling/overflow/computed-value-001.html
new file mode 100644
index 0000000000..0510f1da6d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/overflow/computed-value-001.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>overflow on MathML elements</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet">
+<meta name="assert" content="overflow can be overridden on MathML elements.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<style>
+ /* selector defined in mathml-fragments.js */
+ .element {
+ overflow: scroll;
+ }
+</style>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="container">
+ <math class="element"></math>
+ </div>
+ <script>
+ test(function () {
+ var container = document.getElementById("container");
+ for (tag in MathMLFragments) {
+ // Skip mtable as browsers don't have interoperable behavior for
+ // display: table.
+ // See https://github.com/w3c/csswg-drafts/issues/8133
+ if (tag == "mtable")
+ continue;
+ container.insertAdjacentHTML("beforeend", `<math>${MathMLFragments[tag]}</math>`);
+ }
+ let unknownElement = FragmentHelper.createElement("unknown");
+ unknownElement.setAttribute("class", "element");
+ container.appendChild(unknownElement);
+ Array.from(document.getElementsByClassName("element")).forEach(element => {
+ var tag = element.tagName;
+ var style = window.getComputedStyle(element);
+ assert_equals(style["overflow"], "scroll", `overflow on ${tag}`);
+ }, `overflow can be overridden on all MathML elements`);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-001.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-001.html
new file mode 100644
index 0000000000..fd86388ccd
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-001.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>border</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that border is taken into account.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/box-comparison.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-border")
+ assert_approx_equals(s.left, 20, epsilon, "left border");
+ assert_approx_equals(s.right, 30, epsilon, "right border");
+ assert_approx_equals(s.top, 40, epsilon, "top border");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom border");
+ var b = document.getElementById("mrow-border").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width");
+ assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height");
+ }, "Border properties on mrow");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_true(MathMLFeatureDetection.has_dir());
+ var s = measureSpaceAround("mrow-border-rtl")
+ assert_approx_equals(s.left, 20, epsilon, "left border");
+ assert_approx_equals(s.right, 30, epsilon, "right border");
+ assert_approx_equals(s.top, 40, epsilon, "top border");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom border");
+ var b = document.getElementById("mrow-border-rtl").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width");
+ assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height");
+ }, "Border properties on mrow (rtl)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-border-shorthand")
+ assert_approx_equals(s.left, 20, epsilon, "left border");
+ assert_approx_equals(s.right, 20, epsilon, "right border");
+ assert_approx_equals(s.top, 20, epsilon, "top border");
+ assert_approx_equals(s.bottom, 20, epsilon, "bottom border");
+ var b = document.getElementById("mrow-border-shorthand").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 20, epsilon, "element width");
+ assert_approx_equals(b.height, 20 + 50 + 20, epsilon, "element height");
+ }, "Border properties on mrow (shorthand)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-border-logical")
+ assert_approx_equals(s.left, 20, epsilon, "left border");
+ assert_approx_equals(s.right, 30, epsilon, "right border");
+ assert_approx_equals(s.top, 40, epsilon, "top border");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom border");
+ var b = document.getElementById("mrow-border-logical").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width");
+ assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height");
+ }, "Border properties on mrow (logical)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_true(MathMLFeatureDetection.has_dir());
+ var s = measureSpaceAround("mrow-border-logical-rtl")
+ assert_approx_equals(s.left, 30, epsilon, "left border");
+ assert_approx_equals(s.right, 20, epsilon, "right border");
+ assert_approx_equals(s.top, 40, epsilon, "top border");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom border");
+ var b = document.getElementById("mrow-border-logical-rtl").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width");
+ assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height");
+ }, "Border properties on mrow (logical, rtl)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-border-logical-shorthand")
+ assert_approx_equals(s.left, 20, epsilon, "left border");
+ assert_approx_equals(s.right, 20, epsilon, "right border");
+ assert_approx_equals(s.top, 30, epsilon, "top border");
+ assert_approx_equals(s.bottom, 30, epsilon, "bottom border");
+ var b = document.getElementById("mrow-border-logical-shorthand").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 20, epsilon, "element width");
+ assert_approx_equals(b.height, 30 + 50 + 30, epsilon, "element height");
+ }, "Border properties on mrow (logical, shorthand)");
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-border"
+ style="border-left: 20px solid transparent;
+ border-right: 30px solid transparent;
+ border-top: 40px solid transparent;
+ border-bottom: 50px solid transparent;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math dir="rtl">
+ <mrow>
+ <mrow id="mrow-border-rtl"
+ style="border-left: 20px solid transparent;
+ border-right: 30px solid transparent;
+ border-top: 40px solid transparent;
+ border-bottom: 50px solid transparent;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-border-shorthand"
+ style="border: 20px solid transparent;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-border-logical"
+ style="border-inline-start: 20px solid transparent;
+ border-inline-end: 30px solid transparent;
+ border-block-start: 40px solid transparent;
+ border-block-end: 50px solid transparent;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math dir="rtl">
+ <mrow>
+ <mrow id="mrow-border-logical-rtl"
+ style="border-inline-start: 20px solid transparent;
+ border-inline-end: 30px solid transparent;
+ border-block-start: 40px solid transparent;
+ border-block-end: 50px solid transparent;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-border-logical-shorthand"
+ style="border-inline: 20px solid transparent;
+ border-block: 30px solid transparent;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-002.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-002.html
new file mode 100644
index 0000000000..bfb7f76adc
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/border-002.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>border</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that border is taken into account.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/box-comparison.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag))
+ continue;
+
+ var style = "border-left: 30px solid; border-right: 40px solid; border-top: 50px solid; border-bottom: 60px solid;";
+
+ if (FragmentHelper.isEmpty(tag)) {
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSizeWithAndWithoutStyle(tag, style);
+ assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "left/right border");
+ assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "top/bottom border");
+ assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width");
+ }, `Border properties on ${tag}`);
+ continue;
+ }
+
+ var default_border = tag === "merror" ? 1 : 0;
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSpaceWithAndWithoutStyle(tag, style);
+ assert_approx_equals(s.left_delta + default_border, 30, epsilon, "left border");
+ assert_approx_equals(s.right_delta + default_border, 40, epsilon, "right border");
+ assert_approx_equals(s.top_delta + default_border, 50, epsilon, "top border");
+ assert_approx_equals(s.bottom_delta + default_border, 60, epsilon, "bottom border");
+ assert_approx_equals(s.element_width_delta + 2 * default_border, 30 + 40, epsilon, "element width");
+ assert_approx_equals(s.element_height_delta + 2 * default_border, 50 + 60, epsilon, "element height");
+ assert_approx_equals(s.preferred_width_delta + 2 * default_border, 30 + 40, epsilon, "element preferred width");
+ }, `Border properties on ${tag}`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSpaceWithAndWithoutStyle(tag, style, null, "rtl");
+ assert_approx_equals(s.left_delta + default_border, 30, epsilon, "left border");
+ assert_approx_equals(s.right_delta + default_border, 40, epsilon, "right border");
+ assert_approx_equals(s.top_delta + default_border, 50, epsilon, "top border");
+ assert_approx_equals(s.bottom_delta + default_border, 60, epsilon, "bottom border");
+ assert_approx_equals(s.element_width_delta + 2 * default_border, 30 + 40, epsilon, "element width");
+ assert_approx_equals(s.element_height_delta + 2 * default_border, 50 + 60, epsilon, "element height");
+ assert_approx_equals(s.preferred_width_delta + 2 * default_border, 30 + 40, epsilon, "element preferred width");
+ }, `Border properties on ${tag} (rtl)`);
+ }
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-001.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-001.html
new file mode 100644
index 0000000000..eabb6f46c7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-001.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>margin</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that margin is taken into account.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/box-comparison.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-margin")
+ assert_approx_equals(s.left, 20, epsilon, "left margin");
+ assert_approx_equals(s.right, 30, epsilon, "right margin");
+ assert_approx_equals(s.top, 40, epsilon, "top margin");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom margin");
+ var b = document.getElementById("mrow-margin").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 50, epsilon, "element width");
+ assert_approx_equals(b.height, 50, epsilon, "element height");
+ }, "Margin properties on mrow");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_true(MathMLFeatureDetection.has_dir());
+ var s = measureSpaceAround("mrow-margin-rtl")
+ assert_approx_equals(s.left, 20, epsilon, "left margin");
+ assert_approx_equals(s.right, 30, epsilon, "right margin");
+ assert_approx_equals(s.top, 40, epsilon, "top margin");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom margin");
+ var b = document.getElementById("mrow-margin-rtl").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 50, epsilon, "element width");
+ assert_approx_equals(b.height, 50, epsilon, "element height");
+ }, "Margin properties on mrow (rtl)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-margin-shorthand")
+ assert_approx_equals(s.left, 20, epsilon, "left margin");
+ assert_approx_equals(s.right, 20, epsilon, "right margin");
+ assert_approx_equals(s.top, 20, epsilon, "top margin");
+ assert_approx_equals(s.bottom, 20, epsilon, "bottom margin");
+ var b = document.getElementById("mrow-margin-shorthand").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 50, epsilon, "element width");
+ assert_approx_equals(b.height, 50, epsilon, "element height");
+ }, "Margin properties on mrow (shorthand)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-margin-logical")
+ assert_approx_equals(s.left, 20, epsilon, "left margin");
+ assert_approx_equals(s.right, 30, epsilon, "right margin");
+ assert_approx_equals(s.top, 40, epsilon, "top margin");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom margin");
+ var b = document.getElementById("mrow-margin-logical").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 50, epsilon, "element width");
+ assert_approx_equals(b.height, 50, epsilon, "element height");
+ }, "Margin properties on mrow (logical)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_true(MathMLFeatureDetection.has_dir());
+ var s = measureSpaceAround("mrow-margin-logical-rtl")
+ assert_approx_equals(s.left, 30, epsilon, "left margin");
+ assert_approx_equals(s.right, 20, epsilon, "right margin");
+ assert_approx_equals(s.top, 40, epsilon, "top margin");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom margin");
+ var b = document.getElementById("mrow-margin-logical-rtl").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 50, epsilon, "element width");
+ assert_approx_equals(b.height, 50, epsilon, "element height");
+ }, "Margin properties on mrow (logical, rtl)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-margin-logical-shorthand")
+ assert_approx_equals(s.left, 20, epsilon, "left margin");
+ assert_approx_equals(s.right, 20, epsilon, "right margin");
+ assert_approx_equals(s.top, 30, epsilon, "top margin");
+ assert_approx_equals(s.bottom, 30, epsilon, "bottom margin");
+ var b = document.getElementById("mrow-margin-logical-shorthand").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 50, epsilon, "element width");
+ assert_approx_equals(b.height, 50, epsilon, "element height");
+ }, "Margin properties on mrow (logical, shorthand)");
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-margin"
+ style="margin-left: 20px;
+ margin-right: 30px;
+ margin-top: 40px;
+ margin-bottom: 50px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math dir="rtl">
+ <mrow>
+ <mrow id="mrow-margin-rtl"
+ style="margin-left: 20px;
+ margin-right: 30px;
+ margin-top: 40px;
+ margin-bottom: 50px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-margin-shorthand"
+ style="margin: 20px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-margin-logical"
+ style="margin-inline-start: 20px;
+ margin-inline-end: 30px;
+ margin-block-start: 40px;
+ margin-block-end: 50px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math dir="rtl">
+ <mrow>
+ <mrow id="mrow-margin-logical-rtl"
+ style="margin-inline-start: 20px;
+ margin-inline-end: 30px;
+ margin-block-start: 40px;
+ margin-block-end: 50px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-margin-logical-shorthand"
+ style="margin-inline: 20px;
+ margin-block: 30px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-002.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-002.html
new file mode 100644
index 0000000000..b560ed125c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-002.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>margin</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that margin is taken into account.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/box-comparison.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag))
+ continue;
+
+ var style = "margin-left: 30px; margin-right: 40px; margin-top: 50px; margin-bottom: 60px;";
+
+ if (FragmentHelper.isEmpty(tag)) {
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSizeWithAndWithoutStyle(tag, style);
+ assert_approx_equals(s.width_delta, 30 + 40, epsilon, "left/right margin");
+ assert_approx_equals(s.height_delta, 50 + 60, epsilon, "top/bottom margin");
+ assert_approx_equals(s.element_width_delta, 0, epsilon, "element width");
+ assert_approx_equals(s.element_height_delta, 0, epsilon, "element height");
+ assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width");
+ }, `Margin properties on ${tag}`);
+ continue;
+ }
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSpaceWithAndWithoutStyle(tag, style);
+ assert_approx_equals(s.left_delta, 30, epsilon, "left margin");
+ assert_approx_equals(s.right_delta, 40, epsilon, "right margin");
+ assert_approx_equals(s.top_delta, 50, epsilon, "top margin");
+ assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom margin");
+ assert_approx_equals(s.element_width_delta, 0, epsilon, "element width");
+ assert_approx_equals(s.element_height_delta, 0, epsilon, "element height");
+ assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width");
+ }, `Margin properties on ${tag}`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSpaceWithAndWithoutStyle(tag, style, null, "rtl");
+ assert_approx_equals(s.left_delta, 30, epsilon, "left margin");
+ assert_approx_equals(s.right_delta, 40, epsilon, "right margin");
+ assert_approx_equals(s.top_delta, 50, epsilon, "top margin");
+ assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom margin");
+ assert_approx_equals(s.element_width_delta, 0, epsilon, "element width");
+ assert_approx_equals(s.element_height_delta, 0, epsilon, "element height");
+ assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width");
+ }, `Margin properties on ${tag} (rtl)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ // Apply the same margin style on the parent mrow.
+ // The margins are not collapsed so they should be added twice.
+ var s = compareSpaceWithAndWithoutStyle(tag, style, style);
+ assert_approx_equals(s.left_delta, 30 * 2, epsilon, "left margin");
+ assert_approx_equals(s.right_delta, 40 * 2, epsilon, "right margin");
+ assert_approx_equals(s.top_delta, 50 * 2, epsilon, "top margin");
+ assert_approx_equals(s.bottom_delta, 60 * 2, epsilon, "bottom margin");
+ assert_approx_equals(s.element_width_delta, 0, epsilon, "element width");
+ assert_approx_equals(s.element_height_delta, 0, epsilon, "element height");
+ assert_approx_equals(s.preferred_width_delta, (30 + 40) * 2, epsilon, "preferred width");
+ }, `Margin properties on ${tag} (no margin-collapsing)`);
+ }
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-003.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-003.html
new file mode 100644
index 0000000000..3b6b2a38db
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/margin-003.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>margin</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that margin is taken into account on children.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag) ||
+ FragmentHelper.isEmpty(tag) ||
+ FragmentHelper.isTokenElement(tag) ||
+ tag == "semantics" ||
+ tag == "maction" ||
+ tag == "mtable")
+ continue;
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+
+ document.body.insertAdjacentHTML("beforeend", `<hr/><div>\
+<div style="display: inline-block; border: 1px dashed blue;"><math>${MathMLFragments[tag]}</math></div><br/>\
+<div style="display: inline-block; border: 1px dashed green;"><math>${MathMLFragments[tag]}</math></div>\
+</div>`);
+
+ var div = document.body.lastElementChild;
+ var elementShrinkWrapContainer = div.firstElementChild;
+ var element = elementShrinkWrapContainer.firstElementChild.firstElementChild;
+ var elementContainer = div.firstElementChild;
+ var referenceShrinkWrapContainer = div.lastElementChild;
+ var reference = referenceShrinkWrapContainer.firstElementChild.firstElementChild;
+
+ FragmentHelper.forceNonEmptyElement(element);
+ FragmentHelper.forceNonEmptyElement(reference);
+
+ var mspaceWidth = 20, mspaceHeight = 40, mspaceDepth = 30;
+ var marginLeft = 10, marginRight = 15, marginTop = 20, marginBottom = 25;
+ Array.from(element.children).forEach(mrow => {
+ mrow.outerHTML = `<mspace width="${mspaceWidth}px" height="${mspaceHeight}px" depth='${mspaceDepth}px' style='background: blue; margin-left: ${marginLeft}px; margin-right: ${marginRight}px; margin-top: ${marginTop}px; margin-bottom: ${marginBottom}px;'></mspace>`;
+ });
+
+ Array.from(reference.children).forEach(mrow => {
+ mrow.outerHTML = `<mspace width="${marginLeft+mspaceWidth+marginRight}px" height="${mspaceHeight+marginTop}px" depth='${mspaceDepth+marginBottom}px' style='background: green;'></mspace>`;
+ });
+
+ // Compare sizes.
+ compareSize(element, reference, epsilon);
+
+ // Compare children positions.
+ var elementBox = element.getBoundingClientRect();
+ var referenceBox = reference.getBoundingClientRect();
+ for (var i = 0; i < element.children.length; i++) {
+ var childBox = element.children[i].getBoundingClientRect();
+ var referenceChildBox = reference.children[i].getBoundingClientRect();
+ assert_approx_equals(childBox.width + marginLeft + marginRight, referenceChildBox.width, epsilon, "inline size (child ${i})");
+ assert_approx_equals(childBox.height + marginTop + marginBottom, referenceChildBox.height, epsilon, "block size (child ${i})");
+
+ assert_approx_equals(childBox.left - marginLeft - elementBox.left,
+ referenceChildBox.left - referenceBox.left,
+ epsilon,
+ `inline position (child ${i})`);
+ assert_approx_equals(childBox.top - marginTop - elementBox.top,
+ referenceChildBox.top - referenceBox.top,
+ epsilon,
+ `block position (child ${i})`);
+ }
+
+ // Compare preferred widths.
+ assert_approx_equals(elementShrinkWrapContainer.offsetWidth, referenceShrinkWrapContainer.offsetWidth, epsilon, "preferred width");
+
+ }, `Margin properties on the children of ${tag}`);
+ }
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-001.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-001.html
new file mode 100644
index 0000000000..b6d4901f36
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-001.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>padding</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that padding is taken into account.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/box-comparison.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-padding")
+ assert_approx_equals(s.left, 20, epsilon, "left padding");
+ assert_approx_equals(s.right, 30, epsilon, "right padding");
+ assert_approx_equals(s.top, 40, epsilon, "top padding");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom padding");
+ var b = document.getElementById("mrow-padding").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width");
+ assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height");
+ }, "Padding properties on mrow");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_true(MathMLFeatureDetection.has_dir());
+ var s = measureSpaceAround("mrow-padding-rtl")
+ assert_approx_equals(s.left, 20, epsilon, "left padding");
+ assert_approx_equals(s.right, 30, epsilon, "right padding");
+ assert_approx_equals(s.top, 40, epsilon, "top padding");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom padding");
+ var b = document.getElementById("mrow-padding-rtl").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width");
+ assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height");
+ }, "Padding properties on mrow (rtl)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-padding-shorthand")
+ assert_approx_equals(s.left, 20, epsilon, "left padding");
+ assert_approx_equals(s.right, 20, epsilon, "right padding");
+ assert_approx_equals(s.top, 20, epsilon, "top padding");
+ assert_approx_equals(s.bottom, 20, epsilon, "bottom padding");
+ var b = document.getElementById("mrow-padding-shorthand").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 20, epsilon, "element width");
+ assert_approx_equals(b.height, 20 + 50 + 20, epsilon, "element height");
+ }, "Padding properties on mrow (shorthand)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-padding-logical")
+ assert_approx_equals(s.left, 20, epsilon, "left padding");
+ assert_approx_equals(s.right, 30, epsilon, "right padding");
+ assert_approx_equals(s.top, 40, epsilon, "top padding");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom padding");
+ var b = document.getElementById("mrow-padding-logical").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width");
+ assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height");
+ }, "Padding properties on mrow (logical)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_true(MathMLFeatureDetection.has_dir());
+ var s = measureSpaceAround("mrow-padding-logical-rtl")
+ assert_approx_equals(s.left, 30, epsilon, "left padding");
+ assert_approx_equals(s.right, 20, epsilon, "right padding");
+ assert_approx_equals(s.top, 40, epsilon, "top padding");
+ assert_approx_equals(s.bottom, 50, epsilon, "bottom padding");
+ var b = document.getElementById("mrow-padding-logical-rtl").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 30, epsilon, "element width");
+ assert_approx_equals(b.height, 40 + 50 + 50, epsilon, "element height");
+ }, "Padding properties on mrow (logical, rtl)");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var s = measureSpaceAround("mrow-padding-logical-shorthand")
+ assert_approx_equals(s.left, 20, epsilon, "left padding");
+ assert_approx_equals(s.right, 20, epsilon, "right padding");
+ assert_approx_equals(s.top, 30, epsilon, "top padding");
+ assert_approx_equals(s.bottom, 30, epsilon, "bottom padding");
+ var b = document.getElementById("mrow-padding-logical-shorthand").
+ getBoundingClientRect();
+ assert_approx_equals(b.width, 20 + 50 + 20, epsilon, "element width");
+ assert_approx_equals(b.height, 30 + 50 + 30, epsilon, "element height");
+ }, "Padding properties on mrow (logical, shorthand)");
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-padding"
+ style="padding-left: 20px;
+ padding-right: 30px;
+ padding-top: 40px;
+ padding-bottom: 50px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math dir="rtl">
+ <mrow>
+ <mrow id="mrow-padding-rtl"
+ style="padding-left: 20px;
+ padding-right: 30px;
+ padding-top: 40px;
+ padding-bottom: 50px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-padding-shorthand"
+ style="padding: 20px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-padding-logical"
+ style="padding-inline-start: 20px;
+ padding-inline-end: 30px;
+ padding-block-start: 40px;
+ padding-block-end: 50px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math dir="rtl">
+ <mrow>
+ <mrow id="mrow-padding-logical-rtl"
+ style="padding-inline-start: 20px;
+ padding-inline-end: 30px;
+ padding-block-start: 40px;
+ padding-block-end: 50px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow id="mrow-padding-logical-shorthand"
+ style="padding-inline: 20px;
+ padding-block: 30px;">
+ <mspace width="50px" height="50px"></mspace>
+ </mrow>
+ </mrow>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-002.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-002.html
new file mode 100644
index 0000000000..89d3bdc7ef
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-002.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>padding</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that padding is taken into account.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/box-comparison.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag))
+ continue;
+
+ var defaultInlinePadding = (tag === "mfrac" ? 1 : 0);
+ var style = `padding-left: ${defaultInlinePadding + 30}px; padding-right: ${defaultInlinePadding + 40}px; padding-top: 50px; padding-bottom: 60px;`;
+
+ if (FragmentHelper.isEmpty(tag)) {
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSizeWithAndWithoutStyle(tag, style);
+ assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "left/right padding");
+ assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "top/bottom padding");
+ assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width");
+ }, `Padding properties on ${tag}`);
+ continue;
+ }
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSpaceWithAndWithoutStyle(tag, style);
+ assert_approx_equals(s.left_delta, 30, epsilon, "left padding");
+ assert_approx_equals(s.right_delta, 40, epsilon, "right padding");
+ assert_approx_equals(s.top_delta, 50, epsilon, "top padding");
+ assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom padding");
+ assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "element width");
+ assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "element height");
+ assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width");
+ }, `Padding properties on ${tag}`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var s = compareSpaceWithAndWithoutStyle(tag, style, "rtl");
+ assert_approx_equals(s.left_delta, 30, epsilon, "left padding");
+ assert_approx_equals(s.right_delta, 40, epsilon, "right padding");
+ assert_approx_equals(s.top_delta, 50, epsilon, "top padding");
+ assert_approx_equals(s.bottom_delta, 60, epsilon, "bottom padding");
+ assert_approx_equals(s.element_width_delta, 30 + 40, epsilon, "element width");
+ assert_approx_equals(s.element_height_delta, 50 + 60, epsilon, "element height");
+ assert_approx_equals(s.preferred_width_delta, 30 + 40, epsilon, "preferred width");
+ }, `Padding properties on ${tag} (rtl)`);
+ }
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001-ref.html
new file mode 100644
index 0000000000..150a650bc2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Padding/border/margin</title>
+<body>
+ <p>This test passes if you see a purple square of side 100px, surrounded by a
+ 10px blue padding, surrounded by a 10px blue/yellow dashed border, itself
+ surrounded by a 10px pink margin.</p>
+ </div>
+ <div style="background: pink; position: absolute; left: 10px; top: 3em;">
+ <div style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;">
+ <div style="width: 100px; height: 100px; background: purple;"></div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html
new file mode 100644
index 0000000000..b0fb17c7d2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-001.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Padding/border/margin</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<link rel="match" href="padding-border-margin-001-ref.html"/>
+<meta name="assert" content="Verify visual rendering of padding/border/margin on the mrow element.">
+<body>
+ <p>This test passes if you see a purple square of side 100px, surrounded by a
+ 10px blue padding, surrounded by a 10px blue/yellow dashed border, itself
+ surrounded by a 10px pink margin.</p>
+ <div style="background: pink; position: absolute; left: 10px; top: 3em;">
+ <math>
+ <mrow style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;">
+ <mspace width="100px" height="100px" style="background: purple;"></mspace>
+ </mrow>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002-ref.html
new file mode 100644
index 0000000000..e13a9f47ff
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Padding/border/margin on largeop (reference)</title>
+<body>
+ <p>This test passes if you see a cyan rectangle of width 300px and
+ height 1500px, surrounded by a 10px blue padding, surrounded by a 10px
+ blue/yellow dashed border, itself
+ surrounded by a 10px pink margin.</p>
+ </div>
+ <div style="background: pink; position: absolute; left: 10px; top: 4em;">
+ <div style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;">
+ <div style="width: 300px; height: 1500px; background: cyan;"></div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002.html
new file mode 100644
index 0000000000..4559fc49ce
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-002.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Padding/border/margin on largeop</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-math-style-property">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-operators">
+<link rel="match" href="padding-border-margin-002-ref.html"/>
+<meta name="assert" content="Verify visual rendering of padding/border/margin on a displaystyle mo element with the largeop property.">
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/largeop-displayoperatorminheight5000.woff");
+ }
+ math {
+ /* Largeop variant for U+2AFF has width 100px
+ and height 300 * 5000 / 1000 = 1500px */
+ font-family: TestFont;
+ font-size: 300px;
+ }
+</style>
+<body>
+ <p>This test passes if you see a cyan rectangle of width 300px and
+ height 1500px, surrounded by a 10px blue padding, surrounded by a 10px
+ blue/yellow dashed border, itself
+ surrounded by a 10px pink margin.</p>
+ <div style="background: pink; position: absolute; left: 10px; top: 4em;">
+ <math displaystyle="true">
+ <mo largeop="true" lspace="0" rspace="0" style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px; color: cyan;">&#x2AFF;</mo>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003-ref.html
new file mode 100644
index 0000000000..275494ddd8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Padding/border/margin on an operator, stretchy along the block axis (reference)</title>
+<body>
+ <p>This test passes if you see a cyan rectangle of width 300px and
+ height 1500px, surrounded by a 10px blue padding, surrounded by a 10px
+ blue/yellow dashed border, itself
+ surrounded by a 10px pink margin.</p>
+ </div>
+ <div style="background: pink; position: absolute; left: 10px; top: 4em;">
+ <div style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px;">
+ <div style="width: 300px; height: 1500px; background: cyan;"></div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003.html b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003.html
new file mode 100644
index 0000000000..c54682f309
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/padding-border-margin/padding-border-margin-003.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Padding/border/margin on an operator, stretchy along the block axis</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dfn-algorithm-for-stretching-operators-along-the-block-axis">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-operators">
+<link rel="match" href="padding-border-margin-003-ref.html"/>
+<meta name="assert" content="Verify visual rendering of padding/border/margin on an operator, stretchy along the block axis.">
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/stretchy.woff");
+ }
+ math {
+ font-family: TestFont;
+ font-size: 300px;
+ }
+</style>
+<body>
+ <p>This test passes if you see a cyan rectangle of width 300px and
+ height 1500px, surrounded by a 10px blue padding, surrounded by a 10px
+ blue/yellow dashed border, itself
+ surrounded by a 10px pink margin.</p>
+ <div style="background: pink; position: absolute; left: 10px; top: 4em;">
+ <math>
+ <mspace height="750px" depth="750px"/>
+ <mo lspace="0" rspace="0" style="background: blue; border: 10px dashed yellow; padding: 10px; margin: 10px; color: cyan;">⥜</mo>
+ </math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001-ref.html
new file mode 100644
index 0000000000..ca539440f8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001-ref.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>presentational hints</title>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ @font-face {
+ font-family: DoubleStruck;
+ src: url("/fonts/math/mathvariant-double-struck.woff");
+ }
+ @font-face {
+ font-family: Italic;
+ src: url("/fonts/math/mathvariant-italic.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+</style>
+<body>
+ <p>dir:
+ <math style="direction: ltr;">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </math>
+ </p>
+ <p>mathcolor:
+ <math style="color: green;">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </math>
+ </p>
+ <p>mathbackground:
+ <math style="background: green;">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </p>
+ <p>mathsize:
+ <math>
+ <mtext style="font-size: 100%">X</mtext>
+ </math>
+ </p>
+ <p>mathvariant:
+ <math>
+ <mi style="text-transform: uppercase">sin</mi>
+ </math>
+ </p>
+ <p>displaystyle:
+ <math style="math-style: compact">
+ <munder>
+ <mo movablelimits="true">X</mo>
+ <mo>X</mo>
+ </munder>
+ </math>
+ </p>
+ <p>scriptlevel:
+ <math>
+ <mtext style="math-depth: 0;">X</mtext>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001.html b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001.html
new file mode 100644
index 0000000000..96ee69541b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-001.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>presentational hints</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#double-struck-mappings">
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#new-text-transform-values">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">
+<link rel="match" href="presentational-hints-001-ref.html"/>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<meta name="assert" content="Verify that local author style wins over presentation hints attributes">
+<style>
+ math {
+ font: 25px/1 Ahem;
+ }
+</style>
+<body>
+ <p>dir:
+ <math dir="rtl" style="direction: ltr;">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </math>
+ </p>
+ <p>mathcolor:
+ <math mathcolor="red" style="color: green;">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </math>
+ </p>
+ <p>mathbackground:
+ <math mathbackground="red" style="background: green;">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </p>
+ <p>mathsize:
+ <math>
+ <mtext mathsize="300%" style="font-size: 100%">X</mtext>
+ </math>
+ </p>
+ <p>mathvariant:
+ <math>
+ <mi mathvariant="normal" style="text-transform: uppercase">sin</mi>
+ </math>
+ </p>
+ <p>displaystyle:
+ <math displaystyle="true" style="math-style: compact">
+ <munder>
+ <mo movablelimits="true">X</mo>
+ <mo>X</mo>
+ </munder>
+ </math>
+ </p>
+ <p>scriptlevel:
+ <math>
+ <mtext scriptlevel="1" style="math-depth: 0;">X</mtext>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002-ref.html
new file mode 100644
index 0000000000..fa22741efe
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002-ref.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>presentational hints (dynamic)</title>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ math {
+ font: 25px/1 Ahem;
+ }
+ @font-face {
+ font-family: Italic;
+ src: url("/fonts/math/mathvariant-italic.woff");
+ }
+</style>
+</head>
+<body>
+ <p>dir:
+ <math dir="rtl">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </math>
+ </p>
+ <p>mathcolor:
+ <math mathcolor="green">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </math>
+ </p>
+ <p>mathbackground:
+ <math mathbackground="green">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </p>
+ <p>mathsize:
+ <math>
+ <mtext mathsize="300%">X</mtext>
+ </math>
+ </p>
+ <p>mathvariant:
+ <math style="font-family: Italic">
+ <mi mathvariant="normal">X</mi>
+ </math>
+ </p>
+ <p>displaystyle:
+ <math displaystyle="true">
+ <munder>
+ <mo movablelimits="true">X</mo>
+ <mo>X</mo>
+ </munder>
+ </math>
+ </p>
+ <p>scriptlevel:
+ <math>
+ <mtext scriptlevel="-1">X</mtext>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002.html b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002.html
new file mode 100644
index 0000000000..8bb9153b86
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/presentational-hints-002.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8"/>
+<title>presentational hints (dynamic)</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#double-struck-mappings">
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#new-text-transform-values">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">
+<link rel="match" href="presentational-hints-002-ref.html"/>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<meta name="assert" content="Verify dynamically setting attributes mapped to style.">
+<style>
+ math {
+ font: 25px/1 Ahem;
+ }
+ @font-face {
+ font-family: Italic;
+ src: url("/fonts/math/mathvariant-italic.woff");
+ }
+</style>
+<script>
+ window.addEventListener("load", function() {
+ // force initial layout so we're sure what we're testing against
+ document.documentElement.getBoundingClientRect();
+
+ document.getElementById("dir").setAttribute("dir", "rtl");
+ document.getElementById("mathcolor").setAttribute("mathcolor", "green");
+ document.getElementById("mathbackground").setAttribute("mathbackground", "green");
+ document.getElementById("mathsize").setAttribute("mathsize", "300%");
+ document.getElementById("mathvariant").setAttribute("mathvariant", "normal");
+ document.getElementById("displaystyle").setAttribute("displaystyle", "true");
+ document.getElementById("scriptlevel").setAttribute("scriptlevel", "-1");
+
+ document.documentElement.classList.remove('reftest-wait');
+ });
+</script>
+</head>
+<body>
+ <p>dir:
+ <math id="dir">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </math>
+ </p>
+ <p>mathcolor:
+ <math id="mathcolor">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </math>
+ </p>
+ <p>mathbackground:
+ <math id="mathbackground">
+ <mtext>X</mtext>
+ <mtext>p</mtext>
+ </p>
+ <p>mathsize:
+ <math>
+ <mtext id="mathsize">X</mtext>
+ </math>
+ </p>
+ <p>mathvariant:
+ <math style="font-family: Italic">
+ <mi id="mathvariant">X</mi>
+ </math>
+ </p>
+ <p>displaystyle:
+ <math id="displaystyle">
+ <munder>
+ <mo movablelimits="true">X</mo>
+ <mo>X</mo>
+ </munder>
+ </math>
+ </p>
+ <p>scriptlevel:
+ <math>
+ <mtext id="scriptlevel">X</mtext>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/scriptlevel-001.html b/testing/web-platform/tests/mathml/relations/css-styling/scriptlevel-001.html
new file mode 100644
index 0000000000..e9be1f2965
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/scriptlevel-001.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Automatic scriptlevel</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes">
+<link rel="stylesheet" href="/fonts/ahem.css">
+<meta name="assert" content="Verify automatic scriptlevel changes">
+<style>
+ #container, math {
+ /* Ahem font does not have a MATH table so the font-size scale factor
+ is always 0.71^{computed - inherited math script level} */
+ font: 100px/1 Ahem;
+ }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+ function fontSize(element) {
+ return parseFloat((/(.+)px/).exec(window.getComputedStyle(element).getPropertyValue("font-size"))[1]);
+ }
+ function runTests() {
+ var container = document.getElementById("container");
+ var epsilon = .1
+ var fontSizeAtScriptLevelZero = fontSize(container);
+
+ test(function() {
+ var element = document.getElementById("mfrac_displaystyle");
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "numerator");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "denominator");
+ }, "automatic scriptlevel on mfrac (displaystyle=true)");
+
+ test(function() {
+ var element = document.getElementById("mfrac_notdisplaystyle");
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero * .71, epsilon, "numerator");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71, epsilon, "denominator");
+ }, "automatic scriptlevel on mfrac (displaystyle=false)");
+
+ test(function() {
+ var element = document.getElementsByTagName("mroot")[0];
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71 * .71, epsilon, "index");
+ }, "automatic scriptlevel on mroot");
+
+ ["msub", "msup", "msubsup", "munder", "mover", "munderover", "mmultiscripts"].forEach(tag => {
+ test(function() {
+ var element = document.getElementsByTagName(tag)[0];
+ for (var i = 0; i < element.children.length; i++)
+ assert_approx_equals(fontSize(element.children[i]), i > 0 ? fontSizeAtScriptLevelZero * .71 : fontSizeAtScriptLevelZero, epsilon, `child ${i}`);
+ }, `automatic scriptlevel on ${tag}`);
+ });
+
+ test(function() {
+ var element = document.querySelector("munder[accentunder='true']");
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under");
+ }, `automatic scriptlevel on munder (accentunder=true)`);
+
+ test(function() {
+ var element = document.querySelector("mover[accent='true']");
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "over");
+ }, `automatic scriptlevel on mover (accent=true)`);
+
+ test(function() {
+ var element = document.querySelector("munderover[accentunder='true']");
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under");
+ assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero * .71, epsilon, "over");
+ }, `automatic scriptlevel on munderover (accentunder=true)`);
+
+ test(function() {
+ var element = document.querySelector("munderover[accent='true']");
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71, epsilon, "under");
+ assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero, epsilon, "over");
+ }, `automatic scriptlevel on munderover (accent=true)`);
+
+ test(function() {
+ var element = document.getElementById("munderover-dynamic-case-insensitive")
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71, epsilon, "under");
+ assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero, epsilon, "over");
+
+ element.removeAttribute("accent");
+ element.setAttribute("accentunder", "TrUe");
+ assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
+ assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under");
+ assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero * .71, epsilon, "over");
+ }, "checking dynamic/case-insensitive accent/accentunder");
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="container">
+ <p>
+ <math displaystyle="true">
+ <mfrac id="mfrac_displaystyle">
+ <mn>0</mn>
+ <mn>1</mn>
+ </mfrac>
+ </math>
+
+ <math displaystyle="false">
+ <mfrac id="mfrac_notdisplaystyle">
+ <mn>0</mn>
+ <mn>1</mn>
+ </mfrac>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mroot>
+ <mn>0</mn>
+ <mn>1</mn>
+ </mroot>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msub>
+ <mn>0</mn>
+ <mn>1</mn>
+ </msub>
+ </math>
+ <math>
+ <msup>
+ <mn>0</mn>
+ <mn>1</mn>
+ </msup>
+ </math>
+ <math>
+ <msubsup>
+ <mn>0</mn>
+ <mn>1</mn>
+ <mn>2</mn>
+ </msubsup>
+ </math>
+ <math>
+ <munder>
+ <mn>0</mn>
+ <mn>1</mn>
+ </munder>
+ </math>
+ <math>
+ <mover>
+ <mn>0</mn>
+ <mn>1</mn>
+ </mover>
+ </math>
+ <math>
+ <munderover>
+ <mn>0</mn>
+ <mn>1</mn>
+ <mn>2</mn>
+ </munderover>
+ </math>
+ <math>
+ <mmultiscripts>
+ <mn>0</mn>
+ <mn>1</mn>
+ <mn>2</mn>
+ <mn>3</mn>
+ <mn>4</mn>
+ <mprescripts/>
+ <mn>6</mn>
+ <mn>7</mn>
+ <mn>8</mn>
+ <mn>9</mn>
+ </mmultiscripts>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munder accentunder="true">
+ <mn>0</mn>
+ <mn>1</mn>
+ </munder>
+ </math>
+ <math>
+ <mover accent="true">
+ <mn>0</mn>
+ <mn>1</mn>
+ </mover>
+ </math>
+ <math>
+ <munderover accent="true">
+ <mn>0</mn>
+ <mn>1</mn>
+ <mn>2</mn>
+ </munderover>
+ </math>
+ <math>
+ <munderover accentunder="true">
+ <mn>0</mn>
+ <mn>1</mn>
+ <mn>2</mn>
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover id="munderover-dynamic-case-insensitive" accent="TrUe">
+ <mn>0</mn>
+ <mn>1</mn>
+ <mn>2</mn>
+ </munderover>
+ </math>
+ </p>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/transform-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/transform-ref.html
new file mode 100644
index 0000000000..005e8a7882
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/transform-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Transform property (reference)</title>
+</head>
+<body>
+ <p>Rectangles should be rotated.</p>
+ <div style="background: green; width: 200px; height: 200px; position: absolute; top: 100px; transform: rotate(90deg)"></div>
+ <div style="background: green; width: 200px; height: 200px; position: absolute; top: 300px; transform: rotate(90deg)"></div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/transform.html b/testing/web-platform/tests/mathml/relations/css-styling/transform.html
new file mode 100644
index 0000000000..c45fda3469
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/transform.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Transform property</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="transform-ref.html"/>
+<meta name="assert" content="Verify that the transform property works on MathML elements.">
+</head>
+<body>
+ <p>Rectangles should be rotated.</p>
+ <div>
+ <math><mspace width="200px" height="200px" style="position:absolute; top:100px; background: green; transform: rotate(90deg)"/></math>
+ </div>
+ <div style="position: absolute; top: 300px; width: 200px; height: 200px">
+ <math style="position: absolute; transform: rotate(90deg)"><mspace width="200px" height="200px" style="background: green"/></math>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-001-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-001-ref.html
new file mode 100644
index 0000000000..fcaf5fe85b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-001-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>visibility (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-001.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-001.html
new file mode 100644
index 0000000000..56bf7b7da2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-001.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>visibility</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="match" href="visibility-001-ref.html"/>
+<meta name="assert" content="Verify that visibility=hidden is used for the text of token elements.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px;">
+ <math><mi style="visibility: hidden">1</mi></math>
+ <math><mn style="visibility: hidden">2</mn></math>
+ <math><mo style="visibility: hidden">3</mo></math>
+ <math><mtext style="visibility: hidden">4</mtext></math>
+ <math><ms style="visibility: hidden">5</ms></math>
+ <div id="dynamic">
+ <math><mi>1</mi></math>
+ <math><mn>2</mn></math>
+ <math><mo>3</mo></math>
+ <math><mtext>4</mtext></math>
+ <math><ms>5</ms></math>
+ </div>
+ </div>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("dynamic").style.visibility = "hidden";
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-002-ref.html
new file mode 100644
index 0000000000..fcaf5fe85b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-002-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>visibility (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-002.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-002.html
new file mode 100644
index 0000000000..f92d0faf6d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-002.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>visibility</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#fraction-with-nonzero-line-thickness">
+<link rel="match" href="visibility-002-ref.html"/>
+<meta name="assert" content="Verify that visibility=hidden is used for the text and fraction bar of the mfrac element.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px;">
+ <math><mfrac style="visibility: hidden"><mn>1</mn><mn>2</mn></mfrac></math>
+ <div id="dynamic">
+ <math><mfrac><mn>1</mn><mn>2</mn></mfrac></math>
+ </div>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("dynamic").style.visibility = "hidden";
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-003-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-003-ref.html
new file mode 100644
index 0000000000..fcaf5fe85b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-003-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>visibility (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-003.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-003.html
new file mode 100644
index 0000000000..4bf4d45c81
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-003.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>visibility</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://w3c.github.io/mathml-core/#radical-symbol">
+<link rel="match" href="visibility-003-ref.html"/>
+<meta name="assert" content="Verify that visibility=hidden is used for the text and radical symbol of the msqrt and mroot elements.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px;">
+ <math><msqrt style="visibility: hidden"><mn>1</mn></msqrt></math>
+ <math><mroot style="visibility: hidden"><mn>2</mn><mn>3</mn></mroot></math>
+ <div id="dynamic">
+ <math><msqrt><mn>1</mn></msqrt></math>
+ <math><mroot><mn>2</mn><mn>3</mn></mroot></math>
+ </div>
+ </div>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("dynamic").style.visibility = "hidden";
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_msqrt");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative-ref.html
new file mode 100644
index 0000000000..fcaf5fe85b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>visibility (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative.html
new file mode 100644
index 0000000000..28678eaf0c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-004.tentative.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>visibility</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-mtext">
+<link rel="help" href="https://github.com/mathml-refresh/mathml-core/pull/24">
+<link rel="match" href="visibility-004.tentative-ref.html"/>
+<meta name="assert" content="Verify that visibility=hidden is used for the text and graphical elements of the menclose element.">
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px;">
+ <math><menclose notation="left" style="visibility: hidden"><mn>1</mn></menclose></math>
+ <math><menclose notation="right" style="visibility: hidden"><mn>2</mn></menclose></math>
+ <math><menclose notation="top" style="visibility: hidden"><mn>3</mn></menclose></math>
+ <math><menclose notation="bottom" style="visibility: hidden"><mn>4</mn></menclose></math>
+ <math><menclose notation="box" style="visibility: hidden"><mn>5</mn></menclose></math>
+ <math><menclose notation="roundedbox" style="visibility: hidden"><mn>6</mn></menclose></math>
+ <math><menclose notation="actuarial" style="visibility: hidden"><mn>7</mn></menclose></math>
+ <math><menclose notation="madruwb" style="visibility: hidden"><mn>8</mn></menclose></math>
+ <math><menclose notation="horizontalstrike" style="visibility: hidden"><mn>9</mn></menclose></math>
+ <math><menclose notation="verticalstrike" style="visibility: hidden"><mn>10</mn></menclose></math>
+ <math><menclose notation="updiagonalstrike" style="visibility: hidden"><mn>11</mn></menclose></math>
+ <math><menclose notation="downdiagonalstrike" style="visibility: hidden"><mn>12</mn></menclose></math>
+ <math><menclose notation="longdiv" style="visibility: hidden"><mn>13</mn></menclose></math>
+ <math><menclose notation="circle" style="visibility: hidden"><mn>14</mn></menclose></math>
+ <div id="dynamic">
+ <math><menclose notation="left"><mn>1</mn></menclose></math>
+ <math><menclose notation="right"><mn>2</mn></menclose></math>
+ <math><menclose notation="top"><mn>3</mn></menclose></math>
+ <math><menclose notation="bottom"><mn>4</mn></menclose></math>
+ <math><menclose notation="box"><mn>5</mn></menclose></math>
+ <math><menclose notation="roundedbox"><mn>6</mn></menclose></math>
+ <math><menclose notation="actuarial"><mn>7</mn></menclose></math>
+ <math><menclose notation="madruwb"><mn>8</mn></menclose></math>
+ <math><menclose notation="horizontalstrike"><mn>9</mn></menclose></math>
+ <math><menclose notation="verticalstrike"><mn>10</mn></menclose></math>
+ <math><menclose notation="updiagonalstrike"><mn>11</mn></menclose></math>
+ <math><menclose notation="downdiagonalstrike"><mn>12</mn></menclose></math>
+ <math><menclose notation="longdiv"><mn>13</mn></menclose></math>
+ <math><menclose notation="circle"><mn>14</mn></menclose></math>
+ </div>
+ </div>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("dynamic").style.visibility = "hidden";
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_menclose");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-005-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-005-ref.html
new file mode 100644
index 0000000000..fcaf5fe85b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-005-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>visibility (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; width: 200px; height: 200px;">
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/visibility-005.html b/testing/web-platform/tests/mathml/relations/css-styling/visibility-005.html
new file mode 100644
index 0000000000..a3af376fea
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/visibility-005.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>visibility</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="match" href="visibility-005-ref.html"/>
+<meta name="assert" content="Verify that visibility=hidden is used for normal, stretchy and large operators.">
+<style>
+ math {
+ font: 20px/1 Ahem;
+ }
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ mo {
+ font-family: operators;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if you see a green square.</p>
+ <div style="background: green; color: red; width: 200px; height: 200px;">
+ <math>
+ <!-- unstretched operators -->
+ <mo style="visibility: hidden">⥯</mo>
+ <mo style="visibility: hidden">+</mo>
+ <mo style="visibility: hidden">-</mo>
+ </math>
+ <math displaystyle="true">
+ <!-- large operator -->
+ <mo largeop="true" style="visibility: hidden">⥯</mo>
+ </math>
+ <math>
+ <mrow>
+ <!-- stretchy, small size -->
+ <mspace height="2em"/>
+ <mo style="visibility: hidden">⥯</mo>
+ </mrow>
+ </math>
+ <math>
+ <mrow>
+ <!-- stretchy, large size -->
+ <mspace height="4em"/>
+ <mo style="visibility: hidden">⥯</mo>
+ </mrow>
+ </math>
+ <div id="dynamic">
+ <math>
+ <!-- unstretched operators -->
+ <mo stretchy="false">⥯</mo>
+ <mo>+</mo>
+ <mo>-</mo>
+ </math>
+ <math displaystyle="true">
+ <!-- large operator -->
+ <mo largeop="true">⥯</mo>
+ </math>
+ <math>
+ <mrow>
+ <!-- stretchy, small size -->
+ <mspace height="2em"/>
+ <mo>⥯</mo>
+ </mrow>
+ </math>
+ <math>
+ <mrow>
+ <!-- stretchy, large size -->
+ <mspace height="4em"/>
+ <mo>⥯</mo>
+ </mrow>
+ </math>
+ </div>
+ </div>
+ <script src="/mathml/support/fonts.js"></script>
+ <script>
+ window.addEventListener("load", () => loadAllFonts().then(() => {
+ document.getElementById("dynamic").style.visibility = "hidden";
+ document.documentElement.classList.remove("reftest-wait");
+ }));
+ </script>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_menclose");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-001.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-001.html
new file mode 100644
index 0000000000..2deedc3f0b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-001.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>width, height, inline-size and block-size</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify that width, height, inline-size and block-size properties are ignored.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/box-comparison.js"></script>
+<style>
+ /* Revert style specified in the UA style sheet that changes box size. */
+ merror { border: 0; }
+ mfrac { padding: 0; }
+</style>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag))
+ continue;
+
+ document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;"><math><mrow>${MathMLFragments[tag]}</mrow></math></div>`);
+ let div = document.body.lastElementChild;
+ let element = FragmentHelper.element(div.firstElementChild);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var style = `width: 500px; height: 400px;`;
+ element.setAttribute("style", style);
+ let box = element.getBoundingClientRect();
+ assert_approx_equals(box.width, 500, epsilon, "width");
+ assert_approx_equals(box.height, 400, epsilon, "height");
+ }, `width and height properties on ${tag}`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`);
+ var style = `inline-size: 600px; block-size: 700px;`;
+ element.setAttribute("style", style);
+ let box = element.getBoundingClientRect();
+ assert_approx_equals(box.width, 600, epsilon, "width");
+ assert_approx_equals(box.height, 700, epsilon, "height");
+ }, `inline-size and block-size properties on ${tag}`);
+
+ div.style = "display: none;"; // Hide the div after measurement.
+ }
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-002-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-002-ref.html
new file mode 100644
index 0000000000..ed5125e952
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-002-ref.html
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>content position with width/height (reference)</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ body, math {
+ font: 25px/1 Ahem;
+ color: black;
+ }
+ .test {
+ margin: .5em;
+ }
+ .box {
+ width: 7em;
+ height: 3em;
+ border: 1px solid blue;
+ display: inline-block;
+ }
+ .center {
+ text-align: center;
+ }
+
+ /* Revert style specified in the UA style sheet that changes box size. */
+ mfrac { padding: 0; }
+</style>
+</head>
+<body>
+ <div class="test">
+ <div class="box">
+ <math>
+ <mtext>X</mtext>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <mtext>X</mtext>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <mrow>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mrow>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <mrow>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mrow>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <mpadded lspace="1em" voffset="-1em">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mpadded>
+ </math>
+ </diV>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <mpadded lspace="1em" voffset="-1em">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mpadded>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <mpadded width="9em" height="1em" depth=".5em">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mpadded>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <mpadded width="9em" height="1em" depth=".5em">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mpadded>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box center">
+ <math>
+ <mfrac linethickness="0">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mfrac>
+ </math>
+ </div>
+ <div class="box center" dir="rtl">
+ <math dir="rtl">
+ <mfrac linethickness="0">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mfrac>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <msqrt>
+ <mtext>X</mtext>
+ </msqrt>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <msqrt>
+ <mtext>X</mtext>
+ </msqrt>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <mroot>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mroot>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <mroot>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mroot>
+ </math>
+ </div>
+ </div>
+
+</body>
+</htmL>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-002.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-002.html
new file mode 100644
index 0000000000..99822c1ed9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-002.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>content position with width/height</title>
+<link rel="match" href="width-height-002-ref.html">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac">
+<meta name="assert" content="Verify the inline-start and block-start edges of the math content box for the mtext, mrow, mpadded, mfrac, msqrt, mroot layout algorithms."/>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ body, math {
+ font: 25px/1 Ahem;
+ color: black;
+ }
+ .test {
+ margin: .5em;
+ }
+ .box {
+ width: 7em;
+ height: 3em;
+ border: 1px solid blue;
+ }
+
+ /* Revert style specified in the UA style sheet that changes box size. */
+ mfrac { padding: 0; }
+</style>
+</head>
+<body>
+
+ <div class="test">
+ <math>
+ <mtext class="box">X</mtext>
+ </math>
+ <math dir="rtl">
+ <mtext class="box">X</mtext>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mrow class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mrow>
+ </math>
+ <math dir="rtl">
+ <mrow class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mrow>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mpadded lspace="1em" voffset="-1em" class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mpadded>
+ </math>
+ <math dir="rtl">
+ <mpadded lspace="1em" voffset="-1em" class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mpadded>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mpadded width="9em" height="1em" depth=".5em" class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mpadded>
+ </math>
+ <math dir="rtl">
+ <mpadded width="9em" height="1em" depth=".5em" class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mpadded>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mfrac class="box" linethickness="0">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mfrac>
+ </math>
+ <math dir="rtl">
+ <mfrac class="box" linethickness="0">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mfrac>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <msqrt class="box">
+ <mtext>X</mtext>
+ </msqrt>
+ </math>
+ <math dir="rtl">
+ <msqrt class="box">
+ <mtext>X</mtext>
+ </msqrt>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mroot class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mroot>
+ </math>
+ <math dir="rtl">
+ <mroot class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mroot>
+ </math>
+ </div>
+
+</body>
+</htmL>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-003-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-003-ref.html
new file mode 100644
index 0000000000..84eb2cd089
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-003-ref.html
@@ -0,0 +1,178 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>content position with width/height (reference)</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ body, math {
+ font: 25px/1 Ahem;
+ color: black;
+ }
+ .test {
+ margin: .5em;
+ }
+ .box {
+ width: 7em;
+ height: 3em;
+ border: 1px solid blue;
+ display: inline-block;
+ }
+ .center {
+ text-align: center;
+ }
+</style>
+</head>
+<body>
+
+ <div class="test">
+ <div class="box center">
+ <math>
+ <munder>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munder>
+ </math>
+ </div>
+ <div class="box center" dir="rtl">
+ <math dir="rtl">
+ <munder>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munder>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box center">
+ <math>
+ <mover>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mover>
+ </math>
+ </div>
+ <div class="box center" dir="rtl">
+ <math dir="rtl">
+ <mover>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mover>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box center">
+ <math>
+ <munderover>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munderover>
+ </math>
+ </div>
+ <div class="box center" dir="rtl">
+ <math dir="rtl">
+ <munderover>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munderover>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <msub>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msub>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <msub>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msub>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <msup>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msup>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <msup>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msup>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <msubsup>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msubsup>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <msubsup>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msubsup>
+ </math>
+ </div>
+ </div>
+
+ <div class="test">
+ <div class="box">
+ <math>
+ <mmultiscripts>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mprescripts/>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mmultiscripts>
+ </math>
+ </div>
+ <div class="box" dir="rtl">
+ <math dir="rtl">
+ <mmultiscripts>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mprescripts/>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mmultiscripts>
+ </math>
+ </div>
+ </div>
+
+</body>
+</htmL>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-003.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-003.html
new file mode 100644
index 0000000000..05e00f4759
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-003.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>content position with width/height</title>
+<link rel="match" href="width-height-003-ref.html">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+<meta name="assert" content="Verify the inline-start and block-start edges of the math content box for the munder, mover, munderover, msub, msup, msubsup, multiscripts layout algorithms."/>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ body, math {
+ font: 25px/1 Ahem;
+ color: black;
+ }
+ .test {
+ margin: .5em;
+ }
+ .box {
+ width: 7em;
+ height: 3em;
+ border: 1px solid blue;
+ }
+</style>
+</head>
+<body>
+
+ <div class="test">
+ <math>
+ <munder class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munder>
+ </math>
+ <math dir="rtl">
+ <munder class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munder>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mover class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mover>
+ </math>
+ <math dir="rtl">
+ <mover class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mover>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <munderover class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munderover>
+ </math>
+ <math dir="rtl">
+ <munderover class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munderover>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <msub class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msub>
+ </math>
+ <math dir="rtl">
+ <msub class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msub>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <msup class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msup>
+ </math>
+ <math dir="rtl">
+ <msup class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msup>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <msubsup class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msubsup>
+ </math>
+ <math dir="rtl">
+ <msubsup class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </msubsup>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mmultiscripts class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mprescripts/>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mmultiscripts>
+ </math>
+ <math dir="rtl">
+ <mmultiscripts class="box">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mprescripts/>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mmultiscripts>
+ </math>
+ </div>
+
+</body>
+</htmL>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/width-height-004.html b/testing/web-platform/tests/mathml/relations/css-styling/width-height-004.html
new file mode 100644
index 0000000000..7133573b04
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/width-height-004.html
@@ -0,0 +1,133 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>content position with width/height</title>
+<link rel="match" href="width-height-003-ref.html">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+<meta name="assert" content="Verify the inline-start of the children of the munder, mover, munderover and mfrac layout algorithms."/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ .test, math {
+ font: 25px/1 Ahem;
+ color: black;
+ }
+ .test {
+ margin: .5em;
+ }
+ [data-name] {
+ width: 7em;
+ height: 3em;
+ border: 1px solid blue;
+ }
+</style>
+<script>
+ var epsilon = 1;
+
+ function getMiddle(aElement) {
+ let box = aElement.getBoundingClientRect();
+ return (box.left + box.right) / 2;
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+ Array.from(document.querySelectorAll("[data-name]")).forEach(element => {
+ test(() => {
+ let elementMiddle = getMiddle(element);
+ Array.from(element.children).forEach(child => {
+ assert_approx_equals(getMiddle(child), elementMiddle, epsilon);
+ });
+ }, element.dataset.name);
+ });
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+
+ <div class="test">
+ <math>
+ <mfrac data-name="mfrac">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mfrac>
+ </math>
+ <math dir="rtl">
+ <mfrac data-name="RTL mfrac">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mfrac>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mfrac linethickness="0" data-name="mfrac without bar">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mfrac>
+ </math>
+ <math dir="rtl">
+ <mfrac linethickness="0" data-name="RTL mfrac without bar">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mfrac>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <munder data-name="munder">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munder>
+ </math>
+ <math dir="rtl">
+ <munder data-name="RTL munder">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munder>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <mover data-name="mover">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mover>
+ </math>
+ <math dir="rtl">
+ <mover data-name="RTL mover">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </mover>
+ </math>
+ </div>
+
+ <div class="test">
+ <math>
+ <munderover data-name="munderover">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munderover>
+ </math>
+ <math dir="rtl">
+ <munderover data-name="RTL munderover">
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ <mtext>X</mtext>
+ </munderover>
+ </math>
+ </div>
+
+</body>
+</htmL>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/force-horizontal-tb.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/force-horizontal-tb.html
new file mode 100644
index 0000000000..e239cdca5a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/force-horizontal-tb.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Forced writing-mode on MathML elements</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#user-agent-stylesheet">
+<meta name="assert" content="Test that writing-mode is forced to horizontal-tb on MathML elements.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<style>
+ /* selector defined in mathml-fragments.js */
+ .element {
+ writing-mode: vertical-lr;
+ padding-block-start: 10px;
+ padding-block-end: 15px;
+ padding-inline-start: 20px;
+ padding-inline-end: 25px;
+ }
+</style>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="container">
+ <math class="element"></math>
+ </div>
+ <script>
+ var container = document.getElementById("container");
+ for (tag in MathMLFragments) {
+ container.insertAdjacentHTML("beforeend", `<math>${MathMLFragments[tag]}</math>`);
+ }
+ let unknownElement = FragmentHelper.createElement("unknown");
+ unknownElement.setAttribute("class", "element");
+ container.appendChild(unknownElement);
+ Array.from(document.getElementsByClassName("element")).forEach(element => {
+ var tag = element.tagName;
+ var style = window.getComputedStyle(element);
+ test(function () {
+ assert_equals(style["writing-mode"], "horizontal-tb");
+ }, `writing-mode is forced to horizontal-tb on <${tag}> element`);
+ test(function () {
+ assert_equals(style["padding-block-start"], style["padding-top"]);
+ assert_equals(style["padding-block-end"], style["padding-bottom"]);
+ assert_equals(style["padding-inline-start"], style["padding-left"]);
+ assert_equals(style["padding-inline-end"], style["padding-right"]);
+ }, `logical properties interpreted in horizontal-tb on <${tag}> element`);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property-ref.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property-ref.html
new file mode 100644
index 0000000000..6eae88efb1
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Reset writing-mode and logical property (reference)</title>
+ </head>
+ <body>
+ <p>Test passes if you see a green square.</p>
+ <math style="writing-mode: horizontal-tb;
+ padding-top: 200px;
+ background: green">
+ <mspace width="200px"/>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property.html
new file mode 100644
index 0000000000..939cfc5ba6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/reset-and-logicial-property.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Reset writing-mode and logical property</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+ <meta name="assert" content="Verify how forced writing-mode is taken into account for logicial properties.">
+ <link rel="match" href="reset-and-logicial-property-ref.html">
+ </head>
+ <body>
+ <p>Test passes if you see a green square.</p>
+ <math style="writing-mode: vertical-lr;
+ padding-block-start: 200px;
+ background: green">
+ <mspace width="200px"/>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-001.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-001.html
new file mode 100644
index 0000000000..b751caf90d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-001.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>writing mode</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify CSS writing mode (writing-mode and directionproperties) for mrow.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ var reference = document.getElementById("horizontal-tb_ltr");
+
+ ["horizontal-tb_rtl"].forEach(id => {
+ var element = document.getElementById(id);
+
+ test(function() {
+ var style = window.getComputedStyle(element);
+ var writingMode = id.split("_");
+ assert_equals(style.getPropertyValue("writing-mode"),
+ writingMode[0], "writing-mode");
+ assert_equals(style.getPropertyValue("direction"),
+ writingMode[1], "direction");
+ }, `Inheritance of CSS writing-mode and direction (id='${id}')`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ compareLayout(element, reference, epsilon);
+ }, `Layout of mrow (id='${id}')`);
+ });
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mrow id="horizontal-tb_ltr">
+ <mspace style="background: blue"
+ width="20px" height="30px" depth="40px"></mspace>
+ <mspace style="background: black"
+ width="50px" depth="60px"></mspace>
+ <mspace style="background: yellow"
+ width="70px" height="80px"></mspace>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math style="direction: rtl;">
+ <mrow id="horizontal-tb_rtl">
+ <mspace style="background: blue"
+ width="20px" height="30px" depth="40px"></mspace>
+ <mspace style="background: black"
+ width="50px" depth="60px"></mspace>
+ <mspace style="background: yellow"
+ width="70px" height="80px"></mspace>
+ </mrow>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-002.html b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-002.html
new file mode 100644
index 0000000000..c0b64a917a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/css-styling/writing-mode/writing-mode-002.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>writing mode</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms">
+<meta name="assert" content="Verify CSS writing mode (writing-mode and direction properties) for mrow.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script>
+ var epsilon = 1;
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ for (tag in MathMLFragments) {
+ if (tag == "annotation" || tag == "annotation-xml")
+ continue; // These tags have display: none.
+
+ ["horizontal-tb_rtl"].forEach(id => {
+ var writingMode = id.split("_");
+ var writingModeString = `writing-mode: ${writingMode[0]}; direction: ${writingMode[1]};`;
+
+ document.body.insertAdjacentHTML("beforeend", `<div>\
+<math>${MathMLFragments[tag]}</math>\
+<math>${MathMLFragments[tag]}</math>\
+</div>`);
+ var div = document.body.lastElementChild;
+
+ var styleMath = div.firstElementChild;
+ styleMath.setAttribute("style", writingModeString);
+ var styleElement = FragmentHelper.element(styleMath);
+
+ var referenceMath = div.lastElementChild;
+ var referenceElement = FragmentHelper.element(referenceMath);
+
+ [styleMath, referenceMath].forEach(math => {
+ Array.from(math.getElementsByClassName("mathml-container")).forEach(container => {
+ container.insertAdjacentHTML("beforeend", "\
+<mspace style='background: blue'\
+ width='20px' height='30px' depth='40px'></mspace>\
+<mspace style='background: black'\
+ width='50px' depth='60px'></mspace>\
+<mspace style='background: yellow'\
+ width='70px' height='80px'></mspace>");
+ });
+ Array.from(math.getElementsByClassName("foreign-container")).forEach(container => {
+ container.insertAdjacentHTML("beforeend", "\
+<span style='display: inline-block; background: lightblue;\
+ inline-size: 20px; block-size: 30px;\
+ vertical-align: bottom;'></span>\
+<span style='display: inline-block; background: pink;\
+ inline-size: 40px; block-size: 50px;\
+ vertical-align: bottom;'></span>");
+ });
+ });
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ var style = window.getComputedStyle(styleElement);
+ assert_equals(style.getPropertyValue("writing-mode"),
+ writingMode[0], "writing-mode");
+ assert_equals(style.getPropertyValue("direction"),
+ writingMode[1], "direction");
+ compareLayout(styleElement, referenceElement, epsilon);
+ }, `Layout of ${tag} (${writingModeString})`);
+
+ div.style = "display: none;"; // Hide the div after testing.
+ });
+ }
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/class-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/class-1-ref.html
new file mode 100644
index 0000000000..5afa59ecf2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/class-1-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Class (reference)</title>
+</head>
+<body>
+
+ <p>Test passes if you see the text "PASS".</p>
+ <math>
+ <mtext style="background: green; color: white;">PASS</mtext>
+ </math>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/class-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/class-1.html
new file mode 100644
index 0000000000..fd1678d440
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/class-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Class</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="class-1-ref.html"/>
+<meta name="assert" content="Verify that the class attribute affects CSS selectors.">
+<style>
+ mtext.fail { display: none; }
+ mtext.pass { background: green; }
+</style>
+</head>
+<body>
+
+ <p>Test passes if you see the text "PASS".</p>
+ <math>
+ <mtext class="fail" style="background: red; color: white;">FAIL</mtext>
+ <mtext class="pass" style="color: white;">PASS</mtext>
+ </math>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/class-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/class-2.html
new file mode 100644
index 0000000000..e694b063a6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/class-2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Class</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+<meta name="assert" content="Verify whether the getElementsByClassName() works for MathML elements.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("DOMContentLoaded", function() {
+ var mtext = document.getElementsByClassName("cl");
+ test(function() {
+ assert_equals(mtext.length, 3);
+ var mtext_ref = document.body.lastElementChild.firstElementChild;
+ mtext_ref = mtext_ref.nextElementSibling.nextElementSibling
+ assert_equals(mtext[0], mtext_ref);
+ mtext_ref = mtext_ref.nextElementSibling.nextElementSibling;
+ assert_equals(mtext[1], mtext_ref);
+ mtext_ref = mtext_ref.nextElementSibling.nextElementSibling;
+ assert_equals(mtext[2], mtext_ref);
+ }, "getElementsByClassName()");
+ done();
+ });
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <math>
+ <mtext class="cl_"></mtext>
+ <mtext class="c"></mtext>
+ <mtext class="cl"></mtext>
+ <mtext class="cl_"></mtext>
+ <mtext class="cl"></mtext>
+ <mtext class="c"></mtext>
+ <mtext class="cl"></mtext>
+ <mtext class="cl_"></mtext>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html
new file mode 100644
index 0000000000..bf2f8d11ed
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<title>clipboard event handlers for MathML</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#globaleventhandlers"/>
+<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-copy"/>
+<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-cut"/>
+<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-paste"/>
+<meta
+ name="assert"
+ content="MathMLElements incorporates oncopy / oncut / onpaste event handlers"
+/>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<math
+ oncopy="window.copyHappened1 = true"
+ oncut="window.cutHappened1 = true"
+ onpaste="window.pasteHappened1 = true"
+>
+ <mi>E</mi>
+</math>
+<script>
+ const EVENTS = ["copy", "cut", "paste"];
+ const el = document.querySelector("math");
+
+ function dispatchEventTest(name) {
+ const mathEl = document.createElementNS(
+ "http://www.w3.org/1998/Math/MathML",
+ "math"
+ );
+ test(() => {
+ let target = undefined;
+ mathEl[`on${name}`] = (e) => { target = e.currentTarget; }
+ const event = new ClipboardEvent(name, {
+ bubbles: true,
+ cancellable: true
+ });
+ mathEl.dispatchEvent(event);
+ assert_equals(target, mathEl, "The event must be fired at the <math> element");
+ }, `${name}: dispatching an Event at a <math> element must trigger element.on${name}`);
+ }
+
+ function evaluatedHandlerTest(name) {
+ const handlerName = "on" + name;
+
+ test(() => {
+ const compiledHandler = el[handlerName];
+
+ assert_equals(
+ typeof compiledHandler,
+ "function",
+ `The ${handlerName} property must be a function`
+ );
+ compiledHandler();
+ assert_true(
+ window[`${name}Happened1`],
+ "Calling the handler must run the code"
+ );
+ }, `${handlerName}: the content attribute must be compiled into a function as the corresponding property`);
+
+ test(() => {
+ const mathEl = document.createElementNS(
+ "http://www.w3.org/1998/Math/MathML",
+ "math"
+ );
+ assert_equals(mathEl[handlerName], null, `The ${handlerName} property must be null (no attribute)`);
+
+ mathEl.setAttribute(handlerName, `window.${handlerName}Happened2 = true;`);
+ const compiledHandler = mathEl[handlerName];
+ assert_equals(
+ typeof compiledHandler,
+ "function",
+ `The ${handlerName} property must be a function (set attribute)`
+ );
+ compiledHandler();
+ assert_true(
+ window[`${handlerName}Happened2`],
+ "Calling the handler must run the code (set attribute)"
+ );
+
+ window[`${handlerName}Happened2`] = false;
+ const clonedMathEl = mathEl.cloneNode(true);
+ const clonedCompiledHandler = clonedMathEl[handlerName];
+ assert_equals(
+ typeof clonedCompiledHandler,
+ "function",
+ `The ${handlerName} property must be a function (clone node)`
+ );
+ clonedCompiledHandler();
+ assert_true(
+ window[`${handlerName}Happened2`],
+ "Calling the handler must run the code (clone node)"
+ );
+
+ mathEl.setAttribute(handlerName, `window.${handlerName}Happened3 = true;`);
+ const newCompiledHandler = mathEl[handlerName];
+ assert_equals(
+ typeof newCompiledHandler,
+ "function",
+ `The ${handlerName} property must be a function (modify attribute)`
+ );
+ newCompiledHandler();
+ assert_true(
+ window[`${handlerName}Happened3`],
+ "Calling the handler must run the code (modify attribute)"
+ );
+
+ mathEl.removeAttribute(handlerName);
+ assert_equals(mathEl[handlerName], null, `The ${handlerName} property must be null (remove attribute)`);
+ }, `${handlerName}: dynamic changes on the attribute`);
+
+ }
+
+ EVENTS.forEach(name => {
+ dispatchEventTest(name);
+ evaluatedHandlerTest(name);
+ });
+</script>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1-ref.html
new file mode 100644
index 0000000000..71ee8cea9d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Color Attributes (reference)</title>
+<style>
+ #content > div {
+ position: absolute;
+ }
+</style>
+</head>
+<body>
+
+ <p>Test passes if you see the text below is written in white on a green
+ background.</p>
+
+ <div id="content">
+ <div>
+ <math style="background: green;">
+ <mtext style="color: white;">Hello World!</mtext>
+ </math>
+ </div>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1.html
new file mode 100644
index 0000000000..211bda7f85
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/color-attributes-1.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Color Attributes</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
+<meta name="assert" content="Verify that the mathcolor and mathbackground attributes are supported on the math element.">
+<link rel="match" href="color-attributes-1-ref.html"/>
+<style>
+ #content {
+ color: red;
+ }
+ #content > div {
+ position: absolute;
+ }
+</style>
+</head>
+<body>
+
+ <p>Test passes if you see the text below is written in white on a green
+ background.</p>
+
+ <div id="content">
+ <div>
+ <math style="background: red;">
+ <mtext style="visibility: hidden;">Hello World!</mtext>
+ </math>
+ </div>
+ <div>
+ <math mathcolor="white" mathbackground="green">
+ <mtext>Hello World!</mtext>
+ </math>
+ </div>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/content-editable.html b/testing/web-platform/tests/mathml/relations/html5-tree/content-editable.html
new file mode 100644
index 0000000000..28e8630829
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/content-editable.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML inside content-editable</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg">
+<meta name="assert" content="Verify that putting MathML inside a content-editable div shouldn't affect its layout.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("DOMContentLoaded", function() {
+ var epsilon = 1;
+ var mfrac = document.getElementById("mfrac");
+ var num = mfrac.firstElementChild.getBoundingClientRect();
+ var denom = mfrac.lastElementChild.getBoundingClientRect();
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_approx_equals(num.width, 30, epsilon, "numerator width");
+ assert_approx_equals(num.height, 40, epsilon, "numerator height");
+ assert_approx_equals(denom.width, 50, epsilon, "denominator width");
+ assert_approx_equals(denom.height, 60, epsilon, "denominator height");
+ }, "mspace layout in content-editable div");
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mfrac());
+ assert_greater_than_equal(denom.bottom - num.top,
+ (40 + 60),
+ "numerator is above the denominator");
+ assert_approx_equals((num.left + num.right) / 2,
+ (denom.left + denom.right) / 2,
+ epsilon, "numerator and denominator are horizontally aligned");
+ }, "mfrac layout in content-editable div");
+ done();
+ });
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <div contenteditable="true">
+ This is
+ <math>
+ <mfrac id="mfrac">
+ <mspace width="30px" height="40px" style="background: cyan"></mspace>
+ <mspace width="50px" height="60px" style="background: yellow"></mspace>
+ </mfrac>
+ </math>
+ a content editable div
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative-ref.html
new file mode 100644
index 0000000000..19f3e6c82a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML 'ElementCSSInlineStyle` Dynamic Tests</title>
+<style>
+mspace {
+ background-color: green;
+}
+</style>
+</head>
+<body>
+ <span>This tests that `ElementCSSInlineStyle` interface changes update rendering.</span>
+ <div>
+ <math><mspace width="50px" height="100px"/><mspace width="50px" height="100px"/></math>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative.html
new file mode 100644
index 0000000000..5d27d6a7e6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-dynamic.tentative.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <meta charset="utf-8" />
+ <title>MathML 'ElementCSSInlineStyle` Dynamic Tests</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/>
+ <link rel="match" href="css-inline-style-dynamic.tentative-ref.html"/>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <style>
+ #hidden {
+ visibility: hidden;
+ background-color: green;
+ }
+ #red {
+ background-color: red;
+ }
+ </style>
+ <meta
+ name="assert"
+ content="MathMLElements ElementCSSInlineStyle interface changes update rendering"
+ />
+ <script type="text/javascript">
+ function test()
+ {
+ MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");
+ document.body.offsetTop; // Update layout
+
+ var mspace = document.getElementById("hidden");
+ if (mspace.style)
+ mspace.style.visibility = "visible";
+
+ mspace = document.getElementById("red");
+ if (mspace.style)
+ mspace.style.backgroundColor = "green";
+
+ document.documentElement.className = "";
+ }
+ </script>
+ </head>
+ <body onload="test()">
+ <span>This tests that `ElementCSSInlineStyle` interface changes update rendering.</span>
+ <div>
+ <math><mspace width="50px" height="100px" id="hidden"/><mspace width="50px" height="100px" id="red"/></math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-interface.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-interface.tentative.html
new file mode 100644
index 0000000000..f8348c15b2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/css-inline-style-interface.tentative.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>MathML 'ElementCSSInlineStyle` Mixin Tests</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/>
+ <style>
+ math * {
+ background-color: red;
+ }
+ </style>
+ <meta
+ name="assert"
+ content="MathMLElements incorporate a functional ElementCSSInlineStyle interface"
+ />
+ <script src="/mathml/support/mathml-fragments.js"></script>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <span
+ >This tests the presence and functionality of features of the
+ `ElementCSSInlineStyle` interface for MathMLElements</span
+ >
+ <math></math>
+ <script>
+ let mathEl = document.querySelector("math");
+
+ test(function() {
+ mathEl.style.backgroundColor = "lime";
+ assert_equals(
+ getComputedStyle(mathEl).backgroundColor,
+ "rgb(0, 255, 0)",
+ "The applied background should be green."
+ );
+ }, `The <math> element style property should be present and be functional.`);
+
+ Object.keys(MathMLFragments).forEach(elName => {
+ mathEl.innerHTML = MathMLFragments[elName];
+
+ test(function() {
+ let el = FragmentHelper.element(mathEl);
+ el.style.backgroundColor = "blue";
+
+ assert_equals(
+ getComputedStyle(el).backgroundColor,
+ "rgb(0, 0, 255)",
+ "The applied background should be blue."
+ );
+ }, `The ${elName}'s style property should be present and be functional.`);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/display-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/display-1.html
new file mode 100644
index 0000000000..fa92771fac
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/display-1.html
@@ -0,0 +1,175 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML display attribute</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+<meta name="assert" content="Verify that the display attribute on the math element is supported and impacts centering and line breaking with surrounding content.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/attribute-values.js"></script>
+<script>
+ function getBox(aId) {
+ return document.getElementById(aId).getBoundingClientRect();
+ }
+ window.addEventListener("DOMContentLoaded", function() {
+ for (transform in AttributeValueTransforms) {
+ TransformAttributeValues(transform, ["display"]);
+ var content = getBox("content");
+
+ var before_block = getBox("before_block");
+ var mspace_block = getBox("mspace_block");
+ var after_block = getBox("after_block");
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_approx_equals(before_block.left, content.left, 1,
+ "content before must be left aligned");
+ assert_approx_equals((mspace_block.left + mspace_block.right) / 2,
+ (content.left + content.right) / 2,
+ 1,
+ "math must be centered.");
+ assert_approx_equals(after_block.left, content.left, 1,
+ "content after must be left aligned");
+ assert_less_than_equal(before_block.bottom, mspace_block.top,
+ "new line before math");
+ assert_less_than_equal(mspace_block.bottom, after_block.top,
+ "new line after math");
+ }, `Test display math ${transform}`);
+
+ var before_inline = getBox("before_inline");
+ var mspace_inline = getBox("mspace_inline");
+ var after_inline = getBox("after_inline");
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_approx_equals((before_inline.top + before_inline.bottom) / 2,
+ (mspace_inline.top + mspace_inline.bottom) / 2,
+ 1,
+ "content before must be horizontally aligned with math");
+ assert_approx_equals((after_inline.top + after_inline.bottom) / 2,
+ (mspace_inline.top + mspace_inline.bottom) / 2,
+ 1,
+ "content after must be horizontally aligned with math");
+ assert_less_than_equal(before_inline.right, mspace_inline.left,
+ "content before must be on the left of math");
+ assert_less_than_equal(mspace_inline.right, after_inline.left,
+ "content after must be on the right of math");
+ }, `Test inline math ${transform}`);
+
+ var before_block_and_specified_width = getBox("before_block_and_specified_width");
+ var mspace_width = getBox("mspace_width");
+ var after_block_and_specified_width = getBox("after_block_and_specified_width");
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ let math = getBox("math_with_specified_width");
+ assert_approx_equals(before_block_and_specified_width.left, math.left, 1,
+ "content before must be left aligned");
+ assert_approx_equals(math.width, 100, 1,
+ "math uses specified width.");
+ assert_approx_equals((mspace_width.left + mspace_width.right) / 2,
+ (math.left + math.right) / 2,
+ 1,
+ "math must be centered.");
+ assert_approx_equals(after_block_and_specified_width.left, math.left, 1,
+ "content after must be left aligned");
+ assert_less_than_equal(before_block_and_specified_width.bottom, mspace_width.top,
+ "new line before math");
+ assert_less_than_equal(mspace_width.bottom, after_block_and_specified_width.top,
+ "new line after math");
+ }, `Test width on display=block math ${transform}`);
+ }
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ document.getElementById("mspace_dynamic_block").parentNode.
+ setAttribute("display", "block");
+ var before_block = getBox("before_dynamic_block");
+ var mspace_block = getBox("mspace_dynamic_block");
+ var after_block = getBox("after_dynamic_block");
+
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_approx_equals(before_block.left, content.left, 1,
+ "content before must be left aligned");
+ assert_approx_equals((mspace_block.left + mspace_block.right) / 2,
+ (content.left + content.right) / 2,
+ 1,
+ "math must be centered.");
+ assert_approx_equals(after_block.left, content.left, 1,
+ "content after must be left aligned");
+ assert_less_than_equal(before_block.bottom, mspace_block.top,
+ "new line before math");
+ assert_less_than_equal(mspace_block.bottom, after_block.top,
+ "new line after math");
+ }, "Test dynamically setting display=block");
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ document.getElementById("mspace_dynamic_inline").parentNode.
+ removeAttribute("display");
+ var before_inline = getBox("before_dynamic_inline");
+ var mspace_inline = getBox("mspace_dynamic_inline");
+ var after_inline = getBox("after_dynamic_inline");
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_approx_equals((before_inline.top + before_inline.bottom) / 2,
+ (mspace_inline.top + mspace_inline.bottom) / 2,
+ 1,
+ "content before must be horizontally aligned with math");
+ assert_approx_equals((after_inline.top + after_inline.bottom) / 2,
+ (mspace_inline.top + mspace_inline.bottom) / 2,
+ 1,
+ "content after must be horizontally aligned with math");
+ assert_less_than_equal(before_inline.right, mspace_inline.left,
+ "content before must be on the left of math");
+ assert_less_than_equal(mspace_inline.right, after_inline.left,
+ "content after must be on the right of math");
+ }, "Test dynamically setting display=inline");
+
+ done();
+ });
+</script>
+<style>
+ #content {
+ width: 600px;
+ background: #ccc;
+ }
+ span.square {
+ display: inline-block;
+ width: 50px;
+ height: 50px;
+ background: black;
+ }
+ mspace {
+ background: blue;
+ }
+</style>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="content">
+ <span id="before_block" class="square"></span>
+ <math display="block"><mspace id="mspace_block" width="50px" height="50px"/></math>
+ <span id="after_block" class="square"></span>
+ <br/>
+ <span id="before_inline" class="square"></span>
+ <math display="inline"><mspace id="mspace_inline" width="50px" height="50px"/></math>
+ <span id="after_inline" class="square"></span>
+ <br/>
+ <span id="before_block_and_specified_width" class="square"></span>
+ <math display="block" id="math_with_specified_width" style="background: pink; width:100px"><mspace id="mspace_width" width="50px" height="50px"/></math>
+ <span id="after_block_and_specified_width" class="square"></span>
+ <br/>
+ <div>
+ <span id="before_dynamic_block" class="square"></span>
+ <math><mspace id="mspace_dynamic_block" width="50px" height="50px"/></math>
+ <span id="after_dynamic_block" class="square"></span>
+ </div>
+ <div>
+ <span id="before_dynamic_inline" class="square"></span>
+ <math display="block"><mspace id="mspace_dynamic_inline" width="50px" height="50px"/></math>
+ <span id="after_dynamic_inline" class="square"></span>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/display-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/display-2-ref.html
new file mode 100644
index 0000000000..7864c04099
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/display-2-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>display attribute VS legacy mode attribute (reference)</title>
+</head>
+<body>
+ <p>Test passes if you see four green squares, the last one
+ centered and the others left-aligned.</p>
+ <p>
+ <math>
+ <mspace width="100px" height="100px" style="background: green"></mspace>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mspace width="100px" height="100px" style="background: green"></mspace>
+ </math>
+ </p>
+ <p>
+ <math display="inline">
+ <mspace width="100px" height="100px" style="background: green"></mspace>
+ </math>
+ </p>
+ <p>
+ <math display="block">
+ <mspace width="100px" height="100px" style="background: green"></mspace>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/display-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/display-2.html
new file mode 100644
index 0000000000..b4e79395a1
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/display-2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>display attribute VS legacy mode attribute</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element">
+<link rel="help" href="https://www.w3.org/TR/MathML3/chapter2.html#id.2.2.2">
+<link rel="match" href="display-2-ref.html"/>
+<meta name="assert" content="Verify that the legacy mode attribute has no effect.">
+</head>
+<body>
+ <p>Test passes if you see four green squares, the last one
+ centered and the others left-aligned.</p>
+ <p>
+ <math mode="inline">
+ <mspace width="100px" height="100px" style="background: green"></mspace>
+ </math>
+ </p>
+ <p>
+ <math mode="display">
+ <mspace width="100px" height="100px" style="background: green"></mspace>
+ </math>
+ </p>
+ <p>
+ <math display="inline" mode="display">
+ <mspace width="100px" height="100px" style="background: green"></mspace>
+ </math>
+ </p>
+ <p>
+ <math display="block" mode="inline">
+ <mspace width="100px" height="100px" style="background: green"></mspace>
+ </math>
+ </p>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1-ref.html
new file mode 100644
index 0000000000..5fa90e9d2f
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Dynamic MathML DOM (reference)</title>
+<style>
+ mtext.pass { background: green; color: white; }
+</style>
+</head>
+<body>
+ <p>Test passes if you see the text "PASS".</p>
+ <math>
+ <mtext class="pass">PASS</mtext>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1.html
new file mode 100644
index 0000000000..59403196a8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Dynamic MathML DOM</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/>
+<link rel="match" href="dynamic-1-ref.html"/>
+<meta name="assert" content="Verify that the MathML DOM tree can be modified via javascript and that the rendering is correctly updated.">
+<style>
+ mtext.fail { background: red; color: white; }
+ mtext.pass { background: green; color: white; }
+</style>
+<script>
+ window.addEventListener("DOMContentLoaded", function() {
+ var kMathMLNamespace = "http://www.w3.org/1998/Math/MathML";
+ var mtext = document.createElementNS(kMathMLNamespace, "mtext");
+ mtext.setAttribute("class", "pass");
+ mtext.textContent = "PASS";
+ var math = document.getElementsByTagNameNS(kMathMLNamespace, "math")[0];
+ math.replaceChild(mtext, math.firstElementChild);
+ });
+</script>
+</head>
+<body>
+ <p>Test passes if you see the text "PASS".</p>
+ <math>
+ <mtext class="fail">FAIL</mtext>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2-ref.html
new file mode 100644
index 0000000000..272e8b33ca
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Dynamic id and style (reference)</title>
+<style>
+ #pass { background: green; color: white; }
+</style>
+</head>
+<body>
+ <p>Test passes if you see the text "PASS".</p>
+ <math>
+ <mtext id="pass">PASS</mtext>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2.html
new file mode 100644
index 0000000000..8ad47c5cd9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-2.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Dynamic id and style</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/>
+<link rel="match" href="dynamic-2-ref.html"/>
+<meta name="assert" content="Verify dynamic change of id and style attributes.">
+<style>
+ #fail, #fail2 { background: red; color: white; }
+ #pass { background: green; color: white; }
+</style>
+<script>
+ window.addEventListener("DOMContentLoaded", function() {
+ document.getElementById("fail2").setAttribute("id", "pass");
+ document.getElementById("fail").setAttribute("style", "display: none");
+ });
+</script>
+</head>
+<body>
+ <p>Test passes if you see the text "PASS".</p>
+ <math>
+ <mtext id="fail">FAIL</mtext>
+ <mtext id="fail2">PASS</mtext>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-001.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-001.html
new file mode 100644
index 0000000000..ffd0ae239f
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-001.html
@@ -0,0 +1,630 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Dynamic childlist of MathML elements</title>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+<link rel="help" href="https://w3c.github.io/mathml-core/#fractions-mfrac">
+<link rel="help" href="https://w3c.github.io/mathml-core/#prescripts-and-tensor-indices-mmultiscripts">
+<link rel="help" href="https://w3c.github.io/mathml-core/#radicals-msqrt-mroot">
+<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace">
+<link rel="help" href="https://w3c.github.io/mathml-core/#subscripts-and-superscripts-msub-msup-msubsup">
+<link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+<meta name="assert" content="Dynamically modify DOM tree of some MathML elements by adding or removing children.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<script>
+ function forceNumberOfChildren(element, count) {
+ while (element.children.length > count)
+ element.removeChild(element.lastElementChild);
+ for (let i = element.children.length; i < count; i++) {
+ if (element.tagName === "mmultiscripts" && i === 5) {
+ element.appendChild(FragmentHelper.createElement("mprescripts"));
+ } else {
+ let mspace = FragmentHelper.createElement("mspace");
+ mspace.setAttribute("width", `10px`);
+ mspace.setAttribute("height", `${10*(i+1)}px`);
+ mspace.setAttribute("style", `background: black;`);
+ element.appendChild(mspace);
+ }
+ }
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", function() {
+ // force initial layout so we're sure what we're testing against
+ document.documentElement.getBoundingClientRect();
+
+ let reference = document.getElementById("reference");
+
+ Array.from(document.querySelectorAll("[data-title]")).forEach(element => {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ let reference = document.getElementById(`${element.getAttribute("data-reference")}`);
+ forceNumberOfChildren(element, reference.children.length);
+ const epsilon = 1;
+ if (element.tagName == "mspace") {
+ compareSize(element, reference, epsilon);
+ childrenHaveEmptyBoundingClientRects(element);
+ childrenHaveEmptyBoundingClientRects(reference);
+ } else {
+ compareLayout(element, reference, epsilon);
+ }
+ }, `${element.getAttribute("data-title")}`);
+ });
+ done();
+ });
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mfrac id="mfrac-reference-1">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </mfrac>
+ <mfrac id="mfrac-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mfrac>
+ <mfrac id="mfrac-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mfrac>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mfrac data-reference="mfrac-reference-2" data-title="Adding missing children to mfrac">
+ </mfrac>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mfrac data-reference="mfrac-reference-1" data-title="Removing child from valid mfrac">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mfrac>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mfrac data-reference="mfrac-reference-3" data-title="Adding child to valid mfrac">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mfrac>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mfrac data-reference="mfrac-reference-2" data-title="Removing extra child from mfrac">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mfrac>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <munder id="munder-reference-1">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </munder>
+ <munder id="munder-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </munder>
+ <munder id="munder-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </munder>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munder data-reference="munder-reference-2" data-title="Adding missing children to munder">
+ </munder>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munder data-reference="munder-reference-1" data-title="Removing child from valid munder">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </munder>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munder data-reference="munder-reference-3" data-title="Adding child to valid munder">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </munder>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munder data-reference="munder-reference-2" data-title="Removing extra child from munder">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </munder>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <mover id="mover-reference-1">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </mover>
+ <mover id="mover-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mover>
+ <mover id="mover-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mover data-reference="mover-reference-2" data-title="Adding missing children to mover">
+ </mover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mover data-reference="mover-reference-1" data-title="Removing child from valid mover">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mover data-reference="mover-reference-3" data-title="Adding child to valid mover">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mover data-reference="mover-reference-2" data-title="Removing extra child from mover">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mover>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <munderover id="munderover-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </munderover>
+ <munderover id="munderover-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </munderover>
+ <munderover id="munderover-reference-4">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ <mspace width="10px" height="40px" style="background: black;"/>
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover data-reference="munderover-reference-3" data-title="Adding missing children to munderover">
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover data-reference="munderover-reference-2" data-title="Removing child from valid munderover">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover data-reference="munderover-reference-4" data-title="Adding child to valid munderover">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover data-reference="munderover-reference-3" data-title="Removing extra child from munderover">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ <mspace width="10px" height="40px" style="background: black;"/>
+ </munderover>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <msub id="msub-reference-1">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </msub>
+ <msub id="msub-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </msub>
+ <msub id="msub-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </msub>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msub data-reference="msub-reference-2" data-title="Adding missing children to msub">
+ </msub>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msub data-reference="msub-reference-1" data-title="Removing child from valid msub">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </msub>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msub data-reference="msub-reference-3" data-title="Adding child to valid msub">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </msub>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msub data-reference="msub-reference-2" data-title="Removing extra child from msub">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </msub>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <msup id="msup-reference-1">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </msup>
+ <msup id="msup-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </msup>
+ <msup id="msup-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </msup>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msup data-reference="msup-reference-2" data-title="Adding missing children to msup">
+ </msup>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msup data-reference="msup-reference-1" data-title="Removing child from valid msup">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </msup>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msup data-reference="msup-reference-3" data-title="Adding child to valid msup">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </msup>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msup data-reference="msup-reference-2" data-title="Removing extra child from msup">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </msup>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <msubsup id="msubsup-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </msubsup>
+ <msubsup id="msubsup-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </msubsup>
+ <msubsup id="msubsup-reference-4">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ <mspace width="10px" height="40px" style="background: black;"/>
+ </msubsup>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msubsup data-reference="msubsup-reference-3" data-title="Adding missing children to msubsup">
+ </msubsup>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msubsup data-reference="msubsup-reference-2" data-title="Removing child from valid msubsup">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </msubsup>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msubsup data-reference="msubsup-reference-4" data-title="Adding child to valid msubsup">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </msubsup>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msubsup data-reference="msubsup-reference-3" data-title="Removing extra child from msubsup">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ <mspace width="10px" height="40px" style="background: black;"/>
+ </msubsup>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <mroot id="mroot-reference-1">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </mroot>
+ <mroot id="mroot-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mroot>
+ <mroot id="mroot-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mroot>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mroot data-reference="mroot-reference-2" data-title="Adding missing children to mroot">
+ </mroot>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mroot data-reference="mroot-reference-1" data-title="Removing child from valid mroot">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mroot>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mroot data-reference="mroot-reference-3" data-title="Adding child to valid mroot">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mroot>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mroot data-reference="mroot-reference-2" data-title="Removing extra child from mroot">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mroot>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <msqrt id="msqrt-reference-0">
+ </msqrt>
+ <msqrt id="msqrt-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </msqrt>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msqrt data-reference="msqrt-reference-0" data-title="Removing children from msqrt">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </msqrt>
+ </math>
+ </p>
+ <p>
+ <math>
+ <msqrt data-reference="msqrt-reference-2" data-title="Adding children to msqrt">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </msqrt>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <mpadded id="mpadded-reference-0">
+ </mpadded>
+ <mpadded id="mpadded-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mpadded>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mpadded data-reference="mpadded-reference-0" data-title="Removing children from mpadded">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mpadded>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mpadded data-reference="mpadded-reference-2" data-title="Adding children to mpadded">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </mpadded>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <mspace id="mspace-reference-0" width="30px" height="70px" style="background: blue">
+ </mspace>
+ <mspace id="mspace-reference-2" width="30px" height="70px" style="background: green">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mspace>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mspace data-reference="mspace-reference-0" data-title="Removing children from mspace" width="30px" height="70px" style="background: lightblue">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mspace>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mspace data-reference="mspace-reference-2" data-title="Adding children to mspace" width="30px" height="70px" style="background: lightgreen">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </mspace>
+ </math>
+ </p>
+ <hr/>
+ <p>
+ <math>
+ <mmultiscripts id="mmultiscripts-reference-0">
+ </mmultiscripts>
+ <mmultiscripts id="mmultiscripts-reference-1">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ </mmultiscripts>
+ <mmultiscripts id="mmultiscripts-reference-2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ </mmultiscripts>
+ <mmultiscripts id="mmultiscripts-reference-3">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mmultiscripts>
+ <mmultiscripts id="mmultiscripts-reference-6">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ <mspace width="10px" height="40px" style="background: black;"/>
+ <mspace width="10px" height="50px" style="background: black;"/>
+ <mprescripts/>
+ </mmultiscripts>
+ <mmultiscripts id="mmultiscripts-reference-8">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ <mspace width="10px" height="40px" style="background: black;"/>
+ <mspace width="10px" height="50px" style="background: black;"/>
+ <mprescripts/>
+ <mspace width="10px" height="70px" style="background: black;"/>
+ <mspace width="10px" height="80px" style="background: black;"/>
+ </mmultiscripts>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mmultiscripts data-reference="mmultiscripts-reference-0" data-title="multiscripts child count from 3 to 0">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mmultiscripts>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mmultiscripts data-reference="mmultiscripts-reference-1" data-title="multiscripts child count from 3 to 1">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mmultiscripts>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mmultiscripts data-reference="mmultiscripts-reference-2" data-title="multiscripts child count from 3 to 2">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mmultiscripts>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mmultiscripts data-reference="mmultiscripts-reference-3" data-title="multiscripts child count from 0 to 3">
+ </mmultiscripts>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mmultiscripts data-reference="mmultiscripts-reference-6" data-title="multiscripts child count from 3 to 6">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mmultiscripts>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mmultiscripts data-reference="mmultiscripts-reference-8" data-title="multiscripts child count from 3 to 8">
+ <mspace width="10px" height="10px" style="background: black;"/>
+ <mspace width="10px" height="20px" style="background: black;"/>
+ <mspace width="10px" height="30px" style="background: black;"/>
+ </mmultiscripts>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-002.html b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-002.html
new file mode 100644
index 0000000000..099401eacc
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/dynamic-childlist-002.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Dynamic childlist of MathML elements</title>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+<meta name="assert" content="Dynamically modify DOM tree of some MathML elements by adding or removing children.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/layout-comparison.js"></script>
+<script>
+ function generateMathForTag(tag, childCount) {
+ let math = FragmentHelper.createElement("math");
+ let element = FragmentHelper.createElement(tag);
+ // Add the children with different sizes at odd positions and OOF
+ // mrow at even position.
+ for (let i = 0; i < childCount; i++) {
+ if (i % 2) {
+ let mspace = FragmentHelper.createElement("mspace");
+ mspace.setAttribute("width", `10px`);
+ mspace.setAttribute("height", `${10*(i+1)}px`);
+ mspace.setAttribute("style", `background: black;`);
+ element.appendChild(mspace);
+ } else {
+ let mrow = FragmentHelper.createElement("mrow");
+ mrow.setAttribute("style", "position: absolute");
+ element.appendChild(mrow);
+ }
+ }
+ if (FragmentHelper.isValidChildOfMrow(tag)) {
+ math.appendChild(element);
+ } else if (tag === "mtd") {
+ let mtr = FragmentHelper.createElement("mtr");
+ mtr.appendChild(element);
+ let mtable = FragmentHelper.createElement("mtable");
+ mtable.appendChild(mtr);
+ math.appendChild(mtable);
+ } else {
+ throw `Invalid argument: ${tag}`;
+ }
+ return math;
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", function() {
+
+ for (tag in MathMLFragments) {
+ if (!FragmentHelper.isValidChildOfMrow(tag) || tag === "mtd")
+ continue;
+
+ document.body.insertAdjacentHTML("beforeend", `<div style='display: none; background: pink;'>${tag}: <div></div><div></div><div></div></div>`);
+
+ let container = document.body.lastElementChild;
+ let referenceDiv = container.children[0];
+ const maxChild = 10;
+ const epsilon = 1;
+
+ // Create the references for different number of children as well
+ // as the element that will get the children added / removed.
+ for (let i = 0; i <= maxChild; i++)
+ referenceDiv.append(generateMathForTag(tag, i));
+ let fullReferenceMath = referenceDiv.lastElementChild;
+ let fullReferenceTag = fullReferenceMath.firstElementChild;
+
+ let removeChildrenMath = generateMathForTag(tag, maxChild);
+ container.children[1].append(removeChildrenMath);
+ let removeChildrenTag = removeChildrenMath.firstElementChild;
+
+ let appendChildrenMath = generateMathForTag(tag, 0);
+ container.children[2].append(appendChildrenMath);
+ let appendChildrenTag = appendChildrenMath.firstElementChild;
+
+ // Make content visible after the DOM is ready so that the layout
+ // only happens now.
+ container.style.display = "block";
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_true(MathMLFeatureDetection[`has_${tag}`]());
+
+ for (let i = 0; i < maxChild; i++) {
+ // append and remove children.
+ appendChildrenTag.append(fullReferenceTag.children[i].cloneNode(true));
+ removeChildrenTag.removeChild(removeChildrenTag.lastElementChild);
+
+ // force layout so we're sure what we're testing against
+ container.getBoundingClientRect();
+
+ let appendCount = appendChildrenTag.children.length;
+ let removeCount = removeChildrenTag.children.length;
+ if (tag == "mspace") {
+ compareSize(appendChildrenTag, referenceDiv.children[appendCount].firstElementChild, epsilon);
+ childrenHaveEmptyBoundingClientRects(appendChildrenTag);
+ childrenHaveEmptyBoundingClientRects(referenceDiv.children[appendCount].firstElementChild);
+ childrenHaveEmptyBoundingClientRects(removeChildrenTag);
+ childrenHaveEmptyBoundingClientRects(referenceDiv.children[removeCount].firstElementChild);
+ } else {
+ compareLayout(appendChildrenTag, referenceDiv.children[appendCount].firstElementChild, epsilon, `appending ${appendCount}-th child`);
+ compareLayout(removeChildrenTag, referenceDiv.children[removeCount].firstElementChild, epsilon, `removing ${appendCount + 1}-th child`);
+ }
+ }
+
+ // Hide back the div after successful testing.
+ container.style.display = "none";
+
+ }, `Appending and removing children to ${tag}`);
+ }
+
+ done();
+ });
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1-ref.html
new file mode 100644
index 0000000000..86952567c7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href click (reference)</title>
+</head>
+<body>
+
+ <p>This test passes if you see a green square.</p>
+
+ <div style="width: 150px; height: 150px; background: green">
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1.html
new file mode 100644
index 0000000000..c3e605cb72
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8"/>
+<title>href click</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+<link rel="match" href="href-click-1-ref.html"/>
+<meta name="assert" content="Verify that a click on a link moves to the target.">
+<script type="text/javascript">
+ function test()
+ {
+ var event = new MouseEvent('click', {bubbles: true, cancelable: true});
+ document.getElementById('link').dispatchEvent(event);
+ document.documentElement.className = "";
+ }
+</script>
+</head>
+<body onload="test()">
+
+ <p>This test passes if you see a green square.</p>
+
+ <div style="width: 150px; height: 150px; overflow: hidden">
+ <math>
+ <mrow id="link" href="#target">
+ <mspace id="space" width="150px" height="150px" style="background: red"/>
+ </mrow>
+ </math>
+ <div style="height: 500px;"></div>
+ <math id="target">
+ <mspace width="150px" height="150px" style="background: green"/>
+ </math>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2-ref.html
new file mode 100644
index 0000000000..86952567c7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href click (reference)</title>
+</head>
+<body>
+
+ <p>This test passes if you see a green square.</p>
+
+ <div style="width: 150px; height: 150px; background: green">
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2.html
new file mode 100644
index 0000000000..8ffec61cc7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-2.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8"/>
+<title>href click</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+<link rel="match" href="href-click-2-ref.html"/>
+<meta name="assert" content="Verify that a click on an element bubbles to an ancestor link.">
+<script type="text/javascript">
+ function test()
+ {
+ var event = new MouseEvent('click', {bubbles: true, cancelable: true});
+ document.getElementById('space').dispatchEvent(event);
+ document.documentElement.className = "";
+ }
+</script>
+</head>
+<body onload="test()">
+
+ <p>This test passes if you see a green square.</p>
+
+ <div style="width: 150px; height: 150px; overflow: hidden">
+ <math>
+ <mrow href="#target">
+ <mrow>
+ <mrow>
+ <mspace id="space" width="150px" height="150px" style="background: red"/>
+ </mrow>
+ </mrow>
+ </mrow>
+ </math>
+ <div style="height: 500px;"></div>
+ <math id="target">
+ <mspace width="150px" height="150px" style="background: green"/>
+ </math>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/href-click-3.html b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-3.html
new file mode 100644
index 0000000000..f6f1ada6d7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/href-click-3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>href click</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+</head>
+<body>
+ <p>To test manually, click the blue rectangle.</p>
+ <p>
+ <math>
+ <mspace width="50px" height="10px" style="background: gray"></mspace>
+ <mspace id="target" href="javascript:handler()" width="50px" height="10px" style="background: blue"></mspace>
+ <mspace width="50px" height="10px" style="background: gray"></mspace>
+ </math>
+ </p>
+ <a id="badTarget" href="javascript:badHandler()">DON'T CLICK ME</a>
+ <script>
+ var t = async_test("Click element with href");
+ function handler() { t.done(); }
+ function badHandler() {
+ t.step(() => { assert_unreached("Bad handler executed"); });
+ t.done();
+ }
+ test_driver.click(document.getElementById("target")).then(() => {
+ return test_driver.click(document.getElementById("badTarget"));
+ }).catch(() => {
+ t.step(() => { assert_unreached("Click failed"); });
+ t.done();
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html
new file mode 100644
index 0000000000..028428cd75
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/html-or-foreign-element-interfaces.tentative.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>MathML 'HTMLOrForeignElement` Mixin Tests</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/>
+ <style>
+ mi {
+ background-color: red;
+ }
+ :focus {
+ background-color: rgb(0, 255, 0);
+ }
+ </style>
+ <meta
+ name="assert"
+ content="MathMLElements incorporate a functional HTMLOrForeignElement interface"
+ />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body tabindex="-1">
+ <span tabindex="-1"
+ >This tests the presence and functionality of features of
+ `HTMLOrForeignElement` (currently `HTMLOrSVGElement`)</span
+ >
+ <math tabindex="-1">
+ <mi>E</mi>
+ </math>
+ </body>
+ <script>
+ // spot check the functionality of several interfaces
+ let el = document.querySelector("mi");
+ let mathEl = document.querySelector("math");
+
+ // this really belongs in
+ // https://github.com/web-platform-tests/wpt/blob/master/html/dom/elements/global-attributes/dataset.html
+ // it is here tentatively
+ test(function() {
+ var mathml = document.createElementNS(
+ "http://www.w3.org/1998/Math/MathML",
+ "math"
+ );
+ assert_true(mathml.dataset instanceof DOMStringMap);
+ }, "MathML elements should have a .dataset");
+
+ // exercise some basic tests on .dataset
+ test(function() {
+ assert_equals(
+ Object.keys(el.dataset).toString(),
+ "",
+ "The .dataset property should be present"
+ );
+
+ el.setAttribute("data-one", "x");
+ el.setAttribute("data-two", "y");
+
+ assert_equals(
+ el.dataset.one,
+ "x",
+ '.one should be "x" after setting the data-one attribute'
+ );
+ assert_equals(
+ el.dataset.two,
+ "y",
+ '.one should be "y" after setting the data-two attribute'
+ );
+
+ el.dataset.one = "o";
+ assert_equals(
+ el.getAttribute("data-one"),
+ "o",
+ 'the data-one attribute should reflect a change to dataset.one and contain "o"'
+ );
+ }, "The dataset property should be present and be functional.");
+
+ test(function() {
+ assert_equals(mathEl.tabIndex, -1);
+ }, "MathML elements should have a tabIndex property");
+
+ promise_test(function() {
+ function focus() {
+ mathEl.focus();
+ return Promise.resolve();
+ }
+
+ return focus().then(() => {
+ assert_equals(
+ getComputedStyle(mathEl).backgroundColor,
+ "rgb(0, 255, 0)",
+ "MathML elements with tabindex=-1 should be programmatically focusable and apply :focus"
+ );
+ });
+ }, "MathML elements should work with focus predictably");
+
+ promise_test(function() {
+ function blur() {
+ mathEl.blur();
+ return Promise.resolve();
+ }
+
+ return blur().then(() => {
+ assert_equals(
+ getComputedStyle(mathEl).backgroundColor,
+ "rgba(0, 0, 0, 0)",
+ "MathML elements with tabindex=-1 be programmatically blur() able"
+ );
+ });
+ }, "MathML elements should work with blur predictably");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1-ref.html
new file mode 100644
index 0000000000..4987754967
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML inside foreignObject (reference)</title>
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+ <div>
+ <div style="position: absolute; width: 200px; height: 200px; background: green"></div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1.html
new file mode 100644
index 0000000000..bc725e9d19
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML inside foreignObject</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg">
+<link rel="match" href="integration-point-1-ref.html"/>
+<meta name="assert" content="Verify that MathML can be used inside a foreignObject element.">
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+ <div>
+ <div style="position: absolute; width: 200px; height: 200px; background: red"></div>
+ <div style="position: absolute;">
+ <svg width="200px" height="200px">
+ <rect width="200px" height="100px" fill="red"/>
+ <foreignObject width="200px" height="200px"
+ requiredExtensions="http://www.w3.org/1998/Math/MathML">
+ <div style="width: 200px; height: 200px; background: green"></div>
+ </foreignObject>
+ </svg>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2-ref.html
new file mode 100644
index 0000000000..33c4b7e910
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML as a phrasing content (reference)</title>
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+
+ <div>
+ <div style="position: absolute; background: green; width: 300px; height: 300px;"></div>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2.html
new file mode 100644
index 0000000000..7e6c11a5ac
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-2.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML as a phrasing content</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg">
+<link rel="match" href="integration-point-2-ref.html"/>
+<meta name="assert" content="Verify that MathML can be used at positions where phrasing content is accepted.">
+<style type="text/css">
+ span, math { font-family: monospace; font-size: 10px; }
+ div {
+ color: green;
+ }
+ span.redsquare {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ background: red;
+ }
+ mspace {
+ background: green;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+
+ <div>
+
+ <div style="position: absolute; background: green; width: 300px; height: 300px;">
+ <p><span class="redsquare"></span></p>
+ <h1><span class="redsquare"></span></h1>
+ <h2><span class="redsquare"></span></h2>
+ <ul>
+ <li><span class="redsquare"></span></li>
+ </ul>
+ <ol>
+ <li><span class="redsquare"></span></li>
+ </ol>
+ <table><tr><td><span class="redsquare"></span></td></tr></table>
+ <a href="#id"><span class="redsquare"></span></a>
+ <em><span class="redsquare"></span></em>
+ <strong><span class="redsquare"></span></strong>
+ <small><span class="redsquare"></span></small>
+ <span><span class="redsquare"></span></span>
+ <u><span class="redsquare"></span></u>
+ <q><span class="redsquare"></span></q>
+ </div>
+ <div style="position: absolute; width: 400px;">
+ <p><math><mspace width="10px" height="10px"/></math></p>
+ <h1><math><mspace width="10px" height="10px"/></math></h1>
+ <h2><math><mspace width="10px" height="10px"/></math></h2>
+ <ul>
+ <li><math><mspace width="10px" height="10px"/></math></li>
+ </ul>
+ <ol>
+ <li><math><mspace width="10px" height="10px"/></math></li>
+ </ol>
+ <table><tr><td><math><mspace width="10px" height="10px"/></math></td></tr></table>
+ <a href="#id"><math><mspace width="10px" height="10px"/></math></a>
+ <em><math><mspace width="10px" height="10px"/></math></em>
+ <strong><math><mspace width="10px" height="10px"/></math></strong>
+ <small><math><mspace width="10px" height="10px"/></math></small>
+ <span><math><mspace width="10px" height="10px"/></math></span>
+ <u><math><mspace width="10px" height="10px"/></math></u>
+ <q><math><mspace width="10px" height="10px"/></math></q>
+ </div>
+
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3-ref.html
new file mode 100644
index 0000000000..8362ed28e3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>phrasing content inside mtext (reference)</title>
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+
+ <div>
+
+ <div style="position: absolute; background: green; width: 200px; height: 200px;"></div>
+
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3.html
new file mode 100644
index 0000000000..4c6f89ee93
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-3.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>phrasing content inside mtext</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg">
+<link rel="match" href="integration-point-3-ref.html"/>
+<meta name="assert" content="Verify that <mtext> can contain phrasing content">
+<style type="text/css">
+ div {
+ color: green;
+ }
+ span, math, mtext { font-family: monospace; font-size: 10px; }
+ span.redsquare, span.greensquare {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ }
+ span.redsquare {
+ background: red;
+ }
+ span.greensquare {
+ background: green;
+ }
+ mspace {
+ background: green;
+ }
+</style>
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+
+ <div>
+
+ <div style="position: absolute; background: green; width: 200px; height: 200px;">
+ <span><span><span><span class="redsquare"></span></span></span></span>
+ <span><span><u><span class="redsquare"></span></u></span></span>
+ <span><span><a href="#id"><span class="redsquare"></span></a></span></span>
+ <span><span><del><span class="redsquare"></span></del></span></span>
+ <span><span><em><span class="redsquare"></span></em></span></span>
+ <span><span><strong><span class="redsquare"></span></strong></span></span>
+ <span><span><q><span class="redsquare"></span></q></span></span>
+ <span><span><small><span class="redsquare"></span></small></span></span>
+ <span><span><var><span class="redsquare"></span></var></span></span>
+ <span><span><samp><span class="redsquare"></span></samp></span></span>
+ </div>
+ <div style="position: absolute; width: 200px;">
+ <math><mtext><span><span class="greensquare"></span></span></mtext></math>
+ <math><mtext><u><span class="greensquare"></span></u></mtext></math>
+ <math><mtext><a href="#id"><span class="greensquare"></span></a></mtext></math>
+ <math><mtext><del><span class="greensquare"></span></del></mtext></math>
+ <math><mtext><em><span class="greensquare"></span></em></mtext></math>
+ <math><mtext><strong><span class="greensquare"></span></strong></mtext></math>
+ <math><mtext><q><span class="greensquare"></span></q></mtext></math>
+ <math><mtext><small><span class="greensquare"></span></small></mtext></math>
+ <math><mtext><var><span class="greensquare"></span></var></mtext></math>
+ <math><mtext><samp><span class="greensquare"></span></samp></mtext></math>
+ </div>
+
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-4.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-4.html
new file mode 100644
index 0000000000..c3bc95d1ef
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-4.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML inside foreignObject</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg">
+<meta name="assert" content="Verify that MathML can be used inside a foreignObject element.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("DOMContentLoaded", function() {
+ var scale = 2;
+ var epsilon = 1;
+ var mfrac = document.getElementById("mfrac");
+ var num = mfrac.firstElementChild.getBoundingClientRect();
+ var denom = mfrac.lastElementChild.getBoundingClientRect();
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ // The values of width and height are inverted (because of the
+ // rotation) and multiplied by the scale factor.
+ assert_approx_equals(num.height, 30 * scale, epsilon, "numerator width");
+ assert_approx_equals(num.width, 40 * scale, epsilon, "numerator height");
+ assert_approx_equals(denom.height, 50 * scale, epsilon, "numerator width");
+ assert_approx_equals(denom.width, 60 * scale, epsilon, "numerator height");
+ }, "mspace layout in SVG foreignObject");
+ test(function() {
+ // The horizontal/vertical metrics are inverted (because of the
+ // rotation) and multiplied by the scale factor.
+ assert_true(MathMLFeatureDetection.has_mfrac());
+ assert_greater_than_equal(num.right - denom.left,
+ (40 + 60) * scale,
+ "numerator is on the right of denominator");
+ assert_approx_equals((num.top + num.bottom) / 2,
+ (denom.top + denom.bottom) / 2,
+ epsilon, "numerator and denominator are vertically aligned");
+ }, "mfrac layout in SVG foreignObject");
+ done();
+ });
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <svg width="400px" height="400px">
+ <g transform="rotate(90, 200, 200) scale(2)">
+ <foreignObject width="400px" height="400px"
+ requiredExtensions="http://www.w3.org/1998/Math/MathML">
+ <math>
+ <mfrac id="mfrac">
+ <mspace width="30px" height="40px" style="background: cyan"></mspace>
+ <mspace width="50px" height="60px" style="background: yellow"></mspace>
+ </mfrac>
+ </math>
+ </foreignObject>
+ </g>
+ </svg>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-5.html b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-5.html
new file mode 100644
index 0000000000..b63ab7a63c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/integration-point-5.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML sibling of SVG with foreignObject[overflow=visible]</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=989920">
+<meta name="assert" content="Verify that an SVG containing a foreignObject with visible overflow does not affect layout of MathML siblings.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("DOMContentLoaded", function() {
+ var scale = 2;
+ var epsilon = 1;
+ var mfrac = document.getElementById("mfrac");
+ var num = mfrac.firstElementChild.getBoundingClientRect();
+ var denom = mfrac.lastElementChild.getBoundingClientRect();
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mspace());
+ assert_approx_equals(num.width, 30, epsilon, "numerator width");
+ assert_approx_equals(num.height, 40, epsilon, "numerator height");
+ assert_approx_equals(denom.width, 50, epsilon, "denonimator width");
+ assert_approx_equals(denom.height, 60, epsilon, "denonimator height");
+ }, "mspace layout in sibling of SVG foreignObject[overflow=visible]");
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_mfrac());
+ assert_greater_than_equal(denom.bottom - num.top,
+ (40 + 60),
+ "numerator above denominator");
+ assert_approx_equals((num.left + num.right) / 2,
+ (denom.left + denom.right) / 2,
+ epsilon, "numerator and denominator are horizontally aligned");
+ }, "mfrac layout in sibling of SVG with foreignObject[overflow=visible]");
+ done();
+ });
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <math>
+ <mfrac id="mfrac">
+ <mspace width="30px" height="40px" style="background: cyan"></mspace>
+ <mspace width="50px" height="60px" style="background: yellow"></mspace>
+ </mfrac>
+ </math>
+ <svg width="200px" height="200px" style="background: lightblue">
+ <foreignObject width="200px" height="200px"
+ overflow="visible">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ This is a foreignObject
+ </div>
+ </foreignObject>
+ </svg>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/math-global-event-handlers.tentative.html b/testing/web-platform/tests/mathml/relations/html5-tree/math-global-event-handlers.tentative.html
new file mode 100644
index 0000000000..b924eefa7d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/math-global-event-handlers.tentative.html
@@ -0,0 +1,155 @@
+<!DOCTYPE html>
+<title>MathMLElement GlobalEventHandlers</title>
+<link rel="author" title="Brian Kardell" href="mailto:bkardell@igalia.com" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#event-handler-idl-attributes"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#event-handler-content-attributes"/>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/WebIDLParser.js"></script>
+
+<script>
+ "use strict";
+
+ // The prefixed animation events are special; their event types are
+ // camel-case.
+ const prefixedAnimationAttributeToEventType = new Map([
+ ["webkitanimationend", "webkitAnimationEnd"],
+ ["webkitanimationiteration", "webkitAnimationIteration"],
+ ["webkitanimationstart", "webkitAnimationStart"],
+ ["webkittransitionend", "webkitTransitionEnd"],
+ ]);
+
+ // basic pattern lifted from /html/webappapis/scripting/events/event-handler-all-global-events.html
+ promise_setup(async function() {
+ const res = await fetch("/interfaces/html.idl");
+ const htmlIDL = await res.text();
+ // Parsing the whole IDL file is slow, so use a small regexp to extract only
+ // the part that is relevant for this test.
+ const parsedHTMLIDL = WebIDL2.parse(htmlIDL.
+ match(/^interface mixin GlobalEventHandlers {[^{}]*};$/m)[0]);
+ const globalEventHandlers = parsedHTMLIDL.find(
+ idl => idl.name === "GlobalEventHandlers"
+ );
+
+ // onerror is too special
+ const names = globalEventHandlers.members
+ .map(member => member.name)
+ .filter(name => name !== "onerror");
+
+ for (const name of names) {
+ const withoutOn = name.substring(2);
+
+ promise_test(async () => {
+ const location = MathMLElement.prototype;
+ assert_true(
+ location.hasOwnProperty(name),
+ `${location.constructor.name} has an own property named "${name}"`
+ );
+
+ assert_false(
+ name in Element.prototype,
+ `Element.prototype must not contain a "${name}" property`
+ );
+ }, `${name}: must be on the appropriate locations for GlobalEventHandlers`);
+
+ promise_test(async () => {
+ const location = document.createElementNS(
+ "http://www.w3.org/1998/Math/MathML",
+ "math"
+ );
+
+ assert_equals(
+ location[name],
+ null,
+ `The default value of the property is null for a ${
+ location.constructor.name
+ } instance`
+ );
+ }, `${name}: the default value must be null`);
+
+ promise_test(async () => {
+ const div = document.createElement("div");
+ div.insertAdjacentHTML("beforeend", `<math ${name}="window.${name}Happened1 = true;"></math>`);
+ const compiledHandler = div.firstElementChild[name];
+ assert_equals(
+ typeof compiledHandler,
+ "function",
+ `The ${name} property must be a function`
+ );
+ compiledHandler();
+ assert_true(
+ window[`${name}Happened1`],
+ "Calling the handler must run the code"
+ );
+ }, `${name}: the content attribute must be compiled into a function as the corresponding property`);
+
+ promise_test(async () => {
+ const el = document.createElementNS(
+ "http://www.w3.org/1998/Math/MathML",
+ "math"
+ );
+ assert_equals(el[name], null, `The ${name} property must be null (no attribute)`);
+
+ el.setAttribute(name, `window.${name}Happened2 = true;`);
+ const compiledHandler = el[name];
+ assert_equals(
+ typeof compiledHandler,
+ "function",
+ `The ${name} property must be a function (set attribute)`
+ );
+ compiledHandler();
+ assert_true(
+ window[`${name}Happened2`],
+ "Calling the handler must run the code (set attribute)"
+ );
+
+ window[`${name}Happened2`] = false;
+ const clonedEl = el.cloneNode(true);
+ const clonedCompiledHandler = clonedEl[name];
+ assert_equals(
+ typeof clonedCompiledHandler,
+ "function",
+ `The ${name} property must be a function (clone node)`
+ );
+ clonedCompiledHandler();
+ assert_true(
+ window[`${name}Happened2`],
+ "Calling the handler must run the code (clone node)"
+ );
+
+ el.setAttribute(name, `window.${name}Happened3 = true;`);
+ const newCompiledHandler = el[name];
+ assert_equals(
+ typeof newCompiledHandler,
+ "function",
+ `The ${name} property must be a function (modify attribute)`
+ );
+ newCompiledHandler();
+ assert_true(
+ window[`${name}Happened3`],
+ "Calling the handler must run the code (modify attribute)"
+ );
+
+ el.removeAttribute(name);
+ assert_equals(el[name], null, `The ${name} property must be null (remove attribute)`);
+ }, `${name}: dynamic changes on the attribute`);
+
+ promise_test(async () => {
+ const element = document.createElementNS(
+ "http://www.w3.org/1998/Math/MathML",
+ "math"
+ );
+ let target = undefined;
+ element[name] = (e) => { target = e.currentTarget; }
+ let eventType = withoutOn;
+ if (prefixedAnimationAttributeToEventType.has(eventType)) {
+ eventType = prefixedAnimationAttributeToEventType.get(eventType);
+ }
+ element.dispatchEvent(new Event(eventType));
+ assert_equals(target, element, "The event must be fired at the <math> element");
+ }, `${name}: dispatching an Event at a <math> element must trigger element.${name}`);
+ }
+ });
+</script>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2-ref.html
new file mode 100644
index 0000000000..dcc5b2b7d3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>SVG requiredExtensions (reference)</title>
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+ <svg width="200px" height="200px">
+ <rect width="200px" height="200px" fill="green"/>
+ </svg>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2.html
new file mode 100644
index 0000000000..738f125507
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/required-extensions-2.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>SVG requiredExtensions</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#html-and-svg">
+<link rel="match" href="required-extensions-2-ref.html"/>
+<meta name="assert" content="Verify that a foreignObject with MathML used as a requiredExtensions value is selected for display in a SVG switch element.">
+</head>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+ <svg width="200px" height="200px">
+ <rect width="200px" height="100px" fill="red"/>
+ <switch>
+ <foreignObject width="200px" height="200px"
+ requiredExtensions="http://www.w3.org/1998/Math/MathML">
+ <div style="width: 200px; height: 200px; background: green"></div>
+ </foreignObject>
+ <rect y="100px" width="200px" height="100px" fill="red"/>
+ </switch>
+ </svg>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-001.html b/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-001.html
new file mode 100644
index 0000000000..3aaf0d955a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-001.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>MathML tabIndex attribute</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#the-top-level-math-element">
+<meta name="assert" content="Verify default values for the tabIndex attribute">
+
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <math>
+ </math>
+ <script>
+ const htmlLinkableElements =
+ new Set([
+ 'mi', 'mo', 'mn', 'ms', 'mtext', 'mrow'
+ ]);
+
+ Object.keys(MathMLFragments).forEach(elName => {
+ const mathEl = document.querySelector('math');
+
+ mathEl.innerHTML = `
+ <${elName} id="el" onfocus="alert('fail')"></${elName}>
+ <${elName} id="el-link" href="javascript:alert('fail')" onfocus="alert('fail')"></${elName}>
+ `;
+
+ const el = mathEl.querySelector('#el');
+ const elLink = mathEl.querySelector('#el-link');
+
+ const expectedDefault = (htmlLinkableElements.has(elName)) ? 0 : -1;
+
+ test(() => {
+ assert_equals(el.tabIndex, expectedDefault, "no attribute");
+ el.setAttribute("tabindex", "invalid");
+ assert_equals(el.getAttribute("tabindex"), "invalid");
+ assert_equals(el.tabIndex, expectedDefault, "invalid");
+ el.setAttribute("tabindex", "9999999999");
+ assert_equals(el.getAttribute("tabindex"), "9999999999");
+ assert_equals(el.tabIndex, expectedDefault, "too large integer");
+ }, `default and invalid values for ${elName} without href`);
+ test(() => {
+ assert_equals(elLink.tabIndex, expectedDefault, "no attribute");
+ elLink.setAttribute("tabindex", "invalid");
+ assert_equals(elLink.getAttribute("tabindex"), "invalid");
+ assert_equals(elLink.tabIndex, expectedDefault, "invalid");
+ elLink.setAttribute("tabindex", "9999999999");
+ assert_equals(elLink.getAttribute("tabindex"), "9999999999");
+ assert_equals(elLink.tabIndex, expectedDefault, "too large integer");
+ }, `default and invalid values for ${elName} with href`);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-002.html b/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-002.html
new file mode 100644
index 0000000000..d2144e3d01
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/tabindex-002.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<title>MathML tabindex attribute</title>
+<meta name="timeout" content="long">
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<meta assert="flag" content="interact">
+<meta assert="assert" content="Check the sequential focus navigation order for MathML">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<div id="log"></div>
+<a href="#link">tabindex(html,href)</a>
+<math>
+ <mtext id="text1">tabindex(omitted)</mtext>
+ <mtext id="text2" tabindex="">tabindex(empty)</mtext>
+ <mtext id="text3" tabindex="a">tabindex(a)</mtext>
+ <mtext id="text4" tabindex="-1">tabindex(-1)</mtext>
+ <mtext id="text5" tabindex="0">tabindex(0)</mtext>
+ <mtext id="text6" href="#link">tabindex(href)</mtext>
+ <mtext id="text7" tabindex="3">tabindex(3)</mtext>
+ <mtext id="text8" tabindex="2">tabindex(2)</mtext>
+ <mtext id="text9" tabindex="2">tabindex(2)</mtext>
+ <mtext id="text10" tabindex="2">tabindex(2)</mtext>
+ <mtext id="text11" tabindex="1">tabindex(1)</mtext>
+</math>
+<script>
+
+var i = 0,
+ expectation = ["text11", "text8", "text9", "text10", "text7", "text5"],
+ results = [],
+ t = async_test("Elements with different tabindex must be focused sequentially when pressing 'Tab' keys");
+
+setup(function () {
+ document.body.focus();
+});
+
+document.querySelector("a").addEventListener("focus", function (evt) {
+ // Links are tab-navigable on that platform.
+ expectation.push("text6");
+ // TAB = '\ue004'
+ test_driver.send_keys(document.body, "\ue004");
+}, true);
+
+document.querySelector("math").addEventListener("focus", function (evt) {
+ results.push(evt.target.id);
+ i++;
+ if (i >= expectation.length) {
+ t.step(function () {
+ assert_array_equals(results, expectation);
+ });
+ t.done();
+ } else {
+ t.step(function () {
+ // TAB = '\ue004'
+ test_driver.send_keys(document.body, "\ue004");
+ });
+ }
+}, true);
+
+document.addEventListener("keydown", function (evt) {
+ t.step(function () {
+ assert_equals(evt.keyCode, 9, "Please press 'Tab' key.");
+ });
+}, true);
+
+t.step(function () {
+ // TAB = '\ue004'
+ test_driver.send_keys(document.body, "\ue004");
+});
+</script>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-1.html
new file mode 100644
index 0000000000..6b3ab07f1a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Unique Identifier (iframe)</title>
+</head>
+<body>
+
+ <div style="width: 100px; height: 500px;">
+ <math><mtext style="background: red; color: white;">FAIL</mtext></math>
+ </div>
+ <div style="width: 100px; height: 500px;">
+ <math><mtext style="background: green; color: white;"
+ id="PASS">PASS</mtext></math>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-2.html
new file mode 100644
index 0000000000..ade0110a27
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-iframe-2.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Unique Identifier (iframe reference)</title>
+</head>
+<body>
+
+ <div style="width: 100px; height: 500px;">
+ <math><mtext style="background: green; color: white;"
+ id="PASS" class="pass">PASS</mtext></math>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-ref.html
new file mode 100644
index 0000000000..a219b2c870
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Unique identifier (reference)</title>
+</head>
+<body>
+
+ <p>Test passes if you see the text "PASS".</p>
+
+ <iframe width="100" height="100" frameborder="0" scrolling="no"
+ marginheight="0" marginwidth="0"
+ src="unique-identifier-1-iframe-2.html#PASS"></iframe>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1.html
new file mode 100644
index 0000000000..f5de2757c3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-1.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Unique identifier</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="match" href="unique-identifier-1-ref.html"/>
+<meta name="assert" content="Verify that the id on a MathML element can be used as a fragment identifier in order to force initial scrolling.">
+</head>
+<body>
+
+ <p>Test passes if you see the text "PASS".</p>
+
+ <iframe width="100" height="100" frameborder="0" scrolling="no"
+ marginheight="0" marginwidth="0"
+ src="unique-identifier-1-iframe-1.html#PASS"></iframe>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-2.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-2.html
new file mode 100644
index 0000000000..d4e69df324
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Unique Identifier</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+<meta name="assert" content="Verify whether the getElementById() works for MathML elements.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("DOMContentLoaded", function() {
+ var mtext = document.getElementById("MTEXT");
+ test(function() {
+ assert_equals(mtext, document.body.lastElementChild.lastElementChild);
+ }, "getElementById()");
+ done();
+ });
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <math>
+ <mtext id="MTEXT_"></mtext>
+ <mtext id="MTEX"></mtext>
+ <mtext id="MTEXT"></mtext>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3-ref.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3-ref.html
new file mode 100644
index 0000000000..ef056e0082
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Unique identifier 3 (reference)</title>
+</head>
+<body>
+
+ <p>Test passes if you see the text "PASS".</p>
+ <math>
+ <mtext style="background: green; color: white;">PASS</mtext>
+ </math>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3.html b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3.html
new file mode 100644
index 0000000000..306ce41e25
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/html5-tree/unique-identifier-3.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>Unique Identifier</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="match" href="unique-identifier-3-ref.html"/>
+<meta name="assert" content="Verify that the id attribute affects CSS selectors.">
+<style>
+ #fail { display: none; }
+ #pass { background: green; }
+</style>
+</head>
+<body>
+
+ <p>Test passes if you see the text "PASS".</p>
+ <math>
+ <mtext id="fail" style="background: red; color: white;">FAIL</mtext>
+ <mtext id="pass" style="color: white;">PASS</mtext>
+ </math>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/text-and-math/basic-mathematical-alphanumeric-symbols-with-default-font.html b/testing/web-platform/tests/mathml/relations/text-and-math/basic-mathematical-alphanumeric-symbols-with-default-font.html
new file mode 100644
index 0000000000..c1e8d409b9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/text-and-math/basic-mathematical-alphanumeric-symbols-with-default-font.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Basic mathematical alphanumeric symbols with default font</title>
+ <meta name="assert" content="Verify whether the default font contains italic/bold/bold-italic characters from the Mathematical Alphanumeric Symbols block.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ span[data-name] {
+ font-size: 100px;
+ background: lightblue;
+ display: inline-block;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="log"></div>
+ <p><span id="frakturL" data-name="U+1D529 MATHEMATICAL FRAKTUR SMALL L">𝔩</span></p>
+ <p><span id="emSpace" data-name="U+2003 EM SPACE">&#x2003;</span></p>
+ <p><span data-test="Bold" data-name="U+1D416 MATHEMATICAL BOLD CAPITAL W">𝐖</span></p>
+ <p><span data-test="Italic" data-name="U+1D44A MATHEMATICAL ITALIC CAPITAL W">𝑊</span></p>
+ <p><span data-test="Bold-italic" data-name="U+1D47E MATHEMATICAL BOLD ITALIC CAPITAL">𝑾</span></p>
+ <script>
+ const frakturLWidth = document.getElementById("frakturL").getBoundingClientRect().width;
+ const emSpaceWidth = document.getElementById("emSpace").getBoundingClientRect().width;
+ Array.from(document.querySelectorAll('span[data-test]')).forEach(span => {
+ test(function() {
+ let spanWidth = span.getBoundingClientRect().width;
+ // This test expects the default font to provide a fraktur l than is much thiner than a bold/italic/bold-italic W.
+ // If the font lacks bold/italic/bold-italic W then a fortiori it is likely that its lacks fraktur l, so browsers
+ // will display "Tofu characters" for all of them (e.g. gray boxes or boxes containing the Unicode code points)
+ // with very similar widths, so the test is likely to fail.
+ assert_greater_than(spanWidth, frakturLWidth + emSpaceWidth / 4, `Width of '${span.dataset.name}' is much larger than '${frakturL.dataset.name}'`);
+ }, `${span.dataset.test} mathematical alphanumeric symbol with the default font`);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1-ref.html b/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1-ref.html
new file mode 100644
index 0000000000..3f7f764045
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<title>Open Font Format: USE_TYPO_METRICS (reference)</title>
+<style>
+ #green {
+ position: absolute;
+ background: green;
+ left: 10px;
+ width: 230px;
+ height: 230px;
+ }
+</style>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+
+ <div>
+ <div id="green"></div>
+ </div>
+</body>
diff --git a/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1.html b/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1.html
new file mode 100644
index 0000000000..1af8fdfde1
--- /dev/null
+++ b/testing/web-platform/tests/mathml/relations/text-and-math/use-typo-metrics-1.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<title>Open Font Format: USE_TYPO_METRICS</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#text-layout"/>
+<link rel="match" href="use-typo-metrics-1-ref.html"/>
+<meta name="assert" content="Verify that the USE_TYPO_METRICS flag from the OS/2 table is taken into account to calculate line height.">
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/lineheight5000-typolineheight2300.woff");
+ }
+ .green {
+ position: absolute;
+ background: green;
+ width: 115px;
+ }
+ .red {
+ position: absolute;
+ background: red;
+ width: 115px;
+ }
+ .forceHeight {
+ height: 230px;
+ }
+ .leftSide {
+ left: 10px;
+ }
+ .rightSide {
+ left: 125px;
+ }
+ span {
+ /* em=1000, lineHeight=5000, typoLineHeight=2300 and font-size=100px
+ implies typoLineHeightPx = 230px < 500px = lineHeightPx */
+ font-family: TestFont;
+ font-size: 100px;
+ color: transparent;
+ }
+</style>
+<body>
+ <p>Test passes if there is a green square and no red.</p>
+
+ <div>
+ <!-- Left side verifies that typoLineHeightPx <= 230px -->
+ <div class="leftSide red"><span>O</span></div>
+ <div class="leftSide green forceHeight"></div>
+
+ <!-- Right side verifies that typoLineHeightPx => 230px -->
+ <div class="rightSide red forceHeight"></div>
+ <div class="rightSide green"><span>O</span></div>
+ </div>
+</body>