Bug 1912435 - Make MathML boolean attributes ASCII case-insensitive. r=emilio
This commit ensures MathML boolean attributes (namely displaystyle, mo@stretchy, mo@symmetric, mo@largeop, mo@movablelimits, munder@accentunder, mover@accent, munderover@accent, munderover@accentunder) are ASCII case-insensitive [1]. For displaystyle that was handled in [2]. For mover/munder/munderover attributes, this is covered by a test case from scriptlevel-001.html checking both case-insensitivity and dynamic changes at the same time ; the latter still seems broken, so these checks are moved into separate test cases. For mo attributes, a new WPT test is added. Note that mo@accent, mo@fence, mo@separator are not part of MathML Core (with the two last without visual effect), we make them case-insensitive for consistency but don't bother adding tests for them. [1] https://w3c.github.io/mathml-core/#dfn-boolean used here: [2] https://bugzilla.mozilla.org/show_bug.cgi?id=1574087 Differential Revision: https://phabricator.services.mozilla.com/D218944
This commit is contained in:
@@ -237,17 +237,19 @@ void nsMathMLmoFrame::ProcessOperatorData() {
|
||||
|
||||
// see if the accent attribute is there
|
||||
mContent->AsElement()->GetAttr(nsGkAtoms::accent_, value);
|
||||
if (value.EqualsLiteral("true"))
|
||||
if (value.LowerCaseEqualsLiteral("true")) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
|
||||
else if (value.EqualsLiteral("false"))
|
||||
} else if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
|
||||
}
|
||||
|
||||
// see if the movablelimits attribute is there
|
||||
mContent->AsElement()->GetAttr(nsGkAtoms::movablelimits_, value);
|
||||
if (value.EqualsLiteral("true"))
|
||||
if (value.LowerCaseEqualsLiteral("true")) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
|
||||
else if (value.EqualsLiteral("false"))
|
||||
} else if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_MOVABLELIMITS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// we will be called again to re-sync the rest of our state next time...
|
||||
@@ -444,36 +446,39 @@ void nsMathMLmoFrame::ProcessOperatorData() {
|
||||
// don't process them here
|
||||
|
||||
mContent->AsElement()->GetAttr(nsGkAtoms::stretchy_, value);
|
||||
if (value.EqualsLiteral("false")) {
|
||||
if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mFlags &= ~NS_MATHML_OPERATOR_STRETCHY;
|
||||
} else if (value.EqualsLiteral("true")) {
|
||||
} else if (value.LowerCaseEqualsLiteral("true")) {
|
||||
mFlags |= NS_MATHML_OPERATOR_STRETCHY;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_FENCE(mFlags)) {
|
||||
mContent->AsElement()->GetAttr(nsGkAtoms::fence_, value);
|
||||
if (value.EqualsLiteral("false"))
|
||||
if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mFlags &= ~NS_MATHML_OPERATOR_FENCE;
|
||||
else
|
||||
} else {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_FENCE;
|
||||
}
|
||||
}
|
||||
mContent->AsElement()->GetAttr(nsGkAtoms::largeop_, value);
|
||||
if (value.EqualsLiteral("false")) {
|
||||
if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mFlags &= ~NS_MATHML_OPERATOR_LARGEOP;
|
||||
} else if (value.EqualsLiteral("true")) {
|
||||
} else if (value.LowerCaseEqualsLiteral("true")) {
|
||||
mFlags |= NS_MATHML_OPERATOR_LARGEOP;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_SEPARATOR(mFlags)) {
|
||||
mContent->AsElement()->GetAttr(nsGkAtoms::separator_, value);
|
||||
if (value.EqualsLiteral("false"))
|
||||
if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mFlags &= ~NS_MATHML_OPERATOR_SEPARATOR;
|
||||
else
|
||||
} else {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_SEPARATOR;
|
||||
}
|
||||
}
|
||||
mContent->AsElement()->GetAttr(nsGkAtoms::symmetric_, value);
|
||||
if (value.EqualsLiteral("false"))
|
||||
if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mFlags &= ~NS_MATHML_OPERATOR_SYMMETRIC;
|
||||
else if (value.EqualsLiteral("true"))
|
||||
} else if (value.LowerCaseEqualsLiteral("true")) {
|
||||
mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
|
||||
}
|
||||
|
||||
// minsize
|
||||
//
|
||||
|
||||
@@ -223,9 +223,9 @@ XXX The winner is the outermost setting in conflicting settings like these:
|
||||
// if we have an accentunder attribute, it overrides what the underscript
|
||||
// said
|
||||
if (mContent->AsElement()->GetAttr(nsGkAtoms::accentunder_, value)) {
|
||||
if (value.EqualsLiteral("true")) {
|
||||
if (value.LowerCaseEqualsLiteral("true")) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
} else if (value.EqualsLiteral("false")) {
|
||||
} else if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
|
||||
}
|
||||
}
|
||||
@@ -244,9 +244,9 @@ XXX The winner is the outermost setting in conflicting settings like these:
|
||||
|
||||
// if we have an accent attribute, it overrides what the overscript said
|
||||
if (mContent->AsElement()->GetAttr(nsGkAtoms::accent_, value)) {
|
||||
if (value.EqualsLiteral("true")) {
|
||||
if (value.LowerCaseEqualsLiteral("true")) {
|
||||
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
} else if (value.EqualsLiteral("false")) {
|
||||
} else if (value.LowerCaseEqualsLiteral("false")) {
|
||||
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[scriptlevel-001.html]
|
||||
[checking dynamic/case-insensitive accent/accentunder]
|
||||
[checking dynamic accent/accentunder]
|
||||
expected: FAIL
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Test case insensitivity of mo boolean attributes (reference)</title>
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||
<style>
|
||||
math {
|
||||
font: 25px/1 Ahem;
|
||||
}
|
||||
@font-face {
|
||||
font-family: operators;
|
||||
src: url("/fonts/math/operators.woff");
|
||||
}
|
||||
mo {
|
||||
font-family: operators;
|
||||
}
|
||||
</style>
|
||||
<p>
|
||||
<math>
|
||||
<mrow>
|
||||
<mo symmetric="false" stretchy="false">⥯</mo>
|
||||
<mspace height="2em"></mspace>
|
||||
</mrow>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mrow>
|
||||
<mo symmetric="true" stretchy="true">⥯</mo>
|
||||
<mspace height="1.5em"></mspace>
|
||||
</mrow>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math displaystyle="true">
|
||||
<mo largeop="false">∑</mo>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<munder>
|
||||
<mo movablelimits="false">∑</mo>
|
||||
<mtext>X</mtext>
|
||||
</munder>
|
||||
</math>
|
||||
</p>
|
||||
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Test case insensitivity of mo boolean attributes</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 case insensitivity of mo boolean attributes.">
|
||||
<link rel="match" href="mo-boolean-attributes-case-insensitive-ref.html">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||
<style>
|
||||
math {
|
||||
font: 25px/1 Ahem;
|
||||
}
|
||||
@font-face {
|
||||
font-family: operators;
|
||||
src: url("/fonts/math/operators.woff");
|
||||
}
|
||||
mo {
|
||||
font-family: operators;
|
||||
}
|
||||
</style>
|
||||
<p>
|
||||
<math>
|
||||
<mrow>
|
||||
<mo symmetric="false" stretchy="FaLsE">⥯</mo>
|
||||
<mspace height="2em"></mspace>
|
||||
</mrow>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mrow>
|
||||
<mo symmetric="TrUe" stretchy="true">⥯</mo>
|
||||
<mspace height="1.5em"></mspace>
|
||||
</mrow>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math displaystyle="true">
|
||||
<mo largeop="FALSe">∑</mo>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<munder>
|
||||
<mo movablelimits="fALse">∑</mo>
|
||||
<mtext>X</mtext>
|
||||
</munder>
|
||||
</math>
|
||||
</p>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_munderover");</script>
|
||||
@@ -55,43 +55,50 @@
|
||||
});
|
||||
|
||||
test(function() {
|
||||
var element = document.querySelector("munder[accentunder='true']");
|
||||
var element = document.getElementById("munder-accentunder")
|
||||
assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
|
||||
assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under");
|
||||
}, `automatic scriptlevel on munder (accentunder=true)`);
|
||||
|
||||
test(function() {
|
||||
var element = document.querySelector("mover[accent='true']");
|
||||
var element = document.getElementById("mover-accent")
|
||||
assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
|
||||
assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "over");
|
||||
}, `automatic scriptlevel on mover (accent=true)`);
|
||||
|
||||
test(function() {
|
||||
var element = document.querySelector("munderover[accentunder='true']");
|
||||
var element = document.getElementById("munderover-accentunder")
|
||||
assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
|
||||
assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under");
|
||||
assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero * .71, epsilon, "over");
|
||||
}, `automatic scriptlevel on munderover (accentunder=true)`);
|
||||
|
||||
test(function() {
|
||||
var element = document.querySelector("munderover[accent='true']");
|
||||
var element = document.getElementById("munderover-accent")
|
||||
assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
|
||||
assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71, epsilon, "under");
|
||||
assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero, epsilon, "over");
|
||||
}, `automatic scriptlevel on munderover (accent=true)`);
|
||||
|
||||
test(function() {
|
||||
var element = document.getElementById("munderover-dynamic-case-insensitive")
|
||||
var element = document.getElementById("munderover-case-insensitive")
|
||||
assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
|
||||
assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under");
|
||||
assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero, epsilon, "over");
|
||||
}, "checking case-insensitivity accent/accentunder");
|
||||
|
||||
test(function() {
|
||||
var element = document.getElementById("munderover-dynamic")
|
||||
assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
|
||||
assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero * .71, epsilon, "under");
|
||||
assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero, epsilon, "over");
|
||||
|
||||
element.removeAttribute("accent");
|
||||
element.setAttribute("accentunder", "TrUe");
|
||||
element.setAttribute("accentunder", "true");
|
||||
assert_approx_equals(fontSize(element.children[0]), fontSizeAtScriptLevelZero, epsilon, "base");
|
||||
assert_approx_equals(fontSize(element.children[1]), fontSizeAtScriptLevelZero, epsilon, "under");
|
||||
assert_approx_equals(fontSize(element.children[2]), fontSizeAtScriptLevelZero * .71, epsilon, "over");
|
||||
}, "checking dynamic/case-insensitive accent/accentunder");
|
||||
}, "checking dynamic accent/accentunder");
|
||||
|
||||
done();
|
||||
}
|
||||
@@ -179,26 +186,26 @@
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<munder accentunder="true">
|
||||
<munder id="munder-accentunder" accentunder="true">
|
||||
<mn>0</mn>
|
||||
<mn>1</mn>
|
||||
</munder>
|
||||
</math>
|
||||
<math>
|
||||
<mover accent="true">
|
||||
<mover id="mover-accent" accent="true">
|
||||
<mn>0</mn>
|
||||
<mn>1</mn>
|
||||
</mover>
|
||||
</math>
|
||||
<math>
|
||||
<munderover accent="true">
|
||||
<munderover id="munderover-accent" accent="true">
|
||||
<mn>0</mn>
|
||||
<mn>1</mn>
|
||||
<mn>2</mn>
|
||||
</munderover>
|
||||
</math>
|
||||
<math>
|
||||
<munderover accentunder="true">
|
||||
<munderover id="munderover-accentunder" accentunder="true">
|
||||
<mn>0</mn>
|
||||
<mn>1</mn>
|
||||
<mn>2</mn>
|
||||
@@ -207,7 +214,16 @@
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<munderover id="munderover-dynamic-case-insensitive" accent="TrUe">
|
||||
<munderover id="munderover-case-insensitive" accent="TrUe" accentunder="TrUe">
|
||||
<mn>0</mn>
|
||||
<mn>1</mn>
|
||||
<mn>2</mn>
|
||||
</munderover>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<munderover id="munderover-dynamic" accent="true">
|
||||
<mn>0</mn>
|
||||
<mn>1</mn>
|
||||
<mn>2</mn>
|
||||
|
||||
Reference in New Issue
Block a user