summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/mathml/relations/html5-tree
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/html5-tree
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/html5-tree')
-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
45 files changed, 2547 insertions, 0 deletions
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>