summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/mathml/presentation-markup/operators
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/mathml/presentation-markup/operators
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/mathml/presentation-markup/operators')
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-2-ref.html31
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-2.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-3-ref.html31
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-3.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-4-ref.html31
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-4.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-5-ref.html35
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-5.html37
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-1-ref.html31
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-1.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-2-ref.html31
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-2.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-3-ref.html35
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-3.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-4-ref.html39
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-4.html41
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-2-ref.html32
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-2.html34
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-3-ref.html34
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-3.html34
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-4-ref.html34
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-4.html36
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-5-ref.html34
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-5.html34
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-1-ref.html34
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-1.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-2-ref.html31
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-2.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-3-ref.html31
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-3.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-1.html37
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-2.html35
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-ref.html30
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001-crash.html10
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001.html521
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-002.html559
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-003.html394
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001-ref.html95
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001.html123
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-002.html185
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/largeop-hit-testing.html64
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-axis-height-1.html75
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-dynamic-mozilla-347348-ref.xhtml17
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-dynamic-mozilla-347348.xhtml26
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-font-relative-lengths-001.html114
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002-ref.html48
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002.html66
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-ref.html26
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic.html51
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback.html28
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus-ref.html84
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus.html89
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-ref.html25
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-form.html30
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-2-ref.html28
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-2.html48
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2-ref.html363
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2.html363
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3-ref.html41
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3.html61
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4-ref.html20
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4.html19
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic-ref.html48
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic.html64
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-ref.html41
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace.html38
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-minsize-maxsize-001.html143
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator-ref.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator.html39
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default-ref.html18
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default.html24
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic-ref.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html27
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow-ref.html30
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow.html53
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-ref.html29
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits.html34
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace-ref.html47
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace.html52
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits-ref.html47
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits.html52
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace-ref.html78
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html71
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children-ref.html30
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children.html51
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-001.html68
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-dynamic-001.html154
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accent-dynamic-001-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accent-dynamic-001.html22
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accentunder-dynamic-001-ref.html12
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accentunder-dynamic-001.html22
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/non-spacing-accent-1-ref.xhtml17
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/non-spacing-accent-1.xhtml20
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1-notref.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12-ref.html14
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13-notref.html14
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2-ref.html14
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3-notref.html14
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4-ref.html18
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4.html19
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5-notref.html18
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5.html19
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6.html14
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7-notref.html13
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7.html14
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8-ref.html13
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8.html14
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9-notref.html15
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9.html14
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001-ref.html20
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001.html28
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002-ref.html30
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002.html39
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-combining.html159
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars-ref.html32
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars.html39
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-001.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-002.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-003.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-004.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-005.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-006.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-001.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-002.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-003.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-004.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-005.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-006.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-001.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-002.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-003.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-004.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-005.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-006.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-001.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-002.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-003.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-004.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-005.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-006.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-001.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-002.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-003.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-004.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-005.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-006.html33
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001-ref.html22
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001.html73
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/stretchy-underbar-1-ref.xhtml17
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/stretchy-underbar-1.xhtml20
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.css10
-rw-r--r--testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.js226
161 files changed, 8169 insertions, 0 deletions
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-2-ref.html
new file mode 100644
index 0000000000..f442a48dfe
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-2-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 1: mrow</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- mrow whose child is embellished op -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mo stretchy="false">&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-2.html
new file mode 100644
index 0000000000..f8bfb26d4e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 1: mrow</title>
+ <link rel="mismatch" href="embellished-op-1-2-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- mrow whose child is embellished op -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mo>&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-3-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-3-ref.html
new file mode 100644
index 0000000000..e134bfaceb
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-3-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 1: mstyle</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- mstyle whose child is embellished op -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mstyle><mo stretchy="false">&#xaf;</mo></mstyle>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-3.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-3.html
new file mode 100644
index 0000000000..85a21cc50b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-3.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 1: mstyle</title>
+ <link rel="mismatch" href="embellished-op-1-3-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- mstyle whose child is embellished op -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mstyle><mo>&#xaf;</mo></mstyle>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-4-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-4-ref.html
new file mode 100644
index 0000000000..149eff4b0d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-4-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 1: mpadded</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- mpadded whose child is embellished op -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mpadded><mo stretchy="false">&#xaf;</mo></mpadded>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-4.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-4.html
new file mode 100644
index 0000000000..b6c41256e8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-4.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 1: mpadded</title>
+ <link rel="mismatch" href="embellished-op-1-4-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- mpadded whose child is embellished op -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mpadded><mo>&#xaf;</mo></mpadded>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-5-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-5-ref.html
new file mode 100644
index 0000000000..cb4342e708
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-5-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 1: mphantom</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- mphantom whose child is embellished op -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mtext>g</mtext>
+ <mphantom><mo stretchy="false">&#xaf;</mo></mphantom>
+ <mtext>h</mtext>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-5.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-5.html
new file mode 100644
index 0000000000..1623991c79
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-1-5.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 1: mphantom</title>
+ <link rel="mismatch" href="embellished-op-1-5-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- mphantom whose child is embellished op -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mtext>g</mtext>
+ <mphantom><mo>&#xaf;</mo></mphantom>
+ <mtext>h</mtext>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-1-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-1-ref.html
new file mode 100644
index 0000000000..faa37e0d98
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-1-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: ignore space-like children</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- first child space-like -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mtext>g</mtext><mo stretchy="false">&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-1.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-1.html
new file mode 100644
index 0000000000..a43f65e00e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: ignore space-like children</title>
+ <link rel="mismatch" href="embellished-op-2-1-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- first child space-like -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mtext>g</mtext><mo>&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-2-ref.html
new file mode 100644
index 0000000000..903a30cc1f
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-2-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: ignore space-like children</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- last child space-like -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mo stretchy="false">&#xaf;</mo><mtext>g</mtext></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-2.html
new file mode 100644
index 0000000000..108353dcb3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: ignore space-like children</title>
+ <link rel="mismatch" href="embellished-op-2-2-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- last child space-like -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mo>&#xaf;</mo><mtext>g</mtext></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-3-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-3-ref.html
new file mode 100644
index 0000000000..c40dff710f
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-3-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: ignore space-like children</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- first and last children space-like -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mtext>g</mtext>
+ <mo stretchy="false">&#xaf;</mo>
+ <mtext>h</mtext>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-3.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-3.html
new file mode 100644
index 0000000000..e72cb68be3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-3.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: ignore space-like children</title>
+ <link rel="mismatch" href="embellished-op-2-3-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- first and last children space-like -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mtext>g</mtext><mo>&#xaf;</mo><mtext>h</mtext></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-4-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-4-ref.html
new file mode 100644
index 0000000000..b44f667442
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-4-ref.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: ignore space-like children</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- many space-like children -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mspace/>
+ <mtext>g</mtext>
+ <mspace/>
+ <mo stretchy="false">&#xaf;</mo>
+ <mspace/>
+ <mspace/>
+ <mtext>h</mtext>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-4.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-4.html
new file mode 100644
index 0000000000..7e60d5370b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-2-4.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: ignore space-like children</title>
+ <link rel="mismatch" href="embellished-op-2-4-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- many space-like children -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mspace/>
+ <mtext>g</mtext>
+ <mspace/>
+ <mo>&#xaf;</mo>
+ <mspace/>
+ <mspace/>
+ <mtext>h</mtext>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-2-ref.html
new file mode 100644
index 0000000000..2df02cf9a9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-2-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: maction and mrow-like as space-like children
+ </title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- space-like mrow -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mrow><mspace/></mrow><mo stretchy="false">&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-2.html
new file mode 100644
index 0000000000..ff7b1020cb
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: maction and mrow-like as space-like children
+ </title>
+ <link rel="mismatch" href="embellished-op-3-2-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- space-like mrow -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mrow><mspace/></mrow><mo>&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-3-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-3-ref.html
new file mode 100644
index 0000000000..4615e4de22
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-3-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: maction and mrow-like as space-like children
+ </title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- space-like mstyle -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mstyle><mspace/></mstyle><mo stretchy="false">&#xaf;</mo>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-3.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-3.html
new file mode 100644
index 0000000000..84dec135ca
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-3.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: maction and mrow-like as space-like children
+ </title>
+ <link rel="mismatch" href="embellished-op-3-3-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- space-like mstyle -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mstyle><mspace/></mstyle><mo>&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-4-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-4-ref.html
new file mode 100644
index 0000000000..e02ff28f18
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-4-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: maction and mrow-like as space-like children
+ </title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- space-like mpadded -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mpadded><mspace/></mpadded><mo stretchy="false">&#xaf;</mo>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-4.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-4.html
new file mode 100644
index 0000000000..648b0028f4
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-4.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: maction and mrow-like as space-like children
+ </title>
+ <link rel="mismatch" href="embellished-op-3-4-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- space-like mpadded -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mpadded><mspace/></mpadded><mo>&#xaf;</mo>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-5-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-5-ref.html
new file mode 100644
index 0000000000..c2c85f931c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-5-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: maction and mrow-like as space-like children
+ </title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- space-like mphantom -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mphantom><mspace/></mphantom><mo stretchy="false">&#xaf;</mo>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-5.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-5.html
new file mode 100644
index 0000000000..b6d032a589
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-3-5.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators: maction and mrow-like as space-like children
+ </title>
+ <link rel="mismatch" href="embellished-op-3-5-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- space-like mphantom -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mphantom><mspace/></mphantom><mo>&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-1-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-1-ref.html
new file mode 100644
index 0000000000..bcf58699ea
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-1-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 4-1: some non-space-like children</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- two embellished operators -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow>
+ <mo stretchy="false">&#xaf;</mo>
+ <mo stretchy="false">&#xaf;</mo>
+ </mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-1.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-1.html
new file mode 100644
index 0000000000..724d39ceab
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 4-1: some non-space-like children</title>
+ <link rel="match" href="embellished-op-4-1-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- two embellished operators -->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mo>&#xaf;</mo><mo>&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-2-ref.html
new file mode 100644
index 0000000000..b226d69a97
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-2-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 4-2: some non-space-like children</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- a non-space-like child before-->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mi>g</mi><mo stretchy="false">&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-2.html
new file mode 100644
index 0000000000..1a3724cb9d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 4-2: some non-space-like children</title>
+ <link rel="match" href="embellished-op-4-2-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- a non-space-like child before-->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mi>g</mi><mo>&#xaf;</mo></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-3-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-3-ref.html
new file mode 100644
index 0000000000..8786076642
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-3-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 4-3: some non-space-like children</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- a non-space-like child after-->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mo stretchy="false">&#xaf;</mo><mi>g</mi></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-3.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-3.html
new file mode 100644
index 0000000000..1be87b81dd
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-4-3.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 4-3: some non-space-like children</title>
+ <link rel="match" href="embellished-op-4-3-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <!-- a non-space-like child after-->
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mtext>abcdef</mtext>
+ <mrow><mo>&#xaf;</mo><mi>g</mi></mrow>
+ </mover>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-1.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-1.html
new file mode 100644
index 0000000000..946bda0dc7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 5: vertical stretchy operator</title>
+ <link rel="match" href="embellished-op-5-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mrow>
+ <msub>
+ <mo>|</mo>
+ <mspace/>
+ </msub>
+ </mrow>
+ <mspace height="30px" depth="30px"/>
+ </mrow>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-2.html
new file mode 100644
index 0000000000..95bd2694a5
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 5: vertical stretchy operator</title>
+ <link rel="match" href="embellished-op-5-ref.html"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=21479"/>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <msub>
+ <mo>|</mo>
+ <mspace/>
+ </msub>
+ <mspace height="30px" depth="30px"/>
+ </mrow>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-ref.html
new file mode 100644
index 0000000000..da9d238775
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-op-5-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>embellished operators 5: vertical stretchy operator</title>
+ <link rel="stylesheet" href="/fonts/ahem.css" />
+ <style>
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ math {
+ font: 25px/1 Ahem;
+ }
+ mo {
+ font-family: operators;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div>
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mrow>
+ <mo>|</mo>
+ <mspace height="30px" depth="30px"/>
+ </mrow>
+ </math>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001-crash.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001-crash.html
new file mode 100644
index 0000000000..15e9a0367c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001-crash.html
@@ -0,0 +1,10 @@
+<!DOCTYPE>
+<!-- See https://github.com/w3c/mathml-core/issues/108 -->
+<math>
+ <mrow style="display: inline">A</mrow>
+</math>
+<math>
+ <mrow>
+ <mrow style="display: inline">A</mrow>
+ </mrow>
+</math>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001.html
new file mode 100644
index 0000000000..b8e2cefc1c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-001.html
@@ -0,0 +1,521 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Embellished operators</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators">
+<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<meta name="assert" content="Verify definition of embellished operators">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/box-navigation.js"></script>
+<style>
+ /* Default spacing of operator 'X' is 0.2777777777777778em so quite different
+ from the measured/specified 0em and 1em. */
+ math, math * {
+ font: 25px/1 Ahem;
+ }
+ mn {
+ color: black;
+ }
+ .testedElement mo {
+ color: yellow !important;
+ }
+ .testedElement, .testedElement * {
+ color: blue !important;
+ background: blue !important;
+ }
+ .oof1 {
+ position: absolute;
+ }
+ .oof2 {
+ position: fixed;
+ }
+ .nobox {
+ display: none;
+ }
+</style>
+<script>
+ function spaceBeforeElement(id) {
+ var element = document.getElementById(id);
+ var mnBefore = previousInFlowSibling(element);
+ return element.getBoundingClientRect().left - mnBefore.getBoundingClientRect().right;
+ }
+
+ function spaceBeforeCoreOperator(id) {
+ var element = document.getElementById(id);
+ var coreMo = element.getElementsByTagName("mo")[0];
+ return coreMo.getBoundingClientRect().left - element.getBoundingClientRect().left;
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ var epsilon = 1;
+ var emToPx = 25;
+
+ ["mrow", "mstyle", "mphantom", "mpadded", "merror", "mprescripts", "none", "unknown"].forEach(tag => {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ assert_approx_equals(spaceBeforeElement(`${tag}-op-1`), 2 * emToPx, epsilon);
+ assert_approx_equals(spaceBeforeCoreOperator(`${tag}-op-1`), 0, epsilon);
+ }, `${tag} (embellished operator)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ assert_approx_equals(spaceBeforeElement(`${tag}-op-2`), 2 * emToPx, epsilon);
+ assert_approx_equals(spaceBeforeCoreOperator(`${tag}-op-2`), 0, epsilon);
+ }, `${tag} (embellished operator, from in-flow children)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ assert_approx_equals(spaceBeforeElement(`${tag}-nonop-1`), 0, epsilon);
+ assert_approx_equals(spaceBeforeCoreOperator(`${tag}-nonop-1`), 2 * emToPx, epsilon);
+ }, `${tag} (not embellished operator)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ assert_approx_equals(spaceBeforeElement(`${tag}-nonop-2`), 0, epsilon);
+ assert_approx_equals(spaceBeforeCoreOperator(`${tag}-nonop-2`), 2 * emToPx, epsilon);
+ }, `${tag} (not embellished operator, from in-flow children)`);
+ });
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <!-- mrow is an embellished operator if its in-flow children consist
+ of one embellished operator and zero or more space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <mrow id="mrow-op-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mtext class="space-like">X</mtext>
+ </mrow>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mrow id="mrow-nonop-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ </mrow>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mrow id="mrow-op-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mtext class="space-like">X</mtext>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mrow>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mrow id="mrow-nonop-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mrow>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <!-- mstyle is an embellished operator if its in-flow children consist
+ of one embellished operator and zero or more space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <mstyle id="mstyle-op-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mstyle>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mstyle id="mstyle-nonop-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ </mstyle>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mstyle id="mstyle-op-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mstyle>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mstyle id="mstyle-nonop-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mstyle>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <!-- mphantom is an embellished operator if its in-flow children consist
+ of one embellished operator and zero or more space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <mphantom id="mphantom-op-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mphantom>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mphantom id="mphantom-nonop-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ </mphantom>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mphantom id="mphantom-op-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mphantom>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mphantom id="mphantom-nonop-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mphantom>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <!-- mpadded is an embellished operator if its in-flow children consist
+ of one embellished operator and zero or more space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <mpadded id="mpadded-op-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mpadded>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mpadded id="mpadded-nonop-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ </mpadded>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mpadded id="mpadded-op-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mpadded>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mpadded id="mpadded-nonop-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mpadded>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <!-- merror is an embellished operator if its in-flow children consist
+ of one embellished operator and zero or more space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <merror id="merror-op-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </merror>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <merror id="merror-nonop-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ </merror>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <merror id="merror-op-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </merror>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <merror id="merror-nonop-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </merror>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <!-- mprescripts is an embellished operator if its in-flow children consist
+ of one embellished operator and zero or more space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <mprescripts id="mprescripts-op-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mprescripts>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mprescripts id="mprescripts-nonop-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ </mprescripts>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mprescripts id="mprescripts-op-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mprescripts>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mprescripts id="mprescripts-nonop-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mprescripts>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <!-- none is an embellished operator if its in-flow children consist
+ of one embellished operator and zero or more space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <none id="none-op-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </none>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <none id="none-nonop-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ </none>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <none id="none-op-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </none>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <none id="none-nonop-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </none>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <!-- unknown is an embellished operator if its in-flow children consist
+ of one embellished operator and zero or more space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <unknown id="unknown-op-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </unknown>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <unknown id="unknown-nonop-1" class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ </unknown>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <unknown id="unknown-op-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </unknown>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <unknown id="unknown-nonop-2" class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn> <!-- "mn" is not space-like -->
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </unknown>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-002.html
new file mode 100644
index 0000000000..7ab05441c3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-002.html
@@ -0,0 +1,559 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Embellished operators</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators">
+<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<meta name="assert" content="Verify definition of embellished operators">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/box-navigation.js"></script>
+<style>
+ /* Default spacing of operator 'X' is 0.2777777777777778em so quite different
+ from the measured/specified 0em and 1em. */
+ math, math * {
+ font: 25px/1 Ahem;
+ }
+ mn {
+ color: black;
+ }
+ mtext.space-like {
+ color: lightblue !important;
+ }
+ .testedElement mo {
+ color: yellow !important;
+ }
+ .testedElement, .testedElement * {
+ color: blue !important;
+ background: blue !important;
+ }
+ .oof1 {
+ position: absolute;
+ }
+ .oof2 {
+ position: fixed;
+ }
+ .nobox {
+ display: none;
+ }
+</style>
+<script>
+ function spaceBeforeElement(element) {
+ var mnBefore = previousInFlowSibling(element);
+ return element.getBoundingClientRect().left - mnBefore.getBoundingClientRect().right;
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ var epsilon = 1;
+ var emToPx = 25;
+
+ ["msub", "msup", "msubsup", "munder", "mover", "munderover",
+ "mmultiscripts", "mfrac"].forEach(tag => {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[0];
+ assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon);
+ }, `${tag} (embellished operator)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[1];
+ assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon);
+ }, `${tag} (embellished operator, from in-flow children)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[2];
+ assert_approx_equals(spaceBeforeElement(element), 0, epsilon);
+ }, `${tag} (not embellished operator)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[3];
+ assert_approx_equals(spaceBeforeElement(element), 0, epsilon);
+ }, `${tag} (not embellished operator, from in-flow children)`);
+ });
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <!-- <msub>, <msup>, <msubsup>, <munder>, <mover>, <munderover>,
+ <mmultiscripts>, <mfrac> are embellished
+ operators if their first in-flow
+ child exists and is an embellished operator -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <msub class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ </msub>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <msup class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ </msup>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <msubsup class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ <mn>X</mn>
+ </msubsup>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <munder class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ </munder>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mover class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ </mover>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <munderover class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ </munderover>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mmultiscripts class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ <mn>X</mn>
+ <mn>X</mn>
+ <mn>X</mn>
+ </mmultiscripts>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mfrac class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ </mfrac>
+ <mn>X</mn>
+ </math>
+ </p>
+
+ <!-- Only in-flow children affect determination of embellished operators. -->
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <msub class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </msub>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <msup class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </msup>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <msubsup class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </msubsup>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <munder class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </munder>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mover class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mover>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <munderover class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </munderover>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mmultiscripts class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mmultiscripts>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mfrac class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mfrac>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+
+ <!-- <msub>, <msup>, <msubsup>, <munder>, <mover>, <munderover>,
+ <mmultiscripts>, <mfrac> are not embellished
+ operators if their first in-flow child is not an embellished operator -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <msub class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </msub>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <msup class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </msup>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <msubsup class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ </msubsup>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <munder class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </munder>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mover class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mover>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <munderover class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </munderover>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mmultiscripts class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ <mn>X</mn>
+ <mn>X</mn>
+ </mmultiscripts>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mfrac class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mfrac>
+ <mn>X</mn>
+ </math>
+ </p>
+
+ <!-- Only in-flow children affect determination of embellished operators. -->
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <msub class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </msub>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <msup class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </msup>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <msubsup class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </msubsup>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <munder class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </munder>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mover class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mover>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <munderover class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </munderover>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mmultiscripts class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mmultiscripts>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mfrac class="testedElement">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mfrac>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-003.html
new file mode 100644
index 0000000000..7b36665787
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-003.html
@@ -0,0 +1,394 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Embellished operators</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators">
+<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<meta name="assert" content="Verify definition of embellished operators">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/box-navigation.js"></script>
+<style>
+ /* Default spacing of operator 'X' is 0.2777777777777778em so quite different
+ from the measured/specified 0em and 1em. */
+ math, math * {
+ font: 25px/1 Ahem;
+ }
+ mn {
+ color: black;
+ }
+ mtext.space-like {
+ color: lightblue !important;
+ }
+ .testedElement mo {
+ color: yellow !important;
+ }
+ .testedElement, .testedElement * {
+ color: blue !important;
+ background: blue !important;
+ }
+ .oof1 {
+ position: absolute;
+ }
+ .oof2 {
+ position: fixed;
+ }
+ .nobox {
+ display: none;
+ }
+ .allChildrenVisible > *:not(.nobox) {
+ display: inline math;
+ }
+</style>
+<script>
+ function spaceBeforeElement(element) {
+ var mnBefore = previousInFlowSibling(element);
+ return element.getBoundingClientRect().left - mnBefore.getBoundingClientRect().right;
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function runTests() {
+ var epsilon = 1;
+ var emToPx = 25;
+
+ ["maction", "semantics"].forEach(tag => {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[0];
+ assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon);
+ }, `${tag} (embellished operator)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[1];
+ assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon);
+ }, `${tag} (embellished operator, from in-flow children)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[2];
+ assert_approx_equals(spaceBeforeElement(element), 0, epsilon);
+ }, `${tag} (not embellished operator)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[3];
+ assert_approx_equals(spaceBeforeElement(element), 0, epsilon);
+ }, `${tag} (not embellished operator, from in-flow children)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[4];
+ assert_approx_equals(spaceBeforeElement(element), 0, epsilon);
+ }, `${tag} (not embellished operator, empty)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[5];
+ assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon);
+ }, `${tag} (embellished operator, one child)`);
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var element = document.getElementsByTagName(tag)[6];
+ assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon);
+ }, `${tag} (embellished operator, complex)`);
+ });
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <!-- <semantics> or <maction> are embellished operators if their children
+ consist (in any order) of one embellished operator and zero or more
+ space-like elements. -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <maction class="testedElement" actiontype="statusline">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>STATUS MESSAGE</mn>
+ </maction>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <semantics class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <annotation>TEXT ANNOTATION</annotation>
+ <mn>X</mn>
+ </semantics>
+ <mn>X</mn>
+ </math>
+ </p>
+
+ <!-- Only in-flow children affect determination of embellished operators. -->
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <maction class="testedElement" actiontype="statusline">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>STATUS MESSAGE</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </maction>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <semantics class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <annotation>TEXT ANNOTATION</annotation>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </semantics>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+
+ <!-- <semantics> or <maction> are not embellished
+ operators if their first in-flow child is not an embellished operator -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <msub class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </msub>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <msup class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </msup>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <msubsup class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ </msubsup>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <munder class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </munder>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mover class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mover>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <munderover class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </munderover>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mmultiscripts class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn>X</mn>
+ <mn>X</mn>
+ <mn>X</mn>
+ </mmultiscripts>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <mfrac class="testedElement">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mfrac>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <maction class="testedElement" actiontype="statusline">
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">STATUS MESSAGE</mo>
+ </maction>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <semantics class="testedElement">
+ <mrow>
+ <mn>X</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ </mrow>
+ <annotation>TEXT ANNOTATION</annotation>
+ </semantics>
+ <mn>X</mn>
+ </math>
+ </p>
+
+ <!-- Only in-flow children affect determination of embellished operators. -->
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <maction class="testedElement" actiontype="statusline">
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">STATUS MESSAGE</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </maction>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <semantics class="testedElement">
+ <mrow>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </mrow>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <annotation>TEXT ANNOTATION</annotation>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </semantics>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+
+ <!-- Empty <maction> and <semantics> (invalid in MathML3). -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <maction class="testedElement">
+ </maction>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <semantics class="testedElement">
+ </semantics>
+ <mn>X</mn>
+ </math>
+ </p>
+
+ <!-- One-child <maction> and <semantics> (invalid in MathML3). -->
+ <p>
+ <math>
+ <mn>X</mn>
+ <maction class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </maction>
+ <mn>X</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>X</mn>
+ <semantics class="testedElement">
+ <mo lspace="2em" rspace="0em">X</mo>
+ </semantics>
+ <mn>X</mn>
+ </math>
+ </p>
+
+ <!-- Complex structure (invalid in MathML3). -->
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <maction class="testedElement allChildrenVisible">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mtext class="space-like">X</mtext>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </maction>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <semantics class="testedElement allChildrenVisible">
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mo lspace="2em" rspace="0em">X</mo>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mtext class="space-like">X</mtext>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </semantics>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ <mn>X</mn>
+ <mn class="oof1">0</mn><mn class="oof2">1</mn><mn class="nobox">2</mn>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001-ref.html
new file mode 100644
index 0000000000..b37ce125a7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001-ref.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Embellished operators - tree change and relayout (reference)</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ math, math * {
+ font: 25px/1 Ahem;
+ }
+ mn {
+ color: black;
+ }
+ mo {
+ color: blue;
+ }
+</style>
+</head>
+<body>
+ <p>There should be the five 1em squares on the same line, with colors
+ black, orange, blue, orange, black:</p>
+ <math display="block">
+ <mrow style="background: yellow">
+ <mn>1</mn>
+ <mrow style="background: orange">
+ <mrow id="change_to_non_embellished_operator">
+ <mrow>
+ <mo lspace="1em" rspace="1em">X</mo>
+ </mrow>
+ <mn></mn>
+ </mrow>
+ </mrow>
+ <mn>2</mn>
+ </mrow>
+ </math>
+
+ <p>There should be the five 1em squares on the same line, with colors
+ black, yellow, blue, yellow, black:</p>
+ <math display="block">
+ <mrow style="background: yellow">
+ <mn>3</mn>
+ <mrow style="background: orange">
+ <mrow id="change_to_embellished_operator">
+ <mrow>
+ <mo lspace="1em" rspace="1em">X</mo>
+ </mrow>
+ </mrow>
+ </mrow>
+ <mn>4</mn>
+ </mrow>
+ </math>
+
+ <p>There should be the five 1em squares on the same line, with colors
+ black, orange, blue, orange, black:</p>
+ <math display="block">
+ <mrow style="background: yellow">
+ <mn>5</mn>
+ <mrow style="background: orange">
+ <mrow>
+ <mrow>
+ <mo lspace="1em" rspace="1em">X</mo>
+ </mrow>
+ </mrow>
+ <mrow id="change_to_not_space_like">
+ <mspace></mspace>
+ <mtext></mtext>
+ <mn></mn>
+ </mrow>
+ </mrow>
+ <mn>6</mn>
+ </mrow>
+ </math>
+
+ <p>There should be the five 1em squares on the same line, with colors
+ black, yellow, blue, yellow, black:</p>
+ <math display="block">
+ <mrow style="background: yellow">
+ <mn>7</mn>
+ <mrow style="background: orange">
+ <mrow>
+ <mrow>
+ <mo lspace="1em" rspace="1em">X</mo>
+ </mrow>
+ <mrow id="change_to_space_like">
+ <mspace></mspace>
+ <mtext></mtext>
+ </mrow>
+ </mrow>
+ </mrow>
+ <mn>8</mn>
+ </mrow>
+ </math>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001.html
new file mode 100644
index 0000000000..09a7fe412a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-001.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>Embellished operators - tree change and relayout</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators">
+<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<script src="/mathml/support/mathml-fragments.js"></script>
+<meta name="assert" content="Verify relayout of an mrow with a child that has a deeply nested <mo> element.">
+<link rel="match" href="embellished-operator-dynamic-001-ref.html">
+<style>
+ math, math * {
+ font: 25px/1 Ahem;
+ }
+ mn {
+ color: black;
+ }
+ mo {
+ color: blue;
+ }
+</style>
+</head>
+<body>
+ <p>There should be the five 1em squares on the same line, with colors
+ black, orange, blue, orange, black:</p>
+ <math display="block">
+ <mrow style="background: yellow">
+ <mn>1</mn>
+ <mrow style="background: orange">
+ <mrow id="change_to_not_embellished_operator">
+ <mrow>
+ <mo lspace="1em" rspace="1em">X</mo>
+ </mrow>
+ </mrow>
+ </mrow>
+ <mn>2</mn>
+ </mrow>
+ </math>
+
+ <p>There should be the five 1em squares on the same line, with colors
+ black, yellow, blue, yellow, black:</p>
+ <math display="block">
+ <mrow style="background: yellow">
+ <mn>3</mn>
+ <mrow style="background: orange">
+ <mrow id="change_to_embellished_operator">
+ <mrow>
+ <mo lspace="1em" rspace="1em">X</mo>
+ </mrow>
+ <mn></mn>
+ </mrow>
+ </mrow>
+ <mn>4</mn>
+ </mrow>
+ </math>
+
+ <p>There should be the five 1em squares on the same line, with colors
+ black, orange, blue, orange, black:</p>
+ <math display="block">
+ <mrow style="background: yellow">
+ <mn>5</mn>
+ <mrow style="background: orange">
+ <mrow>
+ <mrow>
+ <mo lspace="1em" rspace="1em">X</mo>
+ </mrow>
+ </mrow>
+ <mrow id="change_to_not_space_like">
+ <mspace></mspace>
+ <mtext></mtext>
+ </mrow>
+ </mrow>
+ <mn>6</mn>
+ </mrow>
+ </math>
+
+ <p>There should be the five 1em squares on the same line, with colors
+ black, yellow, blue, yellow, black:</p>
+ <math display="block">
+ <mrow style="background: yellow">
+ <mn>7</mn>
+ <mrow style="background: orange">
+ <mrow>
+ <mrow>
+ <mo lspace="1em" rspace="1em">X</mo>
+ </mrow>
+ <mrow id="change_to_space_like">
+ <mspace></mspace>
+ <mtext></mtext>
+ <mn></mn>
+ </mrow>
+ </mrow>
+ </mrow>
+ <mn>8</mn>
+ </mrow>
+ </math>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>
+ MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");
+
+ // After adding a not space-like element to mrow1, it is no longer an
+ // embellished operator : lspace/rspace should be around its mrow child.
+ let mrow1 = document.getElementById("change_to_not_embellished_operator");
+ mrow1.appendChild(FragmentHelper.createElement("mn"));
+
+ // Removing the not space-like element from mrow2 makes its orange parent
+ // an embellished operator. lspace/rspace should be around this parent.
+ let mrow2 = document.getElementById("change_to_embellished_operator");
+ mrow2.removeChild(mrow2.lastElementChild);
+
+ // Same as above, but changing the space-like nature of one child.
+ let mrow3 = document.getElementById("change_to_not_space_like");
+ mrow3.appendChild(FragmentHelper.createElement("mn"));
+ let mrow4 = document.getElementById("change_to_space_like");
+ mrow4.removeChild(mrow4.lastElementChild);
+
+ document.documentElement.classList.remove('reftest-wait');
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-002.html
new file mode 100644
index 0000000000..2c52684765
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/embellished-operator-dynamic-002.html
@@ -0,0 +1,185 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Embellished operators - tree change and relayout</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators">
+<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<link rel="help" href="https://chromium-review.googlesource.com/c/chromium/src/+/3059456">
+<meta name="assert" content="Verify relayout of an mrow with a child that has a deeply nested <mo> element.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ math, math * {
+ font: 25px/1 Ahem;
+ }
+ mn {
+ color: black;
+ }
+ .relative_positioned_and_fixed_size {
+ position: relative;
+ height: 0px;
+ width: 0px;
+ overflow: scroll;
+ }
+</style>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+ var epsilon = 1;
+ var emToPx = 25;
+
+ function assertCorrectSpacing(container,
+ zero_size_mrow_is_embellished_op) {
+ // The container should add lspace/rspace around the zero size mrow
+ // if and only if that mrow is an embellished operator.
+ let mnBefore = container.children[0].getBoundingClientRect();
+ let zeroSizeMrow = container.children[1].getBoundingClientRect();
+ let mnAfter = container.children[2].getBoundingClientRect();
+ assert_approx_equals(zeroSizeMrow.left - mnBefore.right,
+ zero_size_mrow_is_embellished_op ?
+ emToPx * 1 : 0, epsilon,
+ "lspace");
+ assert_approx_equals(mnAfter.left - zeroSizeMrow.right,
+ zero_size_mrow_is_embellished_op ?
+ emToPx * 2 : 0, epsilon,
+ "rspace");
+ }
+
+ let container1 = document.getElementById("container1");
+ test(function() {
+ assertCorrectSpacing(container1, true);
+ }, "container1: Initially an embellished operator");
+
+ let container2 = document.getElementById("container2");
+ test(function() {
+ assertCorrectSpacing(container2, false);
+ }, "container2: Initially not an embellished operator");
+
+ test(function() {
+ let mrow1 = document.getElementById("change_to_not_embellished_operator");
+ mrow1.appendChild(FragmentHelper.createElement("mn"));
+ assertCorrectSpacing(container1, false);
+ }, " container1: No longer an embellished operator");
+
+ test(function() {
+ let mrow2 = document.getElementById("change_to_embellished_operator");
+ mrow2.removeChild(mrow2.lastElementChild);
+ assertCorrectSpacing(container2, true);
+ }, "container2: Became an embellished operator");
+
+ let container3 = document.getElementById("container3");
+ test(function() {
+ assertCorrectSpacing(container3, true);
+ }, "container3: Initially an embellished operator (testing space-like)");
+
+ let container4 = document.getElementById("container4");
+ test(function() {
+ assertCorrectSpacing(container4, false);
+ }, "container4/space-like: Initially not an embellished operator (testing space-like)");
+
+ test(function() {
+ let mrow = document.getElementById("change_to_not_space_like");
+ mrow.appendChild(FragmentHelper.createElement("mn"));
+ assertCorrectSpacing(container3, false);
+ }, " container3: No longer an embellished operator (testing space-like)");
+
+ test(function() {
+ let mrow = document.getElementById("change_to_space_like");
+ mrow.removeChild(mrow.lastElementChild);
+ assertCorrectSpacing(container4, true);
+ }, "container4: Became an embellished operator (testing space-like)");
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+
+ <div>
+ <math display="block">
+ <mrow id="container1">
+ <mn>1</mn>
+ <mrow class="relative_positioned_and_fixed_size">
+ <mrow id="change_to_not_embellished_operator">
+ <mrow>
+ <mo lspace="1em" rspace="2em"></mo>
+ </mrow>
+ </mrow>
+ </mrow>
+ <mn>2</mn>
+ </mrow>
+ </math>
+ </div>
+
+ <div>
+ <math display="block">
+ <mrow id="container2">
+ <mn>3</mn>
+ <mrow class="relative_positioned_and_fixed_size">
+ <mrow id="change_to_embellished_operator">
+ <mrow>
+ <mo lspace="1em" rspace="2em"></mo>
+ </mrow>
+ <mn></mn>
+ </mrow>
+ </mrow>
+ <mn>4</mn>
+ </mrow>
+ </math>
+ </div>
+
+ <div>
+ <math display="block">
+ <mrow id="container3">
+ <mn>5</mn>
+ <mrow>
+ <mrow>
+ <mrow>
+ <mo lspace="1em" rspace="2em"></mo>
+ </mrow>
+ <mrow class="relative_positioned_and_fixed_size">
+ <mrow id="change_to_not_space_like">
+ <mspace></mspace>
+ <mtext></mtext>
+ </mrow>
+ </mrow>
+ </mrow>
+ </mrow>
+ <mn>6</mn>
+ </mrow>
+ </math>
+ </div>
+
+ <div>
+ <math display="block">
+ <mrow id="container4">
+ <mn>7</mn>
+ <mrow>
+ <mrow>
+ <mrow>
+ <mo lspace="1em" rspace="2em"></mo>
+ </mrow>
+ <mrow class="relative_positioned_and_fixed_size">
+ <mrow id="change_to_space_like">
+ <mspace></mspace>
+ <mtext></mtext>
+ <mn></mn>
+ </mrow>
+ </mrow>
+ </mrow>
+ </mrow>
+ <mn>8</mn>
+ </mrow>
+ </math>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/largeop-hit-testing.html b/testing/web-platform/tests/mathml/presentation-markup/operators/largeop-hit-testing.html
new file mode 100644
index 0000000000..2b81eb692a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/largeop-hit-testing.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test hit testing on large operators</title>
+<meta name="assert" content="Verify that hit testing works on large operators.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ @font-face {
+ font-family: TestFont;
+ src: url("/fonts/math/largeop-displayoperatorminheight5000.woff");
+ }
+ mo {
+ font-family: TestFont;
+ font-size: 16px;
+ }
+</style>
+<script>
+ function getBox(aId) {
+ return document.getElementById(aId).getBoundingClientRect();
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+
+ let bbox = getBox("largeop");
+ let hit = document.getElementById("largeop");
+ let reference = getBox("reference");
+ assert_true(bbox.height > reference.height, "height of large op is bigger than the equivalent normal operator");
+ assert_equals(hit, document.elementFromPoint(bbox.left + 1, bbox.top + 1), "hit testing top-left corner of large op works");
+ assert_equals(hit, document.elementFromPoint(bbox.right - 1, bbox.bottom - 1), "hit testing bottom-right corner of large op works");
+ }, "Large op hit testing");
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <math>
+ <mtable>
+ <mtr>
+ <mtd>
+ <mstyle displaystyle="false">
+ <mo id="reference">&#x2AFF;</mo>
+ </mstyle>
+ </mtd>
+ <mtd>
+ <mstyle displaystyle="true">
+ <mo id="largeop">&#x2AFF;</mo>
+ </mstyle>
+ </mtd>
+ </mtr>
+ </mtable>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-axis-height-1.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-axis-height-1.html
new file mode 100644
index 0000000000..6de6284188
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-axis-height-1.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>mo axis height</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<meta name="assert" content="Element mo correctly uses the axis height parameter from the MATH table.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ math, mspace {
+ font-size: 10px;
+ }
+ @font-face {
+ font-family: axisheight5000-verticalarrow14000;
+ src: url("/fonts/math/axisheight5000-verticalarrow14000.woff");
+ }
+</style>
+<script>
+ var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000
+ var epsilon = 5;
+
+ function getBox(aId) {
+ return document.getElementById(aId).getBoundingClientRect();
+ }
+
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+ test(function() {
+ var v1 = 5000 * emToPx;
+ var moMiddle = (getBox("mo1").bottom + getBox("mo1").top) / 2;
+ assert_approx_equals(getBox("mo1").height,
+ 14000 * emToPx, epsilon, "mo: size");
+ assert_approx_equals(getBox("baseline1").bottom - moMiddle,
+ v1, epsilon, "mo: axis height");
+ }, "AxisHeight (size variant)");
+
+ test(function() {
+ var v1 = 5000 * emToPx;
+ var moMiddle = (getBox("mo2").bottom + getBox("mo2").top) / 2;
+ assert_approx_equals(getBox("mo2").height,
+ 2 * (getBox("target2").height - v1),
+ epsilon, "mo: size");
+ assert_approx_equals(getBox("baseline2").bottom - moMiddle,
+ v1, epsilon, "mo: axis height");
+ }, "AxisHeight (glyph assembly)");
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math style="font-family: axisheight5000-verticalarrow14000;">
+ <mrow>
+ <mspace id="baseline1" style="background: blue" width="50px" height="1px"/>
+ <mpadded voffset="50px"><mspace style="background: cyan" width="50px" height="1px"/></mpadded>
+ <mo id="mo1" symmetric="true" style="color: green">&#x21A8;</mo>
+ <mspace style="background: gray" width="10px" height="50px"/>
+ </mrow>
+ </math>
+ <math style="font-family: axisheight5000-verticalarrow14000;">
+ <mrow>
+ <mspace id="baseline2" style="background: blue" width="50px" height="1px"/>
+ <mpadded voffset="50px"><mspace style="background: cyan" width="50px" height="1px"/></mpadded>
+ <mo id="mo2" symmetric="true" style="color: green">&#x21A8;</mo>
+ <mspace id="target2" style="background: gray" width="10px" height="200px"/>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-dynamic-mozilla-347348-ref.xhtml b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-dynamic-mozilla-347348-ref.xhtml
new file mode 100644
index 0000000000..0deb51d5f2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-dynamic-mozilla-347348-ref.xhtml
@@ -0,0 +1,17 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+</head>
+
+<body>
+
+<div><math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
+<mrow>
+ <mi>x</mi>
+ <mo id="mo"></mo>
+ <mi>y</mi>
+ </mrow>
+</math></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-dynamic-mozilla-347348.xhtml b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-dynamic-mozilla-347348.xhtml
new file mode 100644
index 0000000000..a8471e116a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-dynamic-mozilla-347348.xhtml
@@ -0,0 +1,26 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=347348"/>
+<link rel="match" href="mo-dynamic-mozilla-347348-ref.xhtml"/>
+<script>
+function foo()
+{
+ var mo = document.getElementById("mo");
+ mo.removeChild(mo.firstChild);
+}
+</script>
+</head>
+
+<body onload="foo();">
+
+<div><math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
+<mrow>
+ <mi>x</mi>
+ <mo id="mo">=</mo>
+ <mi>y</mi>
+ </mrow>
+</math></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-font-relative-lengths-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-font-relative-lengths-001.html
new file mode 100644
index 0000000000..209e59ee33
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-font-relative-lengths-001.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Font-relative lengths on an operator</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators">
+<link rel="help" href="https://w3c.github.io/mathml-core/#definition-of-space-like-elements">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<meta name="assert" content="Verify font-relative lengths refer to the core operator, not the embellished operator">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ math {
+ font: 100px/1 Ahem;
+ }
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ mo {
+ font-family: operators;
+ }
+</style>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+ var epsilon = 1;
+ var baseSizePx = 100;
+
+ test(function() {
+ var beforeRight = document.getElementById("before1").getBoundingClientRect().right;
+ var afterLeft = document.getElementById("after1").getBoundingClientRect().left;
+ var fontScalePercent = .5;
+ var lspaceEm = 1;
+ var moWidthEm = 1;
+ assert_approx_equals(afterLeft - beforeRight, baseSizePx * fontScalePercent * (lspaceEm + moWidthEm), epsilon, "baseSizePx * fontScalePercent * lspaceEm");
+ }, `font-relative lspace refers to the core operator`);
+
+ test(function() {
+ var beforeRight = document.getElementById("before2").getBoundingClientRect().right;
+ var afterLeft = document.getElementById("after2").getBoundingClientRect().left;
+ var fontScalePercent = 2;
+ var rspaceEm = 1;
+ var moWidthEm = 1;
+ assert_approx_equals(afterLeft - beforeRight, baseSizePx * fontScalePercent * (rspaceEm + moWidthEm), epsilon, "baseSizePx * fontScalePercent * rspaceEm");
+ }, `font-relative rspace refers to the core operator`);
+
+ test(function() {
+ var moStretchSize = document.getElementById("operator1").getBoundingClientRect().height;
+ var fontScalePercent = .5;
+ var minsizeEm = 8;
+ var beforeHeight = document.getElementById("before1").getBoundingClientRect().height;
+
+ assert_approx_equals(moStretchSize, baseSizePx * minsizeEm * fontScalePercent, epsilon, "baseSizePx * fontScalePercent * minsizeEm");
+
+ // This is really testing the same thing but do make sure minsize is
+ // applied i.e. the unconstrained target size is less than the actual
+ // stretch size.
+ assert_approx_equals(beforeHeight, moStretchSize / 2, epsilon);
+
+ }, `font-relative minsize refers to the core operator`);
+
+ test(function() {
+ var moStretchSize = document.getElementById("operator2").getBoundingClientRect().height;
+ var fontScalePercent = 2;
+ var maxsizeEm = 1;
+ var afterHeight = document.getElementById("after2").getBoundingClientRect().height;
+
+ assert_approx_equals(moStretchSize, baseSizePx * maxsizeEm * fontScalePercent, epsilon, "baseSizePx * fontScalePercent * maxsizeEm");
+
+ // This is really testing the same thing but do make sure maxsize is
+ // applied i.e. the unconstrained target size is more than the actual
+ // stretch size.
+ assert_approx_equals(afterHeight, 2 * moStretchSize, epsilon);
+
+ }, `font-relative maxsize refers to the core operator`);
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mrow>
+ <mspace id="before1" width="1em" height="1em" depth="1em" style="background: blue"/>
+ <mrow style="font-size: 50%;">
+ <mo id="operator1" lspace="1em" rspace="0em" minsize="8em">⥯</mo>
+ <mspace id="after1" width="1em" height=".5em" depth=".5em" style="background: green"/>
+ </mrow>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mrow style="font-size: 200%">
+ <mspace id="before2" width="1em" height=".5em" depth=".5em" style="background: green"/>
+ <mo id="operator2" lspace="0em" rspace="1em" maxsize="1em">⥯</mo>
+ </mrow>
+ <mspace id="after2" width="1em" height="2em" depth="2em" style="background: blue"/>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002-ref.html
new file mode 100644
index 0000000000..be7f5aa173
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002-ref.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>&lt;mo&gt; dynamic form</title>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math, math * {
+ font: 60px/1 Ahem;
+ }
+ mo {
+ color: blue;
+ }
+ </style>
+ </head>
+ <body>
+ <p>
+ <math>
+ <mn>1</mn><mo id="infix_attach_prefix" form="prefix">+</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="prefix_attach_infix" form="infix">+</mo><mn>3</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="infix_remove">+</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="prefix_remove">+</mo><mn>3</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="infix_set_to_prefix" form="prefix">+</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="prefix_set_to_infix" form="infix">+</mo><mn>3</mn>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002.html
new file mode 100644
index 0000000000..862fc36a20
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-002.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <meta charset="utf-8">
+ <title>&lt;mo&gt; dynamic form</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies that the form (and thus spacing) can be changed dynamically">
+ <link rel="match" href="mo-form-dynamic-002-ref.html">
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math, math * {
+ font: 60px/1 Ahem;
+ }
+ mo {
+ color: blue;
+ }
+ </style>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("infix_attach_prefix").setAttribute("form", "prefix");
+ document.getElementById("prefix_attach_infix").setAttribute("form", "infix");
+ document.getElementById("infix_remove").removeAttribute("form");
+ document.getElementById("prefix_remove").removeAttribute("form");
+ document.getElementById("infix_set_to_prefix").setAttribute("form", "prefix");
+ document.getElementById("prefix_set_to_infix").setAttribute("form", "infix");
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+ </head>
+ <body>
+ <!-- Prefix and infix forms of "+" have different default spacing in
+ the operator dictionary. -->
+ <p>
+ <math>
+ <mn>1</mn><mo id="infix_attach_prefix">+</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="prefix_attach_infix">+</mo><mn>3</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="infix_remove" form="prefix">+</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="prefix_remove" form="infix">+</mo><mn>3</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="infix_set_to_prefix" form="postfix">+</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="prefix_set_to_infix" form="postfix">+</mo><mn>3</mn>
+ </math>
+ </p>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-ref.html
new file mode 100644
index 0000000000..8f8d3da2c3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; dynamic form</title>
+ </head>
+ <body>
+
+ <p>The test should render the same as the static reference.</p>
+
+ _<math><merror><mi>x</mi><mo>+</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo>+</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo>+</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo>+</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo>+</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo>+</mo><mi>y</mi></mstyle></math>_
+
+ _<math><merror><mo>−</mo><mi>y</mi></merror></math>_
+ _<math><mo>−</mo><mi>y</mi></math>_
+ _<math><mphantom><mo>−</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mo>−</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mo>−</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mo>−</mo><mi>y</mi></mstyle></math>_
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic.html
new file mode 100644
index 0000000000..cec203f517
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-dynamic.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; dynamic form</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+ <meta name="assert" content="This test verifies that the form of the operators (and thus their spacing) is updated when you change the child list.">
+ <link rel="match" href="mo-form-dynamic-ref.html">
+
+ <script>
+ window.addEventListener("load", () => {
+
+ // force initial layout so we're sure what we're testing against
+ document.documentElement.getBoundingClientRect();
+
+ for (var i = 1; i <= 6; i++) {
+ var row = document.getElementById("row" + i);
+ var x = document.getElementById("x" + i);
+
+ x.parentNode.removeChild(x);
+
+ row.insertBefore(x, row.firstElementChild);
+ }
+
+ document.documentElement.classList.remove('reftest-wait');
+ })
+ </script>
+ </head>
+ <body>
+
+ <p>The test should render the same as the static reference.</p>
+
+ _<math><merror id="row1"><mo>+</mo><mi>y</mi></merror></math>_
+ _<math id="row2"><mo>+</mo><mi>y</mi></math>_
+ _<math><mphantom id="row3"><mo>+</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow id="row4"><mo>+</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt id="row5"><mo>+</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle id="row6"><mo>+</mo><mi>y</mi></mstyle></math>_
+
+ _<math><merror><mi id="x1">x</mi><mo>−</mo><mi>y</mi></merror></math>_
+ _<math><mi id="x2">x</mi><mo>−</mo><mi>y</mi></math>_
+ _<math><mphantom><mi id="x3">x</mi><mo>−</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi id="x4">x</mi><mo>−</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi id="x5">x</mi><mo>−</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi id="x6">x</mi><mo>−</mo><mi>y</mi></mstyle></math>_
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback-ref.html
new file mode 100644
index 0000000000..8d964eba45
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>form fallback</title>
+ </head>
+ <body>
+
+ <math>
+ <mo stretchy="true">(</mo> <mspace height="3em" depth="3em"/> <mo stretchy="true">)</mo>
+ <mo stretchy="true">(</mo> <mspace height="3em" depth="3em"/> <mo stretchy="true">)</mo>
+ </math>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback.html
new file mode 100644
index 0000000000..b49db9d9ff
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-fallback.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>form fallback</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verify fallback to postfix/prefix forms.">
+ <link rel="match" href="mo-form-fallback-ref.html">
+ </head>
+ <body>
+
+ <!-- The left (respectively right) parenthesis only has a prefix
+ (respectively postfix) form which gives its stretchiness.
+ In theory, the parenthesis in the middle of the <math> element are
+ considered infix operators and should not stretch. Let's check that we
+ fallback to the postfix/prefix forms and actually make them stretchy.
+ This is to handle bad MathML markup that misses explicit <mrow> tags.
+ -->
+
+ <math>
+ <mo>(</mo> <mspace height="3em" depth="3em"/> <mo>)</mo>
+ <mo>(</mo> <mspace height="3em" depth="3em"/> <mo>)</mo>
+ </math>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus-ref.html
new file mode 100644
index 0000000000..b46b307dbe
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus-ref.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>form plus/minus</title>
+ </head>
+ <body>
+
+ <!-- These operators should have form "prefix" -->
+
+ _<math><merror><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></merror></math>_
+ _<math><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></math>_
+ _<math><mphantom><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></mphantom></math>_
+ _<math><mrow><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></mrow></math>_
+ _<math><msqrt><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></msqrt></math>_
+ _<math><mstyle><mo form="prefix" lspace="0em" rspace="0em">−</mo><mi>x</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></merror></math>_
+ _<math><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></math>_
+ _<math><mphantom><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></mphantom></math>_
+ _<math><mrow><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></mrow></math>_
+ _<math><msqrt><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></msqrt></math>_
+ _<math><mstyle><mo form="prefix" lspace="0em" rspace="0em">+</mo><mi>x</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></merror></math>_
+ _<math><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></math>_
+ _<math><mphantom><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></mphantom></math>_
+ _<math><mrow><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></mrow></math>_
+ _<math><msqrt><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></msqrt></math>_
+ _<math><mstyle><mo form="prefix" lspace="0em" rspace="0em">±</mo><mi>x</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></merror></math>_
+ _<math><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></math>_
+ _<math><mphantom><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></mphantom></math>_
+ _<math><mrow><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></mrow></math>_
+ _<math><msqrt><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></msqrt></math>_
+ _<math><mstyle><mo form="prefix" lspace="0em" rspace="0em">∓</mo><mi>x</mi></mstyle></math>_
+
+ <br/>
+
+ <!-- These operators should have form "infix" -->
+
+ _<math><merror><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">−</mo><mi>y</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">+</mo><mi>y</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">±</mo><mi>y</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo form="infix" lspace="0.22222em" rspace="0.22222em">∓</mo><mi>y</mi></mstyle></math>_
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus.html
new file mode 100644
index 0000000000..eb7dbbce2a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-minus-plus.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>form plus/minus</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies behavior of form of plus/minus etc.">
+ <link rel="match" href="mo-form-minus-plus-ref.html">
+ </head>
+ <body>
+
+ <!-- These operators should have form "prefix" -->
+
+ _<math><merror><mo>−</mo><mi>x</mi></merror></math>_
+ _<math><mo>−</mo><mi>x</mi></math>_
+ _<math><mphantom><mo>−</mo><mi>x</mi></mphantom></math>_
+ _<math><mrow><mo>−</mo><mi>x</mi></mrow></math>_
+ _<math><msqrt><mo>−</mo><mi>x</mi></msqrt></math>_
+ _<math><mstyle><mo>−</mo><mi>x</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mo>+</mo><mi>x</mi></merror></math>_
+ _<math><mo>+</mo><mi>x</mi></math>_
+ _<math><mphantom><mo>+</mo><mi>x</mi></mphantom></math>_
+ _<math><mrow><mo>+</mo><mi>x</mi></mrow></math>_
+ _<math><msqrt><mo>+</mo><mi>x</mi></msqrt></math>_
+ _<math><mstyle><mo>+</mo><mi>x</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mo>±</mo><mi>x</mi></merror></math>_
+ _<math><mo>±</mo><mi>x</mi></math>_
+ _<math><mphantom><mo>±</mo><mi>x</mi></mphantom></math>_
+ _<math><mrow><mo>±</mo><mi>x</mi></mrow></math>_
+ _<math><msqrt><mo>±</mo><mi>x</mi></msqrt></math>_
+ _<math><mstyle><mo>±</mo><mi>x</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mo>∓</mo><mi>x</mi></merror></math>_
+ _<math><mo>∓</mo><mi>x</mi></math>_
+ _<math><mphantom><mo>∓</mo><mi>x</mi></mphantom></math>_
+ _<math><mrow><mo>∓</mo><mi>x</mi></mrow></math>_
+ _<math><msqrt><mo>∓</mo><mi>x</mi></msqrt></math>_
+ _<math><mstyle><mo>∓</mo><mi>x</mi></mstyle></math>_
+
+ <br/>
+
+ <!-- These operators should have form "infix" -->
+
+ _<math><merror><mi>x</mi><mo>−</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo>−</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo>−</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo>−</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo>−</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo>−</mo><mi>y</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mi>x</mi><mo>+</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo>+</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo>+</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo>+</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo>+</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo>+</mo><mi>y</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mi>x</mi><mo>±</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo>±</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo>±</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo>±</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo>±</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo>±</mo><mi>y</mi></mstyle></math>_
+
+ <br/>
+
+ _<math><merror><mi>x</mi><mo>∓</mo><mi>y</mi></merror></math>_
+ _<math><mi>x</mi><mo>∓</mo><mi>y</mi></math>_
+ _<math><mphantom><mi>x</mi><mo>∓</mo><mi>y</mi></mphantom></math>_
+ _<math><mrow><mi>x</mi><mo>∓</mo><mi>y</mi></mrow></math>_
+ _<math><msqrt><mi>x</mi><mo>∓</mo><mi>y</mi></msqrt></math>_
+ _<math><mstyle><mi>x</mi><mo>∓</mo><mi>y</mi></mstyle></math>_
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-ref.html
new file mode 100644
index 0000000000..b249fe43b5
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; form attribute</title>
+ </head>
+ <body>
+
+ <!-- This checks the effect of @form on a prefix operator. -->
+ _<math><mo lspace="0.27777em" rspace="0.27777em">∇</mo></math>_
+ _<math><mo lspace="0em" rspace="0em">∇</mo></math>_
+ _<math><mo lspace="0.27777em" rspace="0.27777em">∇</mo></math>_
+
+ <!-- This checks the effect of @form on an infix operator. -->
+ _<math><mo lspace="0.166666em" rspace="0.166666em">⋉</mo></math>_
+ _<math><mo lspace="0.27777em" rspace="0.27777em">⋉</mo></math>_
+ _<math><mo lspace="0.27777em" rspace="0.27777em">⋉</mo></math>_
+
+ <!-- This checks the effect of @form on a postfix operator. -->
+ _<math><mo lspace="0.27777em" rspace="0.27777em">”</mo></math>_
+ _<math><mo lspace="0.27777em" rspace="0.27777em">”</mo></math>_
+ _<math><mo lspace="0em" rspace="0em">”</mo></math>_
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form.html
new file mode 100644
index 0000000000..38cbd6bb4b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-form.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; form attribute</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies behavior of form attribute.">
+ <link rel="match" href="mo-form-ref.html">
+ </head>
+ <body>
+
+ <!-- This checks the effect of @form on a prefix operator. -->
+ _<math><mo form="infix">∇</mo></math>_
+ _<math><mo form="prefix">∇</mo></math>_
+ _<math><mo form="postfix">∇</mo></math>_
+
+ <!-- This checks the effect of @form on an infix operator. -->
+ _<math><mo form="infix">⋉</mo></math>_
+ _<math><mo form="prefix">⋉</mo></math>_
+ _<math><mo form="postfix">⋉</mo></math>_
+
+ <!-- This checks the effect of @form on a postfix operator. -->
+ _<math><mo form="infix">”</mo></math>_
+ _<math><mo form="prefix">”</mo></math>_
+ _<math><mo form="postfix">”</mo></math>_
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-2-ref.html
new file mode 100644
index 0000000000..c13f9b1739
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-2-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <math>
+ <mo>1</mo>
+ </math>
+ <p>
+ <math>
+ <mo>2</mo>
+ </math>
+ <p>
+ <math>
+ <mo>3</mo>
+ </math>
+ <p>
+ <math>
+ <mo>4</mo>
+ </math>
+ <p>
+ <table>
+ <tr>
+ <td style="border: 1px solid;">
+ <math>
+ <mo>x</mo>
+ </math>
+ </td>
+ </tr>
+ </table>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-2.html
new file mode 100644
index 0000000000..d5511a8ea8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-2.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <link rel="match" href="mo-invisibleoperators-2-ref.html">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="This test verifies proper invalidation after dynamically replacing the text of invisible operators.">
+ <meta name="assert" content="https://bugzilla.mozilla.org/show_bug.cgi?id=522393">
+ </head>
+ <body>
+ <math>
+ <mo id="mo1">&#x2061;<!-- FUNCTION APPLICATION --></mo>
+ </math>
+ <p>
+ <math>
+ <mo id="mo2">&#x2062;<!-- INVISIBLE TIMES --></mo>
+ </math>
+ <p>
+ <math>
+ <mo id="mo3">&#x2063;<!-- INVISIBLE SEPARATOR --></mo>
+ </math>
+ <p>
+ <math>
+ <mo id="mo4">&#x2064;<!-- INVISIBLE PLUS --></mo>
+ </math>
+ <p>
+ <!-- Test preferred width after dynamic change-->
+ <table>
+ <tr>
+ <td style="border: 1px solid;">
+ <math>
+ <mo id="mo5">&ApplyFunction;</mo>
+ </math>
+ </td>
+ </tr>
+ </table>
+ <script type="text/javascript">
+ function doTest() {
+ document.getElementById('mo1').firstChild.data = '1';
+ document.getElementById('mo2').firstChild.data = '2';
+ document.getElementById('mo3').firstChild.data = '3';
+ document.getElementById('mo4').firstChild.data = '4';
+ document.getElementById('mo5').firstChild.data = 'x';
+ document.documentElement.removeAttribute("class");
+ }
+ window.addEventListener("TestRendered", doTest);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-ref.html
new file mode 100644
index 0000000000..2b7d9c6add
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+ <math>
+ <mrow>
+ <mn>1</mn>
+ <mn>2</mn>
+ <mn>3</mn>
+ <mn>4</mn>
+ <mn>5</mn>
+ <mspace height="2em" width="0.1em"></mspace>
+ </mrow>
+ </math>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators.html
new file mode 100644
index 0000000000..d027b6491f
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-invisibleoperators.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <link rel="match" href="mo-invisibleoperators-ref.html">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="This test verifies that invisible operators rendered with the default fonts do not add spacing, foreground or background.">
+ <meta name="assert" content="https://bugzilla.mozilla.org/show_bug.cgi?id=969867">
+ <meta name="assert" content="https://bugzilla.mozilla.org/show_bug.cgi?id=522393">
+ </head>
+ <math>
+ <mrow>
+ <mn>1</mn>
+ <mo>&#x2061;<!-- FUNCTION APPLICATION --></mo>
+ <mn>2</mn>
+ <mo>&#x2062;<!-- INVISIBLE TIMES --></mo>
+ <mn>3</mn>
+ <mo>&#x2063;<!-- INVISIBLE SEPARATOR --></mo>
+ <mn>4</mn>
+ <mo>&#x2064;<!-- INVISIBLE PLUS --></mo>
+ <mn>5</mn>
+ <!-- Hack. The invisible operators may not belong to the same font as
+ the numbers, so they may have different heights. The mspace
+ compensates for this by ensuring the height of the mrow does not
+ depend on character height -->
+ <mspace height="2em" width="0.1em"></mspace>
+ </mrow>
+ </math>
+ <p>
+ <!-- Should be invisible -->
+ <math>
+ <mo style="background: red; color: blue;">&ApplyFunction;</mo>
+ </math>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2-ref.html
new file mode 100644
index 0000000000..4ffe6cbc23
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2-ref.html
@@ -0,0 +1,363 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>mo-lspace-rspace-2 (reference)</title>
+ <style type="text/css">
+ mo,td {
+ background-color: red;
+ }
+ msub, mfrac, msup, msubsup, mmultiscripts,
+ mover, munder, munderover, mpadded, merror
+ {
+ background-color: blue
+ }
+ math[display]
+ {
+ background-color: blue
+ }
+ </style>
+ </head>
+ <body>
+
+ <p>
+ <math>
+ <mrow>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mrow>
+ </math>
+ <math>
+ <mfrac>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mfrac>
+ </math>
+ <math>
+ <msqrt>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </msqrt>
+ </math>
+ <math>
+ <mroot>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mroot>
+ </math>
+ <math>
+ <mstyle>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mstyle>
+ </math>
+ </p>
+
+ <p>
+ <table>
+ <tr>
+ <td>
+ <math>
+ <mphantom>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mphantom>
+ </math>
+ </td>
+ </tr>
+ </table>
+ </p>
+
+ <p>
+ <math>
+ <menclose notation="circle">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </menclose>
+ </math>
+ <math>
+ <msub>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </msub>
+ </math>
+ <math>
+ <msup>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </msup>
+ </math>
+ <math>
+ <msubsup>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </msubsup>
+ </math>
+ <math>
+ <munder>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </munder>
+ </math>
+ <math>
+ <mover>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mover>
+ </math>
+ <math>
+ <munderover>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </munderover>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <mmultiscripts>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mprescripts/>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mmultiscripts>
+ </math>
+ <math>
+ <mtable>
+ <mtr>
+ <mtd>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mtd>
+ </mtr>
+ </mtable>
+ </math>
+ <math>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </math>
+ <math>
+ <msub>
+ <mrow>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mrow>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </msub>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <msub>
+ <msub>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </msub>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </msub>
+ </math>
+ <math>
+ <munder>
+ <munder>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </munder>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </munder>
+ </math>
+ <math>
+ <mfrac>
+ <mfrac>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mfrac>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mfrac>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <menclose notation="circle">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </menclose>
+ <menclose notation="circle">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </menclose>
+ <mroot>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mroot>
+ </math>
+ <math>
+ <mpadded height="+1em">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mpadded>
+ </math>
+ <math>
+ <merror>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </merror>
+ </math>
+ </p>
+
+ <math display="block">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </math>
+
+ <p>
+ <math>
+ <mrow>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mrow>
+ <mfrac>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </mfrac>
+ <msqrt>
+ <mo lspace="0" rspace="0">*</mo>
+ </msqrt>
+ <mstyle>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mstyle>
+ </math>
+ </p>
+
+ <p>
+ <table>
+ <tr>
+ <td>
+ <math>
+ <mphantom>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mphantom>
+ </math>
+ </td>
+ </tr>
+ </table>
+ </p>
+
+ <p>
+ <math>
+ <menclose notation="circle">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </menclose>
+ <msub>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </msub>
+ <msup>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </msup>
+ <msubsup>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </msubsup>
+ <munder>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </munder>
+ <mover>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </mover>
+ <munderover>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </munderover>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <mmultiscripts>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ <mprescripts/>
+ <mo lspace="0" rspace="0">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </mmultiscripts>
+ <mtable>
+ <mtr>
+ <mtd>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mtd>
+ </mtr>
+ </mtable>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <msub>
+ <mrow>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mrow>
+ <mo lspace="0" rspace="0">*</mo>
+ </msub>
+ <msub>
+ <mrow>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mrow>
+ <mo lspace="0" rspace="0">*</mo>
+ </msub>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <msub>
+ <msub>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </msub>
+ <mo lspace="0" rspace="0">*</mo>
+ </msub>
+ <munder>
+ <munder>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </munder>
+ <mo lspace="0" rspace="0">*</mo>
+ </munder>
+ <mfrac>
+ <mfrac>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0" rspace="0">*</mo>
+ </mfrac>
+ <mo lspace="0" rspace="0">*</mo>
+ </mfrac>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <mrow>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mpadded height="+1em">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mpadded>
+ </mrow>
+ </math>
+ <math>
+ <mpadded height="+1em">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </mpadded>
+ </math>
+ <math>
+ <merror>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </merror>
+ </math>
+ </p>
+
+ <math display="block">
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </math>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2.html
new file mode 100644
index 0000000000..d54f45c21d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-2.html
@@ -0,0 +1,363 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>mo-lspace-rspace-2</title>
+ <link rel="match" href="mo-lspace-rspace-2-ref.html">
+ <style type="text/css">
+ mo,td {
+ background-color: red;
+ }
+ msub, mfrac, msup, msubsup, mmultiscripts,
+ mover, munder, munderover, mpadded, merror
+ {
+ background-color: blue
+ }
+ math[display]
+ {
+ background-color: blue
+ }
+ </style>
+ </head>
+ <body>
+
+ <p>
+ <math>
+ <mrow>
+ <mo>*</mo>
+ </mrow>
+ </math>
+ <math>
+ <mfrac>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mfrac>
+ </math>
+ <math>
+ <msqrt>
+ <mo>*</mo>
+ </msqrt>
+ </math>
+ <math>
+ <mroot>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mroot>
+ </math>
+ <math>
+ <mstyle>
+ <mo>*</mo>
+ </mstyle>
+ </math>
+ </p>
+
+ <p>
+ <table>
+ <tr>
+ <td>
+ <math>
+ <mphantom>
+ <mo>*</mo>
+ </mphantom>
+ </math>
+ </td>
+ </tr>
+ </table>
+ </p>
+
+ <p>
+ <math>
+ <menclose notation="circle">
+ <mo>*</mo>
+ </menclose>
+ </math>
+ <math>
+ <msub>
+ <mo>*</mo>
+ <mo>*</mo>
+ </msub>
+ </math>
+ <math>
+ <msup>
+ <mo>*</mo>
+ <mo>*</mo>
+ </msup>
+ </math>
+ <math>
+ <msubsup>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mo>*</mo>
+ </msubsup>
+ </math>
+ <math>
+ <munder>
+ <mo>*</mo>
+ <mo>*</mo>
+ </munder>
+ </math>
+ <math>
+ <mover>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mover>
+ </math>
+ <math>
+ <munderover>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mo>*</mo>
+ </munderover>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <mmultiscripts>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mprescripts/>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mmultiscripts>
+ </math>
+ <math>
+ <mtable>
+ <mtr>
+ <mtd>
+ <mo>*</mo>
+ </mtd>
+ </mtr>
+ </mtable>
+ </math>
+ <math>
+ <mo>*</mo>
+ </math>
+ <math>
+ <msub>
+ <mrow>
+ <mo>*</mo>
+ </mrow>
+ <mo>*</mo>
+ </msub>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <msub>
+ <msub>
+ <mo>*</mo>
+ <mo>*</mo>
+ </msub>
+ <mo>*</mo>
+ </msub>
+ </math>
+ <math>
+ <munder>
+ <munder>
+ <mo>*</mo>
+ <mo>*</mo>
+ </munder>
+ <mo>*</mo>
+ </munder>
+ </math>
+ <math>
+ <mfrac>
+ <mfrac>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mfrac>
+ <mo>*</mo>
+ </mfrac>
+ </math>
+ </p>
+ <p>
+ <math>
+ <menclose notation="circle">
+ <mo>*</mo>
+ </menclose>
+ <menclose notation="circle">
+ <mo>*</mo>
+ </menclose>
+ <mroot>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mroot>
+ </math>
+ <math>
+ <mpadded height="+1em">
+ <mo>*</mo>
+ </mpadded>
+ </math>
+ <math>
+ <merror>
+ <mo>*</mo>
+ </merror>
+ </math>
+ </p>
+
+ <math display="block">
+ <mo>*</mo>
+ </math>
+
+ <p>
+ <math>
+ <mrow>
+ <mo>*</mo>
+ </mrow>
+ <mfrac>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mfrac>
+ <msqrt>
+ <mo>*</mo>
+ </msqrt>
+ <mstyle>
+ <mo>*</mo>
+ </mstyle>
+ </math>
+ </p>
+
+ <p>
+ <table>
+ <tr>
+ <td>
+ <math>
+ <mphantom>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mphantom>
+ </math>
+ </td>
+ </tr>
+ </table>
+ </p>
+
+ <p>
+ <math>
+ <menclose notation="circle">
+ <mo>*</mo>
+ <mo>*</mo>
+ </menclose>
+ <msub>
+ <mo>*</mo>
+ <mo>*</mo>
+ </msub>
+ <msup>
+ <mo>*</mo>
+ <mo>*</mo>
+ </msup>
+ <msubsup>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mo>*</mo>
+ </msubsup>
+ <munder>
+ <mo>*</mo>
+ <mo>*</mo>
+ </munder>
+ <mover>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mover>
+ <munderover>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mo>*</mo>
+ </munderover>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <mmultiscripts>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mprescripts/>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mmultiscripts>
+ <mtable>
+ <mtr>
+ <mtd>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mtd>
+ </mtr>
+ </mtable>
+ <mo>*</mo>
+ <msub>
+ <mrow>
+ <mo>*</mo>
+ </mrow>
+ <mo>*</mo>
+ </msub>
+ <msub>
+ <mrow>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mrow>
+ <mo>*</mo>
+ </msub>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <msub>
+ <msub>
+ <mo>*</mo>
+ <mo>*</mo>
+ </msub>
+ <mo>*</mo>
+ </msub>
+ <munder>
+ <munder>
+ <mo>*</mo>
+ <mo>*</mo>
+ </munder>
+ <mo>*</mo>
+ </munder>
+ <mfrac>
+ <mfrac>
+ <mo>*</mo>
+ <mo>*</mo>
+ </mfrac>
+ <mo>*</mo>
+ </mfrac>
+ </math>
+ </p>
+
+ <p>
+ <math>
+ <mrow>
+ <mo>*</mo>
+ <mo>*</mo>
+ <mpadded height="+1em">
+ <mo>*</mo>
+ </mpadded>
+ </mrow>
+ </math>
+ <math>
+ <mpadded height="+1em">
+ <mo>*</mo>
+ <mo>*</mo>
+ </mpadded>
+ </math>
+ <math>
+ <merror>
+ <mo>*</mo>
+ <mo>*</mo>
+ </merror>
+ </math>
+ </p>
+
+ <math display="block">
+ <mo>*</mo>
+ <mo>*</mo>
+ </math>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3-ref.html
new file mode 100644
index 0000000000..1830e11474
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3-ref.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>mo-lspace-rspace-3 (reference)</title>
+ </head>
+ <body>
+ <p>
+ <math>
+ <mo id="mo1" lspace="3em" rspace="0.16666666666666666em">*</mo>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="mo2" lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="mo3" lspace="3em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="mo4" lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo lspace="0.16666666666666666em" rspace="0.16666666666666666em">*</mo>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3.html
new file mode 100644
index 0000000000..4574ff39c9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-3.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <title>mo-lspace-rspace-3</title>
+ <link rel="match" href="mo-lspace-rspace-3-ref.html">
+ </head>
+ <body>
+ <p>
+ <math>
+ <mo id="mo1">*</mo>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="mo2" lspace="3em">*</mo>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="mo3">*</mo>
+ <mo>*</mo>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mo id="mo4" lspace="3em">*</mo>
+ <mo >*</mo>
+ </math>
+ </p>
+ <p>
+ <math id="math1">
+ <mo>*</mo>
+ </math>
+ </p>
+ <p>
+ <math id="math2">
+ <mo>*</mo>
+ <mo id="mo5">*</mo>
+ </math>
+ </p>
+ <script type="text/javascript">
+ function doTest() {
+ // Add and remove lspace
+ document.getElementById("mo1").setAttribute("lspace", "3em");
+ document.getElementById("mo2").removeAttribute("lspace");
+ // and again but with an inferred mrow
+ document.getElementById("mo3").setAttribute("lspace", "3em");
+ document.getElementById("mo4").removeAttribute("lspace");
+
+ // Change to/from inferred mrow
+ var mo1 = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mo");
+ mo1.innerHTML = "*";
+ document.getElementById("math1").appendChild(mo1);
+ document.getElementById("math2").removeChild(document.getElementById("mo5"));
+
+ document.documentElement.removeAttribute("class");
+ }
+ window.addEventListener("load", doTest);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4-ref.html
new file mode 100644
index 0000000000..ab4c08dde1
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>mo-lspace-rspace-4 (reference)</title>
+ </head>
+ <body>
+ <p>
+ <math>
+ <mtext>_</mtext>
+ <mrow>
+ <mfrac>
+ <mo lspace="1em" rspace="2em">_</mo>
+ <mtext>_</mtext>
+ </mfrac>
+ </mrow>
+ <mtext>_</mtext>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4.html
new file mode 100644
index 0000000000..4798454868
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-4.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>mo-lspace-rspace-4</title>
+ <link rel="match" href="mo-lspace-rspace-4-ref.html">
+ </head>
+ <body>
+ <p>
+ <math>
+ <mtext>_</mtext>
+ <mfrac>
+ <mo lspace="1em" rspace="2em">_</mo>
+ <mtext>_</mtext>
+ </mfrac>
+ <mtext>_</mtext>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic-ref.html
new file mode 100644
index 0000000000..85cabd287d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic-ref.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>&lt;mo&gt; dynamic lspace rspace (reference)</title>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math, math * {
+ font: 60px/1 Ahem;
+ }
+ mo {
+ color: blue;
+ }
+ </style>
+ </head>
+ <body>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_attach_lspace" lspace="2em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_attach_rspace" rspace="3em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_modify_lspace" lspace="4em" rspace="1em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_modify_rspace" lspace="1em" rspace="5em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_remove_lspace" rspace="1em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_remove_rspace" lspace="1em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic.html
new file mode 100644
index 0000000000..70098bebf9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-dynamic.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <meta charset="utf-8">
+ <title>&lt;mo&gt; dynamic lspace rspace</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies dynamic setting of lspace and rspace">
+ <link rel="match" href="mo-lspace-rspace-dynamic-ref.html">
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math, math * {
+ font: 60px/1 Ahem;
+ }
+ mo {
+ color: blue;
+ }
+ </style>
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById("mo_attach_lspace").setAttribute("lspace", "2em");
+ document.getElementById("mo_attach_rspace").setAttribute("rspace", "3em");
+ document.getElementById("mo_modify_lspace").setAttribute("lspace", "4em");
+ document.getElementById("mo_modify_rspace").setAttribute("rspace", "5em");
+ document.getElementById("mo_remove_lspace").removeAttribute("lspace");
+ document.getElementById("mo_remove_rspace").removeAttribute("rspace");
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ </script>
+ </head>
+ <body>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_attach_lspace">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_attach_rspace">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_modify_lspace" lspace="1em" rspace="1em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_modify_rspace" lspace="1em" rspace="1em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_remove_lspace" lspace="1em" rspace="1em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mn>1</mn><mo id="mo_remove_rspace" lspace="1em" rspace="1em">X</mo><mn>2</mn>
+ </math>
+ </p>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-ref.html
new file mode 100644
index 0000000000..46be5079e6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace-ref.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>mo-lspace-rspace (reference)</title>
+ </head>
+
+ <body>
+
+ <p>
+ <!-- not in the operator dictionary -->
+ <math>
+ <mtext>_</mtext>
+ <mspace width="0.2777777777777778em" height="0" depth="0"></mspace>
+ <mtext>MO</mtext>
+ <mspace width="0.2777777777777778em" height="0" depth="0"></mspace>
+ <mtext>_</mtext>
+ </math>
+ </p>
+
+ <p>
+ <!-- operator.\u223F.infix = lspace:3 rspace:3 # sine wave -->
+ <math>
+ <mtext>_</mtext>
+ <mspace width="0.16666666666666666em" height="0" depth="0"></mspace>
+ <mtext>&#x0223F;</mtext>
+ <mspace width="0.16666666666666666em" height="0" depth="0"></mspace>
+ <mtext>_</mtext>
+ </math>
+ </p>
+
+ <p>
+ <!-- Invisible operator -->
+ <math>
+ <mtext>_</mtext>
+ <mtext>&#x02061;</mtext>
+ <mtext>_</mtext>
+ </math>
+ </p>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace.html
new file mode 100644
index 0000000000..5774e4ced0
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-lspace-rspace.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>mo-lspace-rspace</title>
+ <link rel="match" href="mo-lspace-rspace-ref.html">
+ </head>
+
+ <body>
+
+ <p>
+ <!-- not in the operator dictionary -->
+ <math>
+ <mtext>_</mtext>
+ <mo>MO</mo>
+ <mtext>_</mtext>
+ </math>
+ </p>
+
+ <p>
+ <!-- operator.\u223F.infix = lspace:3 rspace:3 # sine wave -->
+ <math>
+ <mtext>_</mtext>
+ <mo>&#x0223F;</mo>
+ <mtext>_</mtext>
+ </math>
+ </p>
+
+ <p>
+ <!-- Invisible operator -->
+ <math>
+ <mtext>_</mtext>
+ <mo>&#x02061;</mo>
+ <mtext>_</mtext>
+ </math>
+ </p>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-minsize-maxsize-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-minsize-maxsize-001.html
new file mode 100644
index 0000000000..3e7e5c9bcc
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-minsize-maxsize-001.html
@@ -0,0 +1,143 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Edge cases for minsize and maxsize</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<meta name="assert" content="Verify edge cases for minsize and maxsize .">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ math {
+ font: 25px/1 Ahem;
+ }
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff"); /* AxisHeight == 0 */
+ }
+ mo {
+ font-family: operators;
+ }
+</style>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+ var epsilon = 1;
+ var emToPx = 25;
+ test(function() {
+ assert_approx_equals(document.getElementById("negative_minsize").getBoundingClientRect().height, 5 * emToPx, epsilon);
+ }, `minsize < 0 is treated as 0`);
+
+ test(function() {
+ assert_approx_equals(document.getElementById("maxsize_less_than_minsize").getBoundingClientRect().height, 7 * emToPx, epsilon);
+ }, `maxsize < minsize is treated as maxsize = minsize`);
+
+ test(function() {
+ assert_less_than(document.getElementById("minsize_less_than_negative_maxsize").getBoundingClientRect().height, 2 * emToPx);
+ }, `minsize < maxsize < 0 is treated as maxsize = minsize = 0`);
+
+ test(function() {
+ assert_approx_equals(document.getElementById("zero_target_size_with_minsize").getBoundingClientRect().height, 2 * emToPx, epsilon);
+ assert_approx_equals(document.getElementById("zero_target_size_with_minsize").getBoundingClientRect().bottom - document.getElementById("zero_target_size_with_minsize_math_axis").getBoundingClientRect().bottom, emToPx, epsilon);
+ }, `target size = 0 is treated as Tascent = Tdescent = minsize/2`);
+
+ test(function() {
+ assert_approx_equals(document.getElementById("percent_minsize").getBoundingClientRect().height, 12 * emToPx, epsilon, "percent minsize");
+ assert_approx_equals(document.getElementById("percent_maxsize").getBoundingClientRect().height, 3 * emToPx, epsilon, "percent maxsize");
+ }, `minsize/maxsize percentages are relative to the target size`);
+
+ test(function() {
+ // These tests are not really strong:
+ // - The smallest glyph for this stretchy operator is a 1em square so
+ // it can't go under a minsize of 1em anyway.
+ // - The maxsize is theorically infinite, this only tests that a large
+ // value of 300em is clamped.
+ assert_approx_equals(document.getElementById("default_minsize").getBoundingClientRect().height, 1 * emToPx, epsilon, "default minsize is 1em");
+ assert_approx_equals(document.getElementById("default_maxsize").getBoundingClientRect().height, 300 * emToPx, epsilon, "default maxsize is infinity");
+ }, `default minsize/maxsize percentages`);
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="5em" style="background: blue"/>
+ <mo id="negative_minsize" minsize="-10em" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="5em" style="background: blue"/>
+ <mo id="maxsize_less_than_minsize" minsize="7em" maxsize="2em" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="5em" style="background: blue"/>
+ <mo id="minsize_less_than_negative_maxsize" minsize="-2em" maxsize="-1em" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace id="zero_target_size_with_minsize_math_axis" width="1em" height="0em" style="background: blue"/>
+ <mo id="zero_target_size_with_minsize" minsize="2em" stretchy="true" symmetric="true">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="6em" style="background: blue"/>
+ <mo id="percent_minsize" minsize="200%" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="6em" style="background: blue"/>
+ <mo id="percent_maxsize" maxsize="50%" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height=".5em" style="background: blue"/>
+ <mo id="default_minsize" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="300em" style="background: blue"/>
+ <mo id="default_maxsize" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator-ref.html
new file mode 100644
index 0000000000..cca8b9b697
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator-ref.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; movablelimits and embellished operator (reference)</title>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math { font: 25px/1 Ahem; }
+ </style>
+</head>
+<body>
+ <math>
+ <msub>
+ <mrow><mtext>A</mtext></mrow>
+ <mn>2</mn>
+ </msub>
+ <munder>
+ <mrow><mtext>A</mtext></mrow>
+ <mn>2</mn>
+ </munder>
+ </math>
+ <math displaystyle="true">
+ <munder>
+ <mrow><mtext>A</mtext></mrow>
+ <mn>2</mn>
+ </munder>
+ <munder>
+ <mrow><mtext>A</mtext></mrow>
+ <mn>2</mn>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator.html
new file mode 100644
index 0000000000..2bdfa15bc6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-and-embellished-operator.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; movablelimits and embellished operator (reference)</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#embellished-operators">
+ <meta name="assert" content="Verifies effect of movablelimits on the core operator of an embellished operator, in both displaystyle modes.">
+ <link rel="match" href="mo-movablelimits-and-embellished-operator-ref.html">
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math { font: 25px/1 Ahem; }
+ </style>
+ </head>
+ <body>
+ <math>
+ <munder>
+ <mrow><mo lspace="0px" rspace="0px" movablelimits="true">A</mo></mrow>
+ <mn>2</mn>
+ </munder>
+ <munder>
+ <mrow><mo lspace="0px" rspace="0px" movablelimits="false">A</mo></mrow>
+ <mn>2</mn>
+ </munder>
+ </math>
+ <math displaystyle="true">
+ <munder>
+ <mrow><mo lspace="0px" rspace="0px" movablelimits="true">A</mo></mrow>
+ <mn>2</mn>
+ </munder>
+ <munder>
+ <mrow><mo lspace="0px" rspace="0px" movablelimits="false">A</mo></mrow>
+ <mn>2</mn>
+ </munder>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default-ref.html
new file mode 100644
index 0000000000..8328637397
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>mo movablelimits default value</title>
+ <meta charset="utf-8"/></head>
+<body>
+ <math>
+ <munder>
+ <mo movablelimits="true">∑</mo>
+ <mi>x</mi>
+ </munder>
+ <munder>
+ <mo movablelimits="false">∫</mo>
+ <mi>x</mi>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default.html
new file mode 100644
index 0000000000..4d6ee00d82
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-default.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; movablelimits default value</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies default value of movablelimits for some operators.">
+ <link rel="match" href="mo-movablelimits-default-ref.html">
+ </head>
+ <body>
+ <math>
+ <munder>
+ <mo>∑</mo> <!-- This has movablelimits="true" in the operator dictionary -->
+ <mi>x</mi>
+ </munder>
+ <munder>
+ <mo>∫</mo> <!-- This has movablelimits="false" in the operator dictionary -->
+ <mi>x</mi>
+ </munder>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic-ref.html
new file mode 100644
index 0000000000..cd1aafb4b7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Test dynamically removing movablelimits attribute</title>
+ </head>
+ <body>
+ <math>
+ <munder>
+ <mo>∑</mo>
+ <mi>x</mi>
+ </munder>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html
new file mode 100644
index 0000000000..cf6d0ffa5b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-dynamic.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <meta charset="utf-8"/>
+ <title>Test dynamically removing movablelimits attribute</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#dom-and-javascript">
+ <meta name="assert" content="Verifies dynamically removing movablelimits.">
+ <link rel="match" href="mo-movablelimits-dynamic-ref.html">
+ <script>
+ window.addEventListener("load", () => {
+ document.getElementById('a').removeAttribute('movablelimits');
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ </script>
+ </head>
+ <body>
+ <math>
+ <munder>
+ <mo id="a" movablelimits="false">∑</mo>
+ <mi>x</mi>
+ </munder>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow-ref.html
new file mode 100644
index 0000000000..3efeaa0dfe
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; movablelimits</title>
+ <style>
+ math, math * {
+ font: 25px/1 Ahem;
+ }
+ </style>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ </head>
+ <body>
+ <math>
+ <msub>
+ <mo lspace="0px" rspace="0px">+</mo>
+ <mn>1</mn>
+ </msub>
+ <msup>
+ <mo lspace="0px" rspace="0px">+</mo>
+ <mn>1</mn>
+ </msup>
+ <msubsup>
+ <mo lspace="0px" rspace="0px">+</mo>
+ <mn>1</mn>
+ <mn>2</mn>
+ </msubsup>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow.html
new file mode 100644
index 0000000000..d1a2422c98
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-from-in-flow.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; movablelimits</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verify movablelimits is read from the first in-flow child.">
+ <style>
+ math, math * {
+ font: 25px/1 Ahem;
+ }
+ .oof1 {
+ position: absolute;
+ }
+ .oof2 {
+ position: fixed;
+ }
+ .nobox {
+ display: none;
+ }
+ </style>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <link rel="match" href="mo-movablelimits-from-in-flow-ref.html">
+ </head>
+ <body>
+ <math>
+ <munder>
+ <mo class="oof1" movablelimits="false"></mo>
+ <mo class="oof2" movablelimits="false"></mo>
+ <mo class="nobox" movablelimits="false"></mo>
+ <mo lspace="0px" rspace="0px" movablelimits="true">+</mo>
+ <mn>1</mn>
+ </munder>
+ <mover>
+ <mo class="oof1" movablelimits="false"></mo>
+ <mo class="oof2" movablelimits="false"></mo>
+ <mo class="nobox" movablelimits="false"></mo>
+ <mo lspace="0px" rspace="0px" movablelimits="true">+</mo>
+ <mn>1</mn>
+ </mover>
+ <munderover>
+ <mo class="oof1" movablelimits="false"></mo>
+ <mo class="oof2" movablelimits="false"></mo>
+ <mo class="nobox" movablelimits="false"></mo>
+ <mo lspace="0px" rspace="0px" movablelimits="true">+</mo>
+ <mn>1</mn>
+ <mn>2</mn>
+ </munderover>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-ref.html
new file mode 100644
index 0000000000..cb868d2400
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; movablelimits</title>
+</head>
+<body>
+ <math>
+ <msub>
+ <mtext>A</mtext>
+ <mi>B</mi>
+ </msub>
+ <munder>
+ <mtext>A</mtext>
+ <mi>B</mi>
+ </munder>
+ </math>
+ <math displaystyle="true">
+ <munder>
+ <mtext>A</mtext>
+ <mi>B</mi>
+ </munder>
+ <munder>
+ <mtext>A</mtext>
+ <mi>B</mi>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits.html
new file mode 100644
index 0000000000..e7aa17380b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-movablelimits.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>&lt;mo&gt; movablelimits</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies effect of movablelimits on mo in both displaystyle modes.">
+ <link rel="match" href="mo-movablelimits-ref.html">
+ </head>
+ <body>
+ <math>
+ <munder>
+ <mo lspace="0px" rspace="0px" movablelimits="true">A</mo>
+ <mi>B</mi>
+ </munder>
+ <munder>
+ <mo lspace="0px" rspace="0px" movablelimits="false">A</mo>
+ <mi>B</mi>
+ </munder>
+ </math>
+ <math displaystyle="true">
+ <munder>
+ <mo lspace="0px" rspace="0px" movablelimits="true">A</mo>
+ <mi>B</mi>
+ </munder>
+ <munder>
+ <mo lspace="0px" rspace="0px" movablelimits="false">A</mo>
+ <mi>B</mi>
+ </munder>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace-ref.html
new file mode 100644
index 0000000000..3938db19a7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace-ref.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>lspace/rspace default value for unknown operators (reference)</title>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math {
+ font: 100px/1 Ahem;
+ }
+ mo {
+ color: blue;
+ }
+ </style>
+ </head>
+ <body>
+ <p>This test passes if on each row, the space around the blue rectangle
+ is 0.2777777777777778em.</p>
+ <p>
+ <math>
+ <mrow>
+ <mn>p</mn>
+ <mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">X</mo> <!-- Single character -->
+ <mn>p</mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mn>p</mn>
+ <mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">XX</mo> <!-- Multiple characters -->
+ <mn>p</mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mn>p</mn>
+ <mo form="infix" lspace="0.2777777777777778em" rspace="0.2777777777777778em">X</mo> <!-- Explicit form -->
+ <mn>p</mn>
+ </mrow>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace.html
new file mode 100644
index 0000000000..e6b5b172c3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-lspace-rspace.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>lspace/rspace default value for unknown operators</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies that the default lspace/rspace are 0.2777777777777778em for entries that are not in the operator dictionary.">
+ <link rel="match" href="mo-not-in-dictionary-lspace-rspace-ref.html">
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math {
+ font: 100px/1 Ahem;
+ }
+ mo {
+ color: blue;
+ }
+ </style>
+ </head>
+ <body>
+ <p>This test passes if on each row, the space around the blue rectangle
+ is 0.2777777777777778em.</p>
+ <p>
+ <math>
+ <mrow>
+ <mn>p</mn>
+ <mo>X</mo> <!-- Single character -->
+ <mn>p</mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mn>p</mn>
+ <mo>XX</mo> <!-- Multiple characters -->
+ <mn>p</mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mn>p</mn>
+ <mo form="infix">X</mo> <!-- Explicit form -->
+ <mn>p</mn>
+ </mrow>
+ </math>
+ </p>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits-ref.html
new file mode 100644
index 0000000000..e7ffc78994
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits-ref.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>movablelimits default value for unknown operators (reference)</title>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math {
+ font: 50px/1 Ahem;
+ }
+ mo {
+ color: blue;
+ }
+ </style>
+ </head>
+ <body>
+ <p>This test passes if the black scripts are attached above and below
+ the corresponding blue base.</p>
+ <p>
+ <math>
+ <munderover>
+ <mo movablelimits="false">X</mo> <!-- Single character -->
+ <mn>X</mn>
+ <mn>X</mn>
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover>
+ <mo movablelimits="false">XX</mo> <!-- Multiple characters -->
+ <mn>X</mn>
+ <mn>X</mn>
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover>
+ <mo movablelimits="false" form="infix">X</mo> <!-- Explicit form -->
+ <mn>X</mn>
+ <mn>X</mn>
+ </munderover>
+ </math>
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits.html
new file mode 100644
index 0000000000..8a96e31953
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-not-in-dictionary-movablelimits.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>movablelimits default value for unknown operators</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies that the default movablelimits is false for entries that are not in the operator dictionary.">
+ <link rel="match" href="mo-not-in-dictionary-movablelimits-ref.html">
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math {
+ font: 50px/1 Ahem;
+ }
+ mo {
+ color: blue;
+ }
+ </style>
+ </head>
+ <body>
+ <p>This test passes if the black scripts are attached above and below
+ the corresponding blue base.</p>
+ <p>
+ <math>
+ <munderover>
+ <mo>X</mo> <!-- Single character -->
+ <mn>X</mn>
+ <mn>X</mn>
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover>
+ <mo>XX</mo> <!-- Multiple characters -->
+ <mn>X</mn>
+ <mn>X</mn>
+ </munderover>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munderover>
+ <mo form="infix">X</mo> <!-- Explicit form -->
+ <mn>X</mn>
+ <mn>X</mn>
+ </munderover>
+ </math>
+ </p>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_movablelimits");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace-ref.html
new file mode 100644
index 0000000000..da0b79ff9a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace-ref.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>&lt;mo&gt; paint lspace rspace</title>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <h1>LTR case</h1>
+
+ <p>The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the left,
+ and a trailing space of 200px, which is as wide as the black block to the right.</p>
+
+ <math>
+ <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace>
+ <mspace width="100px"></mspace>
+ <mo lspace="0px" rspace="0px">→</mo>
+ <mspace width="200px"></mspace>
+ <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <p>The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the left,
+ and a trailing space of 150px, which is as wide as the black block to the right.</p>
+
+ <math>
+ <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace>
+ <mspace width="150px"></mspace>
+ <mo lspace="0px" rspace="0px">→</mo>
+ <mspace width="150px"></mspace>
+ <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <p>The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the left,
+ and a trailing space of 100px, which is as wide as the black block to the right.</p>
+
+ <math>
+ <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace>
+ <mspace width="200px"></mspace>
+ <mo lspace="0px" rspace="0px">→</mo>
+ <mspace width="100px"></mspace>
+ <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <h1>RTL case</h1>
+
+ <p>The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the right,
+ and a trailing space of 200px, which is as wide as the black block to the left.</p>
+
+ <math dir="rtl">
+ <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace>
+ <mspace width="100px"></mspace>
+ <mo lspace="0px" rspace="0px">→</mo>
+ <mspace width="200px"></mspace>
+ <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <p>The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the right,
+ and a trailing space of 150px, which is as wide as the black block to the left.</p>
+
+ <math dir="rtl">
+ <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace>
+ <mspace width="150px"></mspace>
+ <mo lspace="0px" rspace="0px">→</mo>
+ <mspace width="150px"></mspace>
+ <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <p>The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the right,
+ and a trailing space of 100px, which is as wide as the black block to the left.</p>
+
+ <math dir="rtl">
+ <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace>
+ <mspace width="200px"></mspace>
+ <mo lspace="0px" rspace="0px">→</mo>
+ <mspace width="100px"></mspace>
+ <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html
new file mode 100644
index 0000000000..a3a3ed501e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>&lt;mo&gt; paint lspace rspace</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <meta name="assert" content="Verifies values for lspace and rspace for element mo in LTR and RTL modes.">
+ <link rel="match" href="mo-paint-lspace-rspace-ref.html">
+ </head>
+ <body>
+ <h1>LTR case</h1>
+
+ <p>The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the left,
+ and a trailing space of 200px, which is as wide as the black block to the right.</p>
+
+ <math>
+ <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace>
+ <mo lspace="100px" rspace="200px">→</mo>
+ <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <p>The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the left,
+ and a trailing space of 150px, which is as wide as the black block to the right.</p>
+
+ <math>
+ <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace>
+ <mo lspace="150px" rspace="150px">→</mo>
+ <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <p>The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the left,
+ and a trailing space of 100px, which is as wide as the black block to the right.</p>
+
+ <math>
+ <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace>
+ <mo lspace="200px" rspace="100px">→</mo>
+ <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <h1>RTL case</h1>
+
+ <p>The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the right,
+ and a trailing space of 200px, which is as wide as the black block to the left.</p>
+
+ <math dir="rtl">
+ <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace>
+ <mo lspace="100px" rspace="200px">→</mo>
+ <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <p>The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the right,
+ and a trailing space of 150px, which is as wide as the black block to the left.</p>
+
+ <math dir="rtl">
+ <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace>
+ <mo lspace="150px" rspace="150px">→</mo>
+ <mspace width="150px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+
+ <p>The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the right,
+ and a trailing space of 100px, which is as wide as the black block to the left.</p>
+
+ <math dir="rtl">
+ <mspace width="200px" height="10px" depth="10px" style="background: black"></mspace>
+ <mo lspace="200px" rspace="100px">→</mo>
+ <mspace width="100px" height="10px" depth="10px" style="background: black"></mspace>
+ </math>
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children-ref.html
new file mode 100644
index 0000000000..6b4ccc775c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>&lt;mo&gt; with a single character and children (reference)</title>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"/>
+ <style>
+ math { font: 25px/1 Ahem; }
+ </style>
+ </head>
+ <body>
+ <p>There should be 5/18em horizontal gaps around the middle rectangles:</p>
+ <p><math><mn>p</mn><mo><span>X</span></mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo>X<span></span></mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo><span></span>X</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo id="dynamic-add">X</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo id="dynamic-text-add">XX</mo><mn>p</mn></math></p>
+
+ <p>There should be no horizontal gap around the middle rectangles:</p>
+
+ <p><math><mn>p</mn><mo stretchy="false" lspace="0" rspace="0">X</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo id="dynamic-remove" stretchy="false" lspace="0" rspace="0"><span></span>X</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo stretchy="false" lspace="0" rspace="0"><!-- COMMENT -->X</mo><mn>p</mn></math></p>
+
+ <p>There should be 4/18em horizontal gaps around the middle rectangles:</p>
+ <p><math><mn>p</mn><mo lspace="0.2222222222222222em" rspace="0.2222222222222222em">XX</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo id="dynamic-text-add-2" lspace="0.2222222222222222em" rspace="0.2222222222222222em">XX</mo><mn>p</mn></math></p>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children.html
new file mode 100644
index 0000000000..a911c44411
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-single-char-and-children.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <meta charset="utf-8">
+ <title>&lt;mo&gt; with a single character and children</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#dfn-algorithm-for-determining-the-properties-of-an-embellished-operator">
+ <meta name="assert" content="Verify that the default operator properties are used for an mo element whose text is a single character but which contains children.">
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"/>
+ <link rel="match" href="mo-single-char-and-children-ref.html">
+ <style>
+ math { font: 25px/1 Ahem; }
+ </style>
+ </head>
+ <body>
+ <p>There should be 5/18em horizontal gaps around the middle rectangles:</p>
+ <p><math><mn>p</mn><mo><span>(</span></mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo>(<span></span></mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo><span></span>(</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo id="dynamic-add">(</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo id="dynamic-text-add">=</mo><mn>p</mn></math></p>
+
+ <p>There should be no horizontal gap around the middle rectangles:</p>
+
+ <p><math><mn>p</mn><mo stretchy="false">(</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo id="dynamic-remove" stretchy="false"><span></span>(</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo stretchy="false"><!-- COMMENT -->(</mo><mn>p</mn></math></p>
+
+ <p>There should be 4/18em horizontal gaps around the middle rectangles:</p>
+ <p><math><mn>p</mn><mo>&amp;<!-- COMMENT -->&amp;</mo><mn>p</mn></math></p>
+ <p><math><mn>p</mn><mo id="dynamic-text-add-2">&amp;</mo><mn>p</mn></math></p>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>
+ MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");
+
+ let mo = document.getElementById("dynamic-add");
+ mo.appendChild(document.createElement("span"));
+
+ mo = document.getElementById("dynamic-text-add");
+ mo.appendChild(document.createTextNode("="));
+
+ mo = document.getElementById("dynamic-text-add-2");
+ mo.appendChild(document.createTextNode("&"));
+
+ mo = document.getElementById("dynamic-remove");
+ mo.removeChild(mo.firstElementChild);
+
+ document.documentElement.classList.remove('reftest-wait');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-001.html
new file mode 100644
index 0000000000..f734253930
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-001.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Stretch properties</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<meta name="assert" content="Verify ">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ math {
+ font: 25px/1 Ahem;
+ }
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ mo {
+ font-family: operators;
+ }
+</style>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+
+ var epsilon = 1;
+ var emToPx = 25;
+ var element;
+
+ test(function() {
+ element = document.getElementById("mn_vertical_line");
+ assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "<mn> element");
+
+ element = document.getElementById("mo_prefix_vertical_line");
+ assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "Prefix <mo> element");
+
+ element = document.getElementById("mo_infix_vertical_line");
+ assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "Infix <mo> element");
+
+ element = document.getElementById("mo_postfix_vertical_line");
+ assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "Postfix <mo> element");
+ }, `Stretchy vertical line`);
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mrow>
+ <!-- Some non-element nodes before -->
+ <mo id="mo_prefix_vertical_line" style="color: green">|</mo>
+ <mn id="mn_vertical_line">|</mn>
+ <mspace width="1em" height="3em" depth="3em" style="background: blue"/>
+ <mo id="mo_infix_vertical_line" lspace="0" rspace="0">|</mo>
+ <mo id="mo_postfix_vertical_line" style="color: green">|</mo>
+ <!-- Some non-element nodes after -->
+ </mrow>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-dynamic-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-dynamic-001.html
new file mode 100644
index 0000000000..5d447aa1d2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/mo-stretch-properties-dynamic-001.html
@@ -0,0 +1,154 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Dynamic stretch properties</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<meta name="assert" content="Verify stretchy, symmetric, largeop, minsize and maxsize are updated dynamically.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ math {
+ font: 25px/1 Ahem;
+ }
+ @font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+ }
+ mo {
+ font-family: operators;
+ }
+</style>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+
+ function runTests() {
+
+ var epsilon = 1;
+ var emToPx = 25;
+ var element;
+
+ test(function() {
+ element = document.getElementById("minsize_attach");
+ element.setAttribute("minsize", "4em");
+ assert_approx_equals(element.getBoundingClientRect().height, 4 * emToPx, epsilon, "attach");
+
+ element = document.getElementById("minsize_modify");
+ element.setAttribute("minsize", "5em");
+ assert_approx_equals(element.getBoundingClientRect().height, 5 * emToPx, epsilon, "modify");
+
+ element = document.getElementById("minsize_remove");
+ element.removeAttribute("minsize");
+ assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "remove");
+ }, `minsize`);
+
+ test(function() {
+ element = document.getElementById("maxsize_attach");
+ element.setAttribute("maxsize", "4em");
+ assert_approx_equals(element.getBoundingClientRect().height, 4 * emToPx, epsilon, "attach");
+
+ element = document.getElementById("maxsize_modify");
+ element.setAttribute("maxsize", "5em");
+ assert_approx_equals(element.getBoundingClientRect().height, 5 * emToPx, epsilon, "modify");
+
+ element = document.getElementById("maxsize_remove");
+ element.removeAttribute("maxsize");
+ assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "remove");
+ }, `maxsize`);
+
+ test(function() {
+ element = document.getElementById("largeop_set_true");
+ element.setAttribute("largeop", "true");
+ assert_approx_equals(element.getBoundingClientRect().height, 2 * emToPx, epsilon, "set true");
+
+ element = document.getElementById("largeop_set_false");
+ element.setAttribute("largeop", "false");
+ assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "set false");
+ }, `largeop`);
+
+ test(function() {
+ element = document.getElementById("symmetric_set_true");
+ element.setAttribute("symmetric", "true");
+ assert_approx_equals(element.getBoundingClientRect().height, 6 * emToPx, epsilon, "set true");
+
+ element = document.getElementById("symmetric_set_false");
+ element.setAttribute("symmetric", "false");
+ assert_approx_equals(element.getBoundingClientRect().height, 3 * emToPx, epsilon, "set false");
+ }, `symmetric`);
+
+ test(function() {
+ element = document.getElementById("stretchy_set_true");
+ element.setAttribute("stretchy", "true");
+ assert_approx_equals(element.getBoundingClientRect().height, 3 * emToPx, epsilon, "set true");
+
+ element = document.getElementById("stretchy_set_false");
+ element.setAttribute("stretchy", "false");
+ assert_approx_equals(element.getBoundingClientRect().height, 1 * emToPx, epsilon, "set false");
+ }, `stretchy`);
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="1em" style="background: blue"/>
+ <mo id="minsize_attach" stretchy="true" symmetric="false">⥯</mo>
+ <mo id="minsize_modify" minsize="3em" stretchy="true" symmetric="false">⥯</mo>
+ <mo id="minsize_remove" minsize="2em" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="6em" style="background: blue"/>
+ <mo id="maxsize_attach" stretchy="true" symmetric="false">⥯</mo>
+ <mo id="maxsize_modify" maxsize="3em" stretchy="true" symmetric="false">⥯</mo>
+ <mo id="maxsize_remove" maxsize="2em" stretchy="true" symmetric="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math displaystyle="true">
+ <mspace width="1em" height="1em" style="background: blue"/>
+ <mrow>
+ <mo id="largeop_set_true" largeop="false" stretchy="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ <mrow>
+ <mo id="largeop_set_false" largeop="true" stretchy="false">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="3em" style="background: blue"/>
+ <mo id="symmetric_set_true" symmetric="false" stretchy="true">⥯</mo>
+ <mo id="symmetric_set_false" symmetric="true" stretchy="true">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+ <p>
+ <math>
+ <mrow>
+ <mspace width="1em" height="3em" style="background: blue"/>
+ <mo id="stretchy_set_true" symmetric="false" stretchy="false">⥯</mo>
+ <mo id="stretchy_set_false" symmetric="false" stretchy="true">⥯</mo>
+ <mn><!-- not space like --></mn>
+ </mrow>
+ </math>
+ </p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accent-dynamic-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accent-dynamic-001-ref.html
new file mode 100644
index 0000000000..3bfb2a3d83
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accent-dynamic-001-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>munderover@accent</title>
+ <meta charset="utf-8"/>
+ </head>
+ <body>
+ <math>
+ <munderover accent="true"><mtext>X</mtext><mo>O</mo><mo>O</mo></munderover>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accent-dynamic-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accent-dynamic-001.html
new file mode 100644
index 0000000000..6c3bc0d830
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accent-dynamic-001.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <title>munderover@accent</title>
+ <meta charset="utf-8"/>
+ <link rel="help" href="https://www.w3.org/TR/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+ <meta name="assert" content="Verifies invalidation after accent attribute is dynamically set.">
+ <link rel="match" href="munderover-accent-dynamic-001-ref.html">
+ <script>
+ function doTest() {
+ document.getElementById('mathOperator').setAttribute('accent', 'true');
+ document.documentElement.removeAttribute("class");
+ }
+ window.addEventListener("TestRendered",doTest);
+ </script>
+ </head>
+ <body>
+ <math>
+ <munderover id="mathOperator"><mtext>X</mtext><mo>O</mo><mo>O</mo></munderover>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accentunder-dynamic-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accentunder-dynamic-001-ref.html
new file mode 100644
index 0000000000..3c3d4abece
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accentunder-dynamic-001-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+ <html>
+ <head>
+ <title>munderover@accentunder</title>
+ <meta charset="utf-8"/>
+ </head>
+ <body>
+ <math>
+ <munderover accentunder="true"><mtext>X</mtext><mo>O</mo><mo>O</mo></munderover>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accentunder-dynamic-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accentunder-dynamic-001.html
new file mode 100644
index 0000000000..33fc5b3f21
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/munderover-accentunder-dynamic-001.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+ <head>
+ <title>munderover@accentunder</title>
+ <meta charset="utf-8"/>
+ <link rel="help" href="https://www.w3.org/TR/mathml-core/#underscripts-and-overscripts-munder-mover-munderover">
+ <meta name="assert" content="Verifies invalidation after accentunder attribute is dynamically set.">
+ <link rel="match" href="munderover-accentunder-dynamic-001-ref.html">
+ <script>
+ function doTest() {
+ document.getElementById('mathOperator').setAttribute('accentunder', 'true');
+ document.documentElement.removeAttribute("class");
+ }
+ window.addEventListener("TestRendered",doTest);
+ </script>
+ </head>
+ <body>
+ <math>
+ <munderover id="mathOperator"><mtext>X</mtext><mo>O</mo><mo>O</mo></munderover>
+ </math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/non-spacing-accent-1-ref.xhtml b/testing/web-platform/tests/mathml/presentation-markup/operators/non-spacing-accent-1-ref.xhtml
new file mode 100644
index 0000000000..9c5a9145f8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/non-spacing-accent-1-ref.xhtml
@@ -0,0 +1,17 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <style type="text/css">
+ html { background-color: white }
+ mi { color: white; }
+ mo { color: red; }
+ </style>
+ </head>
+<body>
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mi>a</mi>
+ <mo>&#x302;</mo>
+ </mover>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/non-spacing-accent-1.xhtml b/testing/web-platform/tests/mathml/presentation-markup/operators/non-spacing-accent-1.xhtml
new file mode 100644
index 0000000000..6061b96bc5
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/non-spacing-accent-1.xhtml
@@ -0,0 +1,20 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Check that non-spacing marks in accents are visible</title>
+ <link rel="mismatch" href="non-spacing-accent-1-ref.xhtml"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=427659"/>
+ <style type="text/css">
+ html { background-color: white }
+ mi { color: white; }
+ mo { color: black; }
+ </style>
+ </head>
+<body>
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <mover>
+ <mi>a</mi>
+ <mo>&#x302;</mo>
+ </mover>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1-notref.html
new file mode 100644
index 0000000000..5650be1936
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1-notref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict mo form</title>
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo form="prefix">+</mo>
+ <!-- need a second child to avoid zeroing dictionary spacing -->
+ <mn>1</mn>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1.html
new file mode 100644
index 0000000000..cdfcca4a57
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict mo form</title>
+ <link rel="mismatch" href="op-dict-1-notref.html">
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo form="infix">+</mo>
+ <mn>1</mn>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12-ref.html
new file mode 100644
index 0000000000..3365b47d39
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict mo movablelimits</title>
+</head>
+<body>
+ <math>
+ <munder>
+ <mo>&sum;</mo>
+ <mi>x</mi>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12.html
new file mode 100644
index 0000000000..7d75c4c174
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-12.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict mo movablelimits</title>
+ <link rel="match" href="op-dict-12-ref.html">
+</head>
+<body>
+ <math>
+ <munder>
+ <mo movablelimits="true">&sum;</mo>
+ <mi>x</mi>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13-notref.html
new file mode 100644
index 0000000000..e9e7614836
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13-notref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict mo movablelimits</title>
+</head>
+<body>
+ <math>
+ <munder>
+ <mo movablelimits="true">&sum;</mo>
+ <mi>x</mi>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13.html
new file mode 100644
index 0000000000..1b7c6bf38f
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-13.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict mo movablelimits</title>
+ <link rel="mismatch" href="op-dict-13-notref.html">
+</head>
+<body>
+ <math>
+ <munder>
+ <mo movablelimits="false">&sum;</mo>
+ <mi>x</mi>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2-ref.html
new file mode 100644
index 0000000000..9c910f8411
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict symmetric</title>
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo symmetric="true">(</mo>
+ <mspace height="5em" depth="5em"/>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2.html
new file mode 100644
index 0000000000..0a26fcae78
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-2.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict symmetric</title>
+ <link rel="match" href="op-dict-2-ref.html">
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo>(</mo>
+ <mspace height="5em" depth="5em"/>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3-notref.html
new file mode 100644
index 0000000000..9c910f8411
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3-notref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict symmetric</title>
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo symmetric="true">(</mo>
+ <mspace height="5em" depth="5em"/>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3.html
new file mode 100644
index 0000000000..bf54ef8582
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-3.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict symmetric</title>
+ <link rel="mismatch" href="op-dict-3-notref.html">
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo symmetric="false">(</mo>
+ <mspace height="5em" depth="5em"/>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4-ref.html
new file mode 100644
index 0000000000..a501e45c8c
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict stretchy</title>
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo>(</mo>
+ <mfrac>
+ <mi>a</mi>
+ <mi>b</mi>
+ </mfrac>
+ <mo>)</mo>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4.html
new file mode 100644
index 0000000000..f847890aa7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-4.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict stretchy</title>
+ <link rel="match" href="op-dict-4-ref.html">
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo stretchy="true">(</mo>
+ <mfrac>
+ <mi>a</mi>
+ <mi>b</mi>
+ </mfrac>
+ <mo stretchy="true">)</mo>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5-notref.html
new file mode 100644
index 0000000000..7ab29e3769
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5-notref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict stretchy</title>
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo stretchy="false">(</mo>
+ <mfrac>
+ <mi>a</mi>
+ <mi>b</mi>
+ </mfrac>
+ <mo>)</mo>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5.html
new file mode 100644
index 0000000000..8c8260d4cd
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-5.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict stretchy</title>
+ <link rel="mismatch" href="op-dict-5-notref.html">
+</head>
+<body>
+ <math>
+ <mrow>
+ <mo>(</mo>
+ <mfrac>
+ <mi>a</mi>
+ <mi>b</mi>
+ </mfrac>
+ <mo>)</mo>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6-ref.html
new file mode 100644
index 0000000000..cb642c4928
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict largeop</title>
+</head>
+<body>
+ <math displaystyle="true">
+ <mrow>
+ <mo largeop="true">&#x2211;</mo>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6.html
new file mode 100644
index 0000000000..6be4cc90a7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-6.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict largeop</title>
+ <link rel="match" href="op-dict-6-ref.html">
+</head>
+<body>
+ <math displaystyle="true">
+ <mrow>
+ <mo>&#x2211;</mo>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7-notref.html
new file mode 100644
index 0000000000..78dd195558
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7-notref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict largeop</title>
+</head>
+<body>
+ <math displaystyle="true">
+ <mrow>
+ <mo>&#x2211;</mo>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7.html
new file mode 100644
index 0000000000..04496eb4f3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-7.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict largeop</title>
+ <link rel="mismatch" href="op-dict-7-notref.html">
+</head>
+<body>
+ <math displaystyle="true">
+ <mrow>
+ <mo largeop="false">&#x2211;</mo>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8-ref.html
new file mode 100644
index 0000000000..b51ce01f36
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict lspace and rspace</title>
+</head>
+<body>
+ <math>
+ <mrow>
+ <mi>x</mi><mo form="prefix" lspace="0.16666666666666666em" rspace="0em">&#x2202;</mo><mi>y</mi>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8.html
new file mode 100644
index 0000000000..0f9b81900e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-8.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict lspace and rspace</title>
+ <link rel="match" href="op-dict-8-ref.html">
+</head>
+<body>
+ <math>
+ <mrow>
+ <mi>x</mi><mo form="prefix">&#x2202;</mo><mi>y</mi>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9-notref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9-notref.html
new file mode 100644
index 0000000000..b976536fac
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9-notref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict lspace and rspace</title>
+</head>
+<body>
+ <math>
+ <mrow>
+ <!-- This spacing was specified in older MathML specification, see
+ https://www.w3.org/TR/MathML3/appendixc.html -->
+ <mi>x</mi><mo form="prefix" lspace="0.1111111111111111em" rspace="0.05555555555555555em">&#x2202;</mo><mi>y</mi>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9.html b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9.html
new file mode 100644
index 0000000000..1e833e31a0
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/op-dict-9.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>op-dict lspace and rspace</title>
+ <link rel="mismatch" href="op-dict-9-notref.html">
+</head>
+<body>
+ <math>
+ <mrow>
+ <mi>x</mi><mo form="prefix">&#x2202;</mo><mi>y</mi>
+ </mrow>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001-ref.html
new file mode 100644
index 0000000000..88e0f5f736
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Spacing of Arabic operators (reference)</title>
+ <link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+ <style>
+ mo {
+ color: blue;
+ }
+ </style>
+ </head>
+ <body>
+
+ <p>There should be no horizontal gaps between the squares:</p>
+ <p><math><mn>_</mn><mo lspace="0" rspace="0">&#x1EEF0;</mo><mn>_</mn></math></p>
+ <p><math><mn>_</mn><mo lspace="0" rspace="0">&#x1EEF1;</mo><mn>_</mn></math></p>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001.html
new file mode 100644
index 0000000000..05d2714af5
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-001.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Spacing of Arabic operators</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+ <meta name="assert" content="Verifies default spacing of the Arabic characters U+1EEF0 and U+1EEF1.">
+ <link rel="match" href="operator-dictionary-arabic-001-ref.html">
+ <link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+ <style>
+ mo {
+ color: blue;
+ }
+ </style>
+ </head>
+ <body>
+
+ <p>There should be no horizontal gaps between the squares:</p>
+ <p><math><mn>_</mn><mo>&#x1EEF0;</mo><mn>_</mn></math></p>
+ <p><math><mn>_</mn><mo>&#x1EEF1;</mo><mn>_</mn></math></p>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>
+ MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002-ref.html
new file mode 100644
index 0000000000..f72fdc8403
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Stretching of Arabic operators (reference)</title>
+ <link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+ </head>
+ <body>
+
+ <p>You should see two rectangles of width 3em and height 1em:</p>
+
+ <p>
+ <math>
+ <munder>
+ <mo stretchy="true">_</mo>
+ <mspace width="3em"/>
+ </munder>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munder>
+ <mo stretchy="true">_</mo>
+ <mspace width="3em"/>
+ </munder>
+ </math>
+ </p>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002.html
new file mode 100644
index 0000000000..d116e1778d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-arabic-002.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Stretching of Arabic operators</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+ <meta name="assert" content="Verifies stretchy property of the Arabic characters U+1EEF0 and U+1EEF1.">
+ <link rel="match" href="operator-dictionary-arabic-002-ref.html">
+ <link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+ </head>
+ <body>
+
+ <p>You should see two rectangles of width 3em and height 1em:</p>
+
+ <p>
+ <math>
+ <munder>
+ <mo>&#x1EEF0;</mo>
+ <mspace width="3em"/>
+ </munder>
+ </math>
+ </p>
+ <p>
+ <math>
+ <munder>
+ <mo>&#x1EEF1;</mo>
+ <mspace width="3em"/>
+ </munder>
+ </math>
+ </p>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script src="/mathml/support/feature-detection-operators.js"></script>
+ <script>
+ MathMLFeatureDetection.ensure_for_match_reftest("has_operator_stretchy");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-combining.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-combining.html
new file mode 100644
index 0000000000..8c891a2a25
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-combining.html
@@ -0,0 +1,159 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary (combining char)</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#layout-of-mrow">
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<meta name="assert" content="Verify special handling of 2-char operator with a combining character">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<style>
+ mo {
+ color: blue;
+ }
+ mn {
+ background: black;
+ }
+</style>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", runTests);
+
+ function spaceBetween(element, i, j) {
+ return element.children[j].getBoundingClientRect().left -
+ element.children[i].getBoundingClientRect().right;
+ }
+ function runTests() {
+ var epsilon = 1;
+ var emToPx = 25;
+
+ [
+ "equal",
+ "vertical_bar",
+ "left_normal_factor_semidirect_product",
+ "there_exists",
+ ].forEach(id => {
+ var div = document.getElementById(id);
+ var ref = div.getElementsByClassName("reference")[0];
+ var totalSpaceRef = spaceBetween(ref, 0, 2);
+ var lspaceRef = spaceBetween(ref, 0, 1);
+ var rspaceRef = spaceBetween(ref, 1, 2);
+ Array.from(div.getElementsByClassName("combining")).forEach(element => {
+ test(function() {
+ assert_true(MathMLFeatureDetection.has_operator_spacing());
+ var totalSpace = spaceBetween(element, 0, 2);
+ var lspace = spaceBetween(element, 0, 1);
+ var rspace = spaceBetween(element, 1, 2);
+ assert_approx_equals(totalSpace, totalSpaceRef, epsilon);
+ assert_approx_equals(rspace, rspaceRef, epsilon);
+ assert_approx_equals(lspace, lspaceRef, epsilon);
+ }, `Spacing around ${element.children[1].textContent}`);
+ });
+ });
+
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+ <div id="equal">
+ <p>
+ <math class="reference">
+ <mn>&nbsp;</mn>
+ <mo>=</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ <p>
+ <math class="combining">
+ <mn>&nbsp;</mn>
+ <mo>=&#x338;</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ <p>
+ <math class="combining">
+ <mn>&nbsp;</mn>
+ <mo>=&#x20D2;</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ </div>
+ <div id="vertical_bar">
+ <p>
+ <math class="reference">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">|</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ <p>
+ <math class="combining">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">|&#x338;</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ <p>
+ <math class="combining">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">|&#x20D2;</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ </div>
+ <div id="left_normal_factor_semidirect_product">
+ <p>
+ <math class="reference">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">⋉</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ <p>
+ <math class="combining">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">⋉&#x338;</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ <p>
+ <math class="combining">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">⋉&#x20D2;</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ </div>
+ <div id="there_exists">
+ <p>
+ <math class="reference">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">∃</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ <p>
+ <math class="combining">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">∃&#x338;</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ <p>
+ <math class="combining">
+ <mn>&nbsp;</mn>
+ <mo stretchy="false">∃&#x20D2;</mo>
+ <mn>&nbsp;</mn>
+ </math>
+ </p>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars-ref.html
new file mode 100644
index 0000000000..2cbed12940
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Spacing of empty and three-char operators (reference)</title>
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math {
+ font: 50px/1 Ahem;
+ }
+ mn:first-child {
+ color: blue;
+ }
+ mn:last-child {
+ color: yellow;
+ }
+ </style>
+ </head>
+ <body>
+
+ <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">_</mo><mn>_</mn></math></p>
+
+ <p>The spacing after the blue squares and before the yellow squares should be the same as the above reference:</p>
+
+ <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em"><!-- empty --></mo><mn>_</mn></math></p>
+ <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">...</mo><mn>_</mn></math></p>
+ <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">lim</mo><mn>_</mn></math>
+ <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">max</mo><mn>_</mn></math>
+ <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">min</mo><mn>_</mn></math>
+ <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">|||</mo><mn>_</mn></math>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars.html
new file mode 100644
index 0000000000..231041c17f
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-empty-and-three-chars.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Spacing of empty and three-char operators</title>
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+ <link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+ <meta name="assert" content="Verifies that empty and three-char operators use the default spacing.">
+ <link rel="match" href="operator-dictionary-empty-and-three-chars-ref.html">
+ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <style>
+ math {
+ font: 50px/1 Ahem;
+ }
+ mn:first-child {
+ color: blue;
+ }
+ mn:last-child {
+ color: yellow;
+ }
+ </style>
+ </head>
+ <body>
+
+ <p><math><mn>_</mn><mo lspace="0.2777777777777778em" rspace="0.2777777777777778em">_</mo><mn>_</mn></math></p>
+
+ <p>The spacing after the blue squares and before the yellow squares should be the same as the above reference:</p>
+
+ <p><math><mn>_</mn><mo><!-- empty --></mo><mn>_</mn></math></p>
+ <p><math><mn>_</mn><mo>...</mo><mn>_</mn></math></p>
+ <p><math><mn>_</mn><mo>lim</mo><mn>_</mn></math>
+ <p><math><mn>_</mn><mo>max</mo><mn>_</mn></math>
+ <p><math><mn>_</mn><mo>min</mo><mn>_</mn></math>
+ <p><math><mn>_</mn><mo>|||</mo><mn>_</mn></math>
+
+ <script src="/mathml/support/feature-detection.js"></script>
+ <script>MathMLFeatureDetection.ensure_for_match_reftest("has_operator_spacing");</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-001.html
new file mode 100644
index 0000000000..457deb3422
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-001.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "largeop", 0);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-002.html
new file mode 100644
index 0000000000..5f132ac3b2
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-002.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "largeop", 1);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-003.html
new file mode 100644
index 0000000000..cb1b1e6b9b
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-003.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "largeop", 2);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-004.html
new file mode 100644
index 0000000000..19a6f9b2f1
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-004.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "largeop", 3);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-005.html
new file mode 100644
index 0000000000..fd04712693
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-005.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "largeop", 4);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-006.html
new file mode 100644
index 0000000000..77d23f60f7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-largeop-006.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "largeop", 5);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-001.html
new file mode 100644
index 0000000000..0a21e277b4
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-001.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "movablelimits", 0);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-002.html
new file mode 100644
index 0000000000..2d7dc414a0
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-002.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "movablelimits", 1);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-003.html
new file mode 100644
index 0000000000..e166d7ffbb
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-003.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "movablelimits", 2);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-004.html
new file mode 100644
index 0000000000..d5dd12b383
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-004.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "movablelimits", 3);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-005.html
new file mode 100644
index 0000000000..d8e96e17a6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-005.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "movablelimits", 4);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-006.html
new file mode 100644
index 0000000000..a6ddeb92ff
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-movablelimits-006.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "movablelimits", 5);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-001.html
new file mode 100644
index 0000000000..6839b183be
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-001.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "lspace/rspace", 0);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-002.html
new file mode 100644
index 0000000000..84113a9ac8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-002.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "lspace/rspace", 1);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-003.html
new file mode 100644
index 0000000000..387f61922d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-003.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "lspace/rspace", 2);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-004.html
new file mode 100644
index 0000000000..b27024c2d3
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-004.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "lspace/rspace", 3);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-005.html
new file mode 100644
index 0000000000..7acf5ab20e
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-005.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "lspace/rspace", 4);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-006.html
new file mode 100644
index 0000000000..928182cbe6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-spacing-006.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "lspace/rspace", 5);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-001.html
new file mode 100644
index 0000000000..beebe77ed7
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-001.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "stretchy", 0);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-002.html
new file mode 100644
index 0000000000..2cdf0114db
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-002.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "stretchy", 1);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-003.html
new file mode 100644
index 0000000000..4f0f0b3641
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-003.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "stretchy", 2);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-004.html
new file mode 100644
index 0000000000..08428b8928
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-004.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "stretchy", 3);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-005.html
new file mode 100644
index 0000000000..94fe507755
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-005.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "stretchy", 4);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-006.html
new file mode 100644
index 0000000000..c4d5e44d43
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-stretchy-006.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "stretchy", 5);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-001.html
new file mode 100644
index 0000000000..c1154cebf5
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-001.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "symmetric", 0);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-002.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-002.html
new file mode 100644
index 0000000000..3cb4b07a55
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-002.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "symmetric", 1);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-003.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-003.html
new file mode 100644
index 0000000000..7588df48f8
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-003.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "symmetric", 2);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-004.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-004.html
new file mode 100644
index 0000000000..f7d8bdc89d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-004.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "symmetric", 3);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-005.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-005.html
new file mode 100644
index 0000000000..9303b9a482
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-005.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "symmetric", 4);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-006.html b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-006.html
new file mode 100644
index 0000000000..90a812786a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/operator-dictionary-symmetric-006.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Operator dictionary</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://w3c.github.io/mathml-core/#dictionary-based-attributes">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-dictionary">
+<link rel="help" href="https://w3c.github.io/mathml-core/#stretchy-operator-axis">
+<meta name="assert" content="Verify default properties for characters that are in the operator dictionary, as well as for U+00A0 NO-BREAK SPACE">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+<script src="/mathml/support/feature-detection-operators.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<script src="/mathml/support/operator-dictionary.js"></script>
+<script src="./support/operator-dictionary-tests.js"></script>
+<link rel="stylesheet" href="./support/operator-dictionary-tests.css"/>
+<script>
+ setup({ explicit_done: true });
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+ async function runTests() {
+ let json = await fetchOperatorDictionary();
+ await OperatorDictionaryTests.run(json, "symmetric", 5);
+ done();
+ }
+</script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001-ref.html b/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001-ref.html
new file mode 100644
index 0000000000..0c7642a20a
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Painting of vertical assembly (reference)</title>
+<style>
+ .container {
+ font-size: 50px;
+ position: absolute;
+ left: 1em;
+ top: 1em;
+ padding: 5px;
+ background: green;
+ width: 4em;
+ height: 8em;
+ }
+</style>
+<body>
+ <p>This test passes if you see a green rectangle and no red.</p>
+ <div class="container">
+ </div>
+</body>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001.html b/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001.html
new file mode 100644
index 0000000000..2a9578badc
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/painting-stretchy-operator-001.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>Painting of vertical assembly</title>
+<link rel="match" href="painting-stretchy-operator-001-ref.html">
+<link rel="help" href="https://w3c.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
+<link rel="help" href="https://crbug.com/1409380">
+<meta name="assert" content="Verify that vertical glyph assemblies are painted at the position of their bounding box.">
+<script src="/mathml/support/fonts.js"></script>
+<style>
+ .container {
+ font-size: 50px;
+ position: absolute;
+ left: 1em;
+ top: 1em;
+ padding: 5px;
+ background: green;
+ width: 4em;
+ height: 8em;
+ }
+ mo {
+ color: green;
+ background: red;
+ }
+ .frame {
+ position: absolute;
+ box-sizing: border-box;
+ border: 2px solid green;
+ }
+ @font-face {
+ font-family: stretchy;
+ src: url("/fonts/math/stretchy.woff");
+ }
+ @font-face {
+ font-family: stretchy-centered-on-baseline;
+ src: url("/fonts/math/stretchy-centered-on-baseline.woff");
+ }
+</style>
+<script>
+ function runTests() {
+ // Add a green frame around mo to avoid antialisasing/rounding issues.
+ Array.from(document.getElementsByTagName('mo')).forEach(mo => {
+ let box = mo.getBoundingClientRect();
+ let div = document.createElement("div");
+ div.className = 'frame';
+ div.style.left = `${box.left-1}px`;
+ div.style.top = `${box.top-1}px`;
+ div.style.width = `${box.width+1}px`;
+ div.style.height = `${box.height+1}px`;
+ document.body.appendChild(div);
+ });
+ document.documentElement.classList.remove("reftest-wait");
+ }
+ window.addEventListener("load", () => { loadAllFonts().then(runTests); });
+</script>
+<body>
+ <p>This test passes if you see a green rectangle and no red.</p>
+ <div class="container">
+ <!-- This font uses assembly glyphs with zero ink descent, which is what
+ Latin Modern Math does for U+007C VERTICAL LINE. -->
+ <math style="font-family: stretchy">
+ <mspace height="4em"/>
+ <mo stretchy="true" symmetric="true">&#x295C;</mo>
+ </math>
+ <!-- This font uses assembly glyphs with non-zero ink descent, which is what
+ Cambria Math does for U+007C VERTICAL LINE. -->
+ <math style="font-family: stretchy-centered-on-baseline">
+ <mspace height="4em"/>
+ <mo stretchy="true" symmetric="true">&#x295C;</mo>
+ </math>
+ </div>
+</body>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/stretchy-underbar-1-ref.xhtml b/testing/web-platform/tests/mathml/presentation-markup/operators/stretchy-underbar-1-ref.xhtml
new file mode 100644
index 0000000000..0f36f2da64
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/stretchy-underbar-1-ref.xhtml
@@ -0,0 +1,17 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <style type="text/css">
+ html { background-color: white; font-size: 50px }
+ mi { color: white; }
+ mo { color: red; }
+ </style>
+ </head>
+<body>
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <munder>
+ <mi>long</mi>
+ <mo stretchy="true">&#x332;</mo>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/stretchy-underbar-1.xhtml b/testing/web-platform/tests/mathml/presentation-markup/operators/stretchy-underbar-1.xhtml
new file mode 100644
index 0000000000..63bf7391c6
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/stretchy-underbar-1.xhtml
@@ -0,0 +1,20 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Check that UnderBar is visible when stretched</title>
+ <link rel="mismatch" href="stretchy-underbar-1-ref.xhtml"/>
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=242861"/>
+ <style type="text/css">
+ html { background-color: white; font-size: 50px }
+ mi { color: white; }
+ mo { color: black; }
+ </style>
+ </head>
+<body>
+ <math xmlns="http://www.w3.org/1998/Math/MathML">
+ <munder>
+ <mi>long</mi>
+ <mo stretchy="true">&#x332;</mo>
+ </munder>
+ </math>
+</body>
+</html>
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.css b/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.css
new file mode 100644
index 0000000000..4f80ad7f8d
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.css
@@ -0,0 +1,10 @@
+@font-face {
+ font-family: operators;
+ src: url("/fonts/math/operators.woff");
+}
+math, math * {
+ font-family: operators;
+ /* Use large enough font-size so that 1/18em = 2.77px > epsilon and
+ one can really distinguish lspace/rspace values. */
+ font-size: 50px;
+}
diff --git a/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.js b/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.js
new file mode 100644
index 0000000000..35efc2ecb9
--- /dev/null
+++ b/testing/web-platform/tests/mathml/presentation-markup/operators/support/operator-dictionary-tests.js
@@ -0,0 +1,226 @@
+var OperatorDictionaryTests = {
+ "lspace/rspace": function(json, key) {
+ let parsedKey = splitKey(key);
+ let entry = json.dictionary[key];
+ let epsilon = 1;
+
+ document.body.insertAdjacentHTML("beforeend", `<div>\
+lspace/rspace for "${parsedKey.characters}" (${parsedKey.form}): \
+<math>\
+ <mrow>\
+ <mn>&nbsp;</mn>\
+ <mo form="${parsedKey.form}">${parsedKey.characters}</mo>\
+ <mn>&nbsp;</mn>\
+ </mrow>\
+</math>\
+ VS \
+<math>\
+ <mrow>\
+ <mn>&nbsp;</mn>\
+ <mo form="${parsedKey.form}" lspace="${defaultPropertyValue(entry, 'lspace')}" rspace="${defaultPropertyValue(entry, 'rspace')}">${parsedKey.characters}</mo>\
+ <mn>&nbsp;</mn>\
+ </mrow>\
+</math>\
+</div>`);
+ var div = document.body.lastElementChild;
+ var mrows = div.getElementsByTagName("mrow");
+ function spaceBetween(element, i, j) {
+ return element.children[j].getBoundingClientRect().left -
+ element.children[i].getBoundingClientRect().right;
+ }
+ var lspace = spaceBetween(mrows[0], 0, 1);
+ var rspace = spaceBetween(mrows[0], 1, 2);
+ var lspaceRef = spaceBetween(mrows[1], 0, 1);
+ var rspaceRef = spaceBetween(mrows[1], 1, 2);
+ assert_approx_equals(lspace, lspaceRef, epsilon, `lspace (${key})`);
+ assert_approx_equals(rspace, rspaceRef, epsilon, `rspace (${key})`);
+ div.style.display = "none";
+ },
+
+ "movablelimits": function(json, key) {
+ let parsedKey = splitKey(key);
+ let entry = json.dictionary[key];
+ let epsilon = 1;
+
+ var defaultValue = defaultPropertyValue(entry, "movablelimits");
+ document.body.insertAdjacentHTML("beforeend", `<div>\
+movablelimits for "${parsedKey.characters}" (${parsedKey.form}): \
+<math>\
+ <munder>\
+ <mo stretchy="false" form="${parsedKey.form}">${parsedKey.characters}</mo>\
+ <mn>&nbsp;</mn>\
+ </munder>\
+</math>\
+ VS \
+<math>\
+ <munder>\
+ <mo stretchy="false" form="${parsedKey.form}" movablelimits="${defaultValue}">${parsedKey.characters}</mo>\
+ <mn>&nbsp;</mn>\
+ </munder>\
+</math>\
+</div>`);
+ var div = document.body.lastElementChild;
+ var munders = div.getElementsByTagName("munder");
+ munder = munders[0].getBoundingClientRect()
+ munderRef = munders[1].getBoundingClientRect()
+ assert_approx_equals(munder.height, munderRef.height, epsilon, `Movablelimits property for ${key} should be '${defaultValue}'`);
+ div.style.display = "none";
+ },
+
+ "largeop": function(json, key) {
+ let parsedKey = splitKey(key);
+ let entry = json.dictionary[key];
+ let epsilon = 1;
+
+ var defaultValue = defaultPropertyValue(entry, "largeop");
+ document.body.insertAdjacentHTML("beforeend", `<div>\
+largeop for "${parsedKey.characters}" (${parsedKey.form}): \
+<math displaystyle="true">\
+ <mo form="${parsedKey.form}">${parsedKey.characters}</mo>\
+</math>\
+ VS \
+<math displaystyle="true">\
+ <mo form="${parsedKey.form}" largeop="${defaultValue}">${parsedKey.characters}</mo>\
+</math>\
+</div>`);
+ var div = document.body.lastElementChild;
+ var mos = div.getElementsByTagName("mo");
+ mo = mos[0].getBoundingClientRect()
+ moRef = mos[1].getBoundingClientRect()
+ assert_approx_equals(mo.height, moRef.height, epsilon, `Largeop property for ${key} should be '${defaultValue}'`);
+ div.style.display = "none";
+ },
+
+ "stretchy": function(json, key) {
+ let parsedKey = splitKey(key);
+ let entry = json.dictionary[key];
+ let epsilon = 1;
+
+ if (entry.horizontal) {
+ // FIXME: Should really do a MathMLFeatureDetection to verify
+ // support for *horizontal* stretching.
+ var defaultValue = defaultPropertyValue(entry, "stretchy");
+ document.body.insertAdjacentHTML("beforeend", `<div>\
+stretchy for "${parsedKey.characters}" (${parsedKey.form}): \
+<math>\
+ <munder>\
+ <mn>&nbsp;&nbsp;</mn>\
+ <mo form="${parsedKey.form}">${parsedKey.characters}</mo>\
+ </munder>\
+</math>\
+ VS \
+<math>\
+ <munder>\
+ <mn>&nbsp;&nbsp;</mn>\
+ <mo form="${parsedKey.form}" stretchy="${defaultValue}">${parsedKey.characters}</mo>\
+ </munder>\
+</math>\
+</div>`);
+ var div = document.body.lastElementChild;
+ var mos = div.getElementsByTagName("mo");
+ mo = mos[0].getBoundingClientRect()
+ moRef = mos[1].getBoundingClientRect()
+ assert_approx_equals(mo.width, moRef.width, epsilon, `Stretchy property for ${key} should be '${defaultValue}'`);
+ div.style.display = "none";
+ } else {
+ var defaultValue = defaultPropertyValue(entry, "stretchy");
+ document.body.insertAdjacentHTML("beforeend", `<div>\
+stretchy for "${parsedKey.characters}" (${parsedKey.form}): \
+<math>\
+ <mrow>\
+ <mo form="${parsedKey.form}" symmetric="false">${parsedKey.characters}</mo>\
+ <mspace height="2em"></mspace>\
+ </mrow>\
+</math>\
+ VS \
+<math>\
+ <mrow>\
+ <mo form="${parsedKey.form}" symmetric="false" stretchy="${defaultValue}">${parsedKey.characters}</mo>\
+ <mspace height="2em"></mspace>\
+ </mrow>\
+</math>\
+</div>`);
+ var div = document.body.lastElementChild;
+ var mos = div.getElementsByTagName("mo");
+ mo = mos[0].getBoundingClientRect()
+ moRef = mos[1].getBoundingClientRect()
+ assert_approx_equals(mo.height, moRef.height, epsilon, `Stretchy property for ${key} should be '${defaultValue}'`);
+ div.style.display = "none";
+ }
+ },
+
+ "symmetric": function(json, key) {
+ let parsedKey = splitKey(key);
+ let entry = json.dictionary[key];
+ let epsilon = 1;
+
+ var defaultValue = defaultPropertyValue(entry, "symmetric");
+ document.body.insertAdjacentHTML("beforeend", `<div>\
+symmetric for "${parsedKey.characters}" (${parsedKey.form}): \
+<math>\
+ <mrow>\
+ <mo form="${parsedKey.form}" stretchy="true">${parsedKey.characters}</mo>\
+ <mspace height="1.5em"></mspace>\
+ </mrow>\
+</math>\
+ VS \
+<math>\
+ <mrow>\
+ <mo form="${parsedKey.form}" stretchy="true" symmetric="${defaultValue}">${parsedKey.characters}</mo>\
+ <mspace height="1.5em"></mspace>\
+ </mrow>\
+</math>\
+</div>`);
+ var div = document.body.lastElementChild;
+ var mos = div.getElementsByTagName("mo");
+ mo = mos[0].getBoundingClientRect()
+ moRef = mos[1].getBoundingClientRect()
+ assert_approx_equals(mo.height, moRef.height, epsilon, `Symmetric property for ${key} should be '${defaultValue}'`);
+ div.style.display = "none";
+ },
+
+ run: async function(json, name, fileIndex) {
+ let has_required_feature_for_testing =
+ await MathMLFeatureDetection[`has_operator_${name}`]();
+
+ // The operator dictionary has more than one thousand of entries so the
+ // tests are grouped in chunks so that these don't get much more
+ // importance than other MathML tests. For easy debugging, one can set the
+ // chunk size to 1. Also, note that the test div will remain visible for
+ // failed tests.
+ const entryPerChunk = 50
+ const filesPerProperty = 6
+
+ var counter = 0;
+ var test;
+
+ for (key in json.dictionary) {
+
+ // Skip this key if it does not belong to that test file.
+ if (counter % filesPerProperty != fileIndex) {
+ counter++;
+ continue;
+ }
+
+ var counterInFile = (counter - fileIndex) / filesPerProperty;
+ if (counterInFile % entryPerChunk === 0) {
+ // Start of a new chunk.
+ // Complete current async tests and create new ones for the next chunk.
+ if (test) test.done();
+ test = async_test(`Operator dictionary chunk ${1 + counterInFile / entryPerChunk} - ${name}`);
+
+ test.step(function() {
+ assert_true(has_required_feature_for_testing, `${name} is supported`);
+ });
+ }
+ test.step(function() {
+ OperatorDictionaryTests[name](json, key);
+ });
+
+ counter++;
+ }
+
+ // Complete current async test.
+ if (test) test.done();
+ }
+};