Bug 1568670 [wpt PR 18059] - MathML: Prevent false negative results when mspace is not supported., a=testonly

Automatic update from web-platform-tests
MathML: Prevent false negative results when mspace is not supported. (#18059)

Many testharness tests rely on the <mspace> to draw boxes inside math formulas
and test MathML layout. When this element is not supported (e.g. lack of
MathML support) the boxes are basically empty and this leads to many false
negative results, especially because tests also allow some rounding errors.
More generally, for several tests it is assumed that some more basic
features are supported in order to perform their verifications.

This commit introduces a new MathMLFeatureDetection helper class to perform
such verifications and avoid false negatives results. One detection is added
for the <mspace> element and several presentation-markup tests relying on this
element are updated to perform this feature detection prior to runnig the
actual checks. This could be improved in the future, this is just fixing the
most serious issues.
--

wpt-commits: 6550e91cd39dde7597b780f2d643a1a131837012
wpt-pr: 18059
This commit is contained in:
Frédéric Wang 2019-08-01 14:18:42 +00:00 committed by moz-wptsync-bot
parent 64a64ce96c
commit 15e48cb829
20 changed files with 209 additions and 1 deletions

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Verify fraction metrics for different sizes of numerator and denominator.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -33,6 +34,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 3;
var mathAxis = getBox("axis").middle;
// For stacks, nothing in the OpenType MATH specification seems to ensure
@ -51,6 +54,8 @@
}, "Fraction axis is aligned on the math axis");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
for (var i = 0; i < 10; i++) {
assert_less_than(getBox("frac" + i + "num").bottom, getBox("frac" + i + "den").top, "numerator is above denominator");
assert_less_than(getBox("frac" + i + "den").top - getBox("frac" + i + "num").bottom, 5, "The gap between numerator and denominator is not too large");
@ -58,12 +63,16 @@
}, "Vertical positions of numerator and denominator");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 3;
for (var i = 0; i < 10; i++)
assert_approx_equals(getBox("frac" + i + "num").center, getBox("frac" + i + "den").center, e, "numerator and denominator are horizontally centered");
}, "Horizontal alignments of numerator and denominator");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 5;
for (var i = 0; i < 10; i++) {
var frac = getBox("frac" + i);

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Element mfrac correctly uses the fraction parameters from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -68,6 +69,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 7000 * emToPx;
var v2 = 1000 * emToPx;
assert_approx_equals(getBox("ref0001").top - getBox("num0001").bottom,
@ -75,54 +78,72 @@
}, "AxisHeight");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 5000 * emToPx;
assert_approx_equals(getBox("den0002").top - getBox("ref0002").bottom,
v1, epsilon, "mfrac: denominator gap");
}, "DenominatorDisplayStyleGapMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 6000 * emToPx;
assert_approx_equals(getBox("den0003").top - getBox("ref0003").bottom,
v1, epsilon, "mfrac: denominator shift");
}, "DenominatorDisplayStyleShiftDown");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 4000 * emToPx;
assert_approx_equals(getBox("den0004").top - getBox("ref0004").bottom,
v1, epsilon, "mfrac: denominator gap");
}, "DenominatorGapMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 3000 * emToPx;
assert_approx_equals(getBox("den0005").top - getBox("ref0005").bottom,
v1, epsilon, "mfrac: denominator shift");
}, "DenominatorShiftDown");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 8000 * emToPx;
assert_approx_equals(getBox("ref0006").top - getBox("num0006").bottom,
v1, epsilon, "mfrac: numerator gap");
}, "NumeratorDisplayStyleGapMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 2000 * emToPx;
assert_approx_equals(getBox("ref0007").top - getBox("num0007").bottom,
v1, epsilon, "mfrac: numerator shift");
}, "NumeratorDisplayStyleShiftDown");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 9000 * emToPx;
assert_approx_equals(getBox("ref0008").top - getBox("num0008").bottom,
v1, epsilon, "mfrac: numerator gap");
}, "NumeratorGapMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 11000 * emToPx;
assert_approx_equals(getBox("ref0009").top - getBox("num0009").bottom,
v1, epsilon, "mfrac: numerator shift");
}, "NumeratorShiftDown");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 10000 * emToPx;
assert_approx_equals(getBox("den0010").top - getBox("num0010").bottom,
v1, epsilon, "mfrac: rule thickness");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Element mfrac correctly uses the stack parameters from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -56,42 +57,56 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 7000 * emToPx;
assert_approx_equals(getBox("ref0001").top - getBox("num0001").bottom,
v, epsilon, "mfrac: axis height");
}, "AxisHeight");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 5000 * emToPx;
assert_approx_equals(getBox("den0002").top - getBox("ref0002").bottom,
v, epsilon, "mfrac: denominator shift");
}, "BottomDisplayStyleShiftDown");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 6000 * emToPx;
assert_approx_equals(getBox("den0003").top - getBox("ref0003").bottom,
v, epsilon, "mfrac: denominator shift");
}, "BottomShiftDown");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 4000 * emToPx;
assert_approx_equals(getBox("den0004").top - getBox("num0004").bottom,
v, epsilon, "mfrac: gap");
}, "DisplayStyleGapMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 8000 * emToPx;
assert_approx_equals(getBox("den0005").top - getBox("num0005").bottom,
v, epsilon, "mfrac: gap");
}, "GapMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 3000 * emToPx;
assert_approx_equals(getBox("ref0006").top - getBox("num0006").bottom,
v, epsilon, "mfrac: numerator shift");
}, "TopDisplayStyleShiftUp");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 9000 * emToPx;
assert_approx_equals(getBox("ref0007").top - getBox("num0007").bottom,
v, epsilon, "mfrac: numerator shift");

View File

@ -12,6 +12,7 @@
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#enclose-expression-inside-notation-menclose">
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#adjust-space-around-content-mpadded">
<meta name="assert" content="Baseline for mrow-like elements is correct.">
<script src="/mathml/support/feature-detection.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="text/javascript">
@ -23,6 +24,7 @@
var x = document.getElementById("above" + tag).getBoundingClientRect();
var y = document.getElementById("below" + tag).getBoundingClientRect();
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
assert_equals(x.bottom, y.top);
}, "baseline alignment inside " + tag);
});

View File

@ -13,6 +13,7 @@
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#adjust-space-around-content-mpadded">
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
<meta name="assert" content="Operators can stretch inside mrow-like elements.">
<script src="/mathml/support/feature-detection.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
@ -36,6 +37,7 @@
["Mrow", "Sqrt", "Style", "Error", "Phantom", "Math", "Menclose", "Mpadded"].forEach((tag) => {
var mo = document.getElementById("mo" + tag);
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
assert_greater_than_equal(mo.getBoundingClientRect().height, 100);
}, "operator stretching inside " + tag);
});

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Elements msqrt and mroot correctly use the radical parameters from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -56,6 +57,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 25;
var v2 = 1000 * emToPx;
var radicalHeight = getBox("base001").height + v2;
@ -65,6 +68,8 @@
}, "RadicalDegreeBottomRaisePercent");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 7000 * emToPx;
var v2 = 1000 * emToPx;
assert_approx_equals(getBox("base0021").top - getBox("radical0021").top,
@ -76,6 +81,8 @@
}, "RadicalDisplayStyleVerticalGap");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 3000 * emToPx;
var v2 = 1000 * emToPx;
assert_approx_equals(getBox("base0031").top - getBox("radical0031").top,
@ -86,7 +93,9 @@
"mroot: vertical gap");
}, "RadicalExtraAscender");
test(function() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
// Note: the size variants of U+221A in this font have width 1000.
var v1 = 5000 * emToPx;
var radicalSymbolWidth = 1000 * emToPx;
@ -97,6 +106,8 @@
}, "RadicalKernAfterDegree");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 4000 * emToPx;
assert_approx_equals(getBox("index005").left - getBox("radical005").left,
v1, epsilon,
@ -104,6 +115,8 @@
}, "RadicalKernBeforeDegree");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 8000 * emToPx;
assert_approx_equals(getBox("base0061").top - getBox("radical0061").top,
v, epsilon,
@ -114,6 +127,8 @@
}, "RadicalRuleThickness");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 6000 * emToPx;
var v2 = 1000 * emToPx;
assert_approx_equals(getBox("base0071").top - getBox("radical0071").top,

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Basic metrics for elements msub, msup and msubsup.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -28,6 +29,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
assert_less_than_equal(getBox("msubBase").right, getBox("msubSub").left, e, "msub: subscript is after base");
assert_less_than_equal(getBox("msupBase").right, getBox("msupSup").left, e, "msup: superscript is after base");
@ -43,6 +46,8 @@
}, "Respective horizontal positions");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
assert_approx_equals(getBox("msubBase").middle, getBox("baseline").bottom, e, "msub: base is placed on the baseline");
assert_approx_equals(getBox("msupBase").middle, getBox("baseline").bottom, e, "msup: base is placed on the baseline");
@ -50,6 +55,8 @@
}, "Alignment of the base on the baseline");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 3;
assert_approx_equals(getBox("msubSub").middle, getBox("msubBase").bottom, e, "msub: script is placed at the bottom of the base");
assert_approx_equals(getBox("msupSup").middle, getBox("msupBase").top, e, "msup: script is placed at the top of the base");
@ -58,6 +65,8 @@
}, "Vertical position of scripts");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 3;
assert_approx_equals(getBox("msub").width, getBox("msubSub").right - getBox("msubBase").left, e, "msub: width is determined by the left/right sides of base/script (+ some space after script)");
assert_approx_equals(getBox("msup").width, getBox("msupSup").right - getBox("msupBase").left, e, "msup: width is determined by the left/right sides of base/script (+ some space after script)");
@ -65,6 +74,8 @@
}, "Width of scripted elements");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
assert_greater_than_equal(getBox("msub").height, getBox("msubBase").height, e, "msub: height is at least the one of the base");
assert_greater_than_equal(getBox("msup").height, getBox("msupBase").height, e, "msup: height is at least the one of the base");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Basic metrics for the mmultiscript element.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -28,6 +29,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
assert_less_than_equal(getBox("msubBase").right, getBox("msubSub").left, e, "subscript is after base");
assert_less_than_equal(getBox("msupBase").right, getBox("msupSup").left, e, "superscript is after base");
@ -54,6 +57,8 @@
}, "Respective horizontal positions");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
assert_approx_equals(getBox("msubBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline");
assert_approx_equals(getBox("msupBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline");
@ -64,6 +69,8 @@
}, "Alignment of the base on the baseline");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 3;
assert_approx_equals(getBox("msubSub").middle, getBox("msubBase").bottom, e, "script is placed at the bottom of the base");
assert_approx_equals(getBox("msupSup").middle, getBox("msupBase").top, e, "script is placed at the top of the base");
@ -77,6 +84,8 @@
}, "Vertical position of scripts");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 3;
assert_approx_equals(getBox("msub").width, getBox("msubSub").right - getBox("msubBase").left, e, "width is determined by the left/right sides of base/script (+ some space after script)");
assert_approx_equals(getBox("msup").width, getBox("msupSup").right - getBox("msupBase").left, e, "width is determined by the left/right sides of base/script (+ some space after script)");
@ -88,6 +97,8 @@
}, "Width of scripted elements");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
assert_greater_than_equal(getBox("msub").height, getBox("msubBase").height, e, "height is at least the one of the base");
assert_greater_than_equal(getBox("msup").height, getBox("msupBase").height, e, "height is at least the one of the base");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Basic metrics for the mmultiscript element with many scripts.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -28,12 +29,16 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
for (var i = 0; i < 5; i++)
assert_approx_equals(getBox("multi" + i + "base").middle, getBox("baseline").bottom, e, "base " + i + "is placed on the baseline");
}, "Alignment of the base on the baseline");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 5;
assert_approx_equals(getBox("multi0").width, 30, e, "width of multi0");
assert_approx_equals(getBox("multi0").height, 30, e, "height of multi0");
@ -49,6 +54,8 @@
}, "Dimensions of the scripted elements");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 3;
for (var i = 2; i <= 4; i++) {
var base = getBox("multi" + i + "base");
@ -66,6 +73,8 @@
}, "Vertical positions of scripts");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
for (var i = 2; i <= 4; i++) {
var base = getBox("multi" + i + "base");
@ -81,6 +90,8 @@
}, "Horizontal alignment of scripts");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
for (var i = 2; i <= 4; i++) {
var base = getBox("multi" + i + "base");
var firstPostScript = getBox("multi" + i + "postsub1");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Verify metrics of scripted elements for bases of different heights.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -30,6 +31,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
sizeArray.forEach(function(size) {
assert_approx_equals(getBox("msub" + size + "base").middle, getBox("baseline").bottom, e, "msub base " + size + "is placed on the baseline");
@ -40,6 +43,8 @@
}, "Alignment on the baseline for bases of different heights");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 5;
sizeArray.forEach(function(size) {
assert_approx_equals(getBox("msub" + size + "sub").middle, getBox("msub" + size + "base").bottom, e, "msub script " + size + "is placed at the top of of the base");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Verify metrics of scripted elements with tall scripts.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -30,6 +31,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
assert_approx_equals(getBox("msubbase").middle, getBox("baseline").bottom, e, "msub base is placed on the baseline");
assert_approx_equals(getBox("msupbase").middle, getBox("baseline").bottom, e, "msup base is placed on the baseline");
@ -38,6 +41,8 @@
}, "Alignment on the baseline with different and large script heights");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
assert_greater_than(getBox("msubsub").top, getBox("msubbase").top, "msub: subscript is below the top of the base");
assert_less_than(getBox("msupsup").bottom, getBox("msupbase").bottom, "msup: supscript is above the bottom of the base");
assert_greater_than(getBox("msubsupsub").top, getBox("msubsupbase").top, "msubsup: subscript is below the top of the base");
@ -49,6 +54,8 @@
}, "Tall subscripts/superscripts are not placed too high/low");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
assert_greater_than(getBox("msubsupsub").top, getBox("msubsupsup").bottom, "msubsup: subscript is below the superscript");
assert_greater_than(getBox("multipresub").top, getBox("multipresup").bottom, "mmultiscripts: presubscript is below the presuperscript");
assert_greater_than(getBox("multipostsub").top, getBox("multipostsup").bottom, "mmultiscripts: postsubscript is below the postsuperscript");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Elements msub, msup, subsup and msubsup correctly use the subscript and superscript parameters from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -68,6 +69,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 3000 * emToPx;
assert_approx_equals(getBox("ref001").left - getBox("sub001").right, v, epsilon, "msub: Space after subscript");
assert_approx_equals(getBox("ref002").left - getBox("sup002").right, v, epsilon, "msup: Space after superscript");
@ -78,6 +81,8 @@
}, "SpaceAfterScript");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 7000 * emToPx;
assert_approx_equals(getBox("ref101").bottom - getBox("sup102").bottom, v, epsilon, "msup: Superscript shift");
assert_approx_equals(getBox("ref101").bottom - getBox("sup103").bottom, v, epsilon, "msubsup: Superscript shift");
@ -87,6 +92,8 @@
}, "SuperscriptShiftUp");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 5000 * emToPx;
assert_approx_equals(getBox("ref201").bottom - getBox("sup202").bottom, v, epsilon, "msup: Superscript shift");
assert_approx_equals(getBox("ref201").bottom - getBox("sup203").bottom, v, epsilon, "msubsup: Superscript shift");
@ -96,6 +103,8 @@
}, "SuperscriptShiftUpCramped");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 6000 * emToPx;
assert_approx_equals(getBox("sub301").bottom - getBox("ref300").bottom, v, epsilon, "msup: Subscript shift");
assert_approx_equals(getBox("sub302").bottom - getBox("ref300").bottom, v, epsilon, "msubsup: Subscript shift");
@ -104,12 +113,16 @@
}, "SubscriptShiftDown");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 11000 * emToPx;
assert_approx_equals(getBox("sub4011").top - getBox("sup4012").bottom, v, epsilon, "msubsup: SubSuperscript gap");
assert_approx_equals(getBox("sub4021").top - getBox("sup4022").bottom, v, epsilon, "mmultiscripts: SubSuperscript gap");
}, "SubSuperscriptGapMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 11000 * emToPx;
var v2 = 3000 * emToPx;
assert_approx_equals(getBox("sub501").top - getBox("sup501").bottom, v1, epsilon, "msubsup: SubSuperscript gap");
@ -119,21 +132,29 @@
}, "SuperscriptBottomMaxWithSubscript");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 4000 * emToPx;
assert_approx_equals(getBox("ref600").bottom - getBox("sub601").top, v, epsilon, "msub: Subscript top");
}, "SubscriptTopMax");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 8000 * emToPx;
assert_approx_equals(getBox("ref700").bottom - getBox("sub701").bottom, v, epsilon, "msub: Superscript bottom");
}, "SuperscriptBottomMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 9000 * emToPx;
assert_approx_equals(getBox("sub801").bottom - getBox("base801").bottom, v, epsilon, "msub: Superscript drop");
}, "SubscriptBaselineDrop");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 10000 * emToPx;
assert_approx_equals(getBox("sup901").bottom - getBox("base901").top, v, epsilon, "msup: Superscript drop");
}, "SuperscriptBaselineDrop");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Elements msub, msup, subsup and msubsup correctly use the italic correction from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -42,6 +43,8 @@
var epsilon = 1;
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 0;
assert_approx_equals(getBox("base001").right - getBox("sub001").left, v, epsilon, "msub");
assert_approx_equals(getBox("sup002").left, getBox("base002").right, epsilon, "msup");
@ -50,6 +53,8 @@
assert_approx_equals(getBox("sup005").left - getBox("sub005").left, 0, epsilon, "mmultiscripts prescripts");
}, "Null Italic Correction");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000
var v = 3000 * emToPx;
assert_approx_equals(getBox("base011").right - getBox("sub011").left, v, epsilon, "msub");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Elements munder, mover, munderover correctly .">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace, mo {
font-size: 10px;
@ -29,6 +30,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
for (var i = 0; i <= 3; i++) {
assert_approx_equals(getBox("under" + i + "base").middle, getBox("baseline").bottom, e, "munder " + i + ": base is placed on the baseline");
@ -40,6 +43,8 @@
}, "Alignment of the base on the baseline");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
for (var i = 0; i <= 3; i++) {
assert_approx_equals(getBox("under" + i + "under").center, getBox("under" + i + "base").center, e, "munder " + i + ": base and script are horizontally centered");
@ -52,6 +57,8 @@
}, "Horizontal alignments of base and scripts");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
for (var i = 0; i <= 3; i++) {
assert_greater_than_equal(getBox("under" + i + "under").top, getBox("under" + i + "base").bottom, "munder " + i + ": script is under base");
assert_less_than_equal(getBox("over" + i + "over").bottom, getBox("over" + i + "base").top, "mover " + i + ": script is over base");
@ -63,6 +70,8 @@
}, "Relative vertical positions of base and scripts");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 1;
for (var i = 0; i <= 3; i++) {
assert_approx_equals(getBox("under" + i).width, Math.max(getBox("under" + i + "base").width, getBox("under" + i + "under").width), e, "munder " + i + ": width is determined by the maximum of width of base and script");
@ -74,6 +83,8 @@
}, "Width of scripted elements");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var e = 3.2;
for (var i = 0; i <= 3; i++) {
assert_approx_equals(getBox("under" + i).height, getBox("under" + i + "base").height + getBox("under" + i + "under").height + e, e, "munder " + i + ": height is determined by the sum of heights of base and script plus some spacing.");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Elements munder, mover, munderover correctly use the limit parameters from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace, mo {
font-size: 10px;
@ -44,6 +45,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 3000 * emToPx;
assert_approx_equals(getBox("under00011").top - getBox("ref0001").bottom,
v, epsilon, "munder: under shift");
@ -52,6 +55,8 @@
}, "LowerLimitBaselineDropMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 11000 * emToPx;
assert_approx_equals(getBox("under00021").top - getBox("ref0002").bottom,
v, epsilon, "munder: under gap");
@ -60,6 +65,8 @@
}, "LowerLimitGapMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 5000 * emToPx;
assert_approx_equals(getBox("ref0003").top - getBox("over00031").bottom,
v, epsilon, "mover: over shift");
@ -68,6 +75,8 @@
}, "UpperLimitBaselineRiseMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 7000 * emToPx;
assert_approx_equals(getBox("ref0004").top - getBox("over00041").bottom,
v, epsilon, "mover: over shift");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Elements munder, mover, munderover correctly use the stretch stack parameters from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace, mo {
font-size: 10px;
@ -44,6 +45,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 3000 * emToPx;
assert_approx_equals(getBox("under00011").top - getBox("ref0001").bottom,
v, epsilon, "munder: under shift");
@ -52,6 +55,8 @@
}, "StretchStackBottomShiftDown");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 11000 * emToPx;
assert_approx_equals(getBox("under00021").top - getBox("ref0002").bottom,
v, epsilon, "munder: under gap");
@ -60,6 +65,8 @@
}, "StretchStackGapBelowMin");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 5000 * emToPx;
assert_approx_equals(getBox("ref0003").top - getBox("over00031").bottom,
v, epsilon, "mover: over shift");
@ -68,6 +75,8 @@
}, "StretchStackTopShiftUp");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 7000 * emToPx;
assert_approx_equals(getBox("ref0004").top - getBox("over00041").bottom,
v, epsilon, "mover: over shift");

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Elements munder, mover, munderover correctly use underbar/overbar and AccentBaseHeight parameters from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace, mo {
font-size: 10px;
@ -47,6 +48,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
for (var i = 1; i <= 4; i++) {
for (var j = 1; j <= 6; j++) {
var baseId = ("base00" + i) + j;
@ -59,6 +62,8 @@
}, "Baseline alignment");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
for (var i = 1; i <= 4; i++) {
for (var j = 1; j <= 6; j++) {
var baseId = ("base00" + i) + j;
@ -72,6 +77,8 @@
}, "Heights of bases");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 5000 * emToPx;
assert_approx_equals(getBox("ref001").bottom - getBox("over0014").bottom,
shortBaseHeight, epsilon,
@ -96,6 +103,8 @@
}, "AccentBaseHeight, UnderbarExtraDescender");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 7000 * emToPx;
assert_approx_equals(getBox("ref002").bottom - getBox("over0024").bottom,
shortBaseHeight, epsilon,
@ -118,6 +127,8 @@
}, "AccentBaseHeight, UnderbarVerticalGap");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 3000 * emToPx;
assert_approx_equals(getBox("ref003").bottom - getBox("over0031").bottom,
shortBaseHeight, epsilon,
@ -154,6 +165,8 @@
}, "AccentBaseHeight, OverbarExtraAscender");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
v = 11000 * emToPx;
assert_approx_equals(getBox("ref004").bottom - getBox("over0041").bottom,
shortBaseHeight + v, epsilon,

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Elements munder, mover, munderover correctly use underbar/overbar and AccentBaseHeight parameters from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace, mo {
font-size: 10px;
@ -47,6 +48,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
for (var i = 1; i <= 4; i++) {
for (var j = 1; j <= 6; j++) {
var baseId = ("base00" + i) + j;
@ -59,6 +62,8 @@
}, "Baseline alignment");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
for (var i = 1; i <= 4; i++) {
for (var j = 1; j <= 6; j++) {
var baseId = ("base00" + i) + j;
@ -72,6 +77,8 @@
}, "Heights of bases");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 5000 * emToPx;
assert_approx_equals(getBox("ref001").bottom - getBox("over0014").bottom,
shortBaseHeight, epsilon,
@ -96,6 +103,8 @@
}, "AccentBaseHeight, UnderbarExtraDescender");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 7000 * emToPx;
assert_approx_equals(getBox("ref002").bottom - getBox("over0024").bottom,
shortBaseHeight, epsilon,
@ -118,6 +127,8 @@
}, "AccentBaseHeight, UnderbarVerticalGap");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v = 3000 * emToPx;
assert_approx_equals(getBox("ref003").bottom - getBox("over0031").bottom,
shortBaseHeight, epsilon,
@ -154,6 +165,8 @@
}, "AccentBaseHeight, OverbarExtraAscender");
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
v = 11000 * emToPx;
assert_approx_equals(getBox("ref004").bottom - getBox("over0041").bottom,
shortBaseHeight + v, epsilon,

View File

@ -7,6 +7,7 @@
<meta name="assert" content="Element mtable correctly uses the axis height parameter from the MATH table.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/mathml/support/feature-detection.js"></script>
<style>
math, mspace {
font-size: 10px;
@ -32,6 +33,8 @@
function runTests() {
test(function() {
assert_true(MathMLFeatureDetection.has_mspace());
var v1 = 5000 * emToPx;
var tableMiddle = (getBox("table").bottom + getBox("table").top) / 2;
assert_approx_equals(getBox("baseline").bottom - tableMiddle,

View File

@ -0,0 +1,15 @@
// This is a helper for MathML feature detection.
// It is indented to be used to prevent false negative test results.
var MathMLFeatureDetection = {
has_mspace: function() {
if (!this.hasOwnProperty("_has_mspace")) {
document.body.insertAdjacentHTML("beforeend", "<math><mspace width='20px'></mspace></math>");
var math = document.body.lastElementChild;
this._has_mspace =
math.firstChild.getBoundingClientRect().width > 10;
document.body.removeChild(math);
}
return this._has_mspace;
}
};