Skip to content

Commit b949de1

Browse files
fred-wangmoz-wptsync-bot
authored andcommitted
Bug 1571679 [wpt PR 18293] - MathML: Add tests for children not participating to their parent layout, a=testonly
Automatic update from web-platform-tests MathML: Add tests for children not participating to their parent layout (#18293) * MathML: Add tests for children not participating to their parent layout This commit adds new tests to verify that children with "display: none", "position: absolute" or "position: fixed" don't affect preferred width calculation or layout of their parents. - mathml/support/mathml-fragments.js: Add function to append a non empty child (optionally making the element invalid) and use that function for forceNonEmptyElement. - mathml/support/layout-comparison.js: Introduce new helpers function to extract the children participating to their parent layout. Modify compareLayout so that it browser that list of children instead and allow comparison in horizontal+LTR mode. * Add feature detection otherwise these tests pass when MathML is disabled. * Add TODO for floats. -- wpt-commits: 7a669f450b8ffbc803a3206bee36733e06773e90 wpt-pr: 18293
1 parent a244983 commit b949de1

File tree

3 files changed

+116
-24
lines changed

3 files changed

+116
-24
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Elements not participating to the layout of their parent</title>
6+
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#layout-algorithms">
7+
<meta name="assert" content="Verify that display: none and out-of-flow positioned elements do not participate to layout of their parent.">
8+
<script src="/resources/testharness.js"></script>
9+
<script src="/resources/testharnessreport.js"></script>
10+
<script src="/mathml/support/feature-detection.js"></script>
11+
<script src="/mathml/support/layout-comparison.js"></script>
12+
<script src="/mathml/support/mathml-fragments.js"></script>
13+
<script>
14+
var epsilon = 1;
15+
16+
setup({ explicit_done: true });
17+
window.addEventListener("load", runTests);
18+
19+
function runTests() {
20+
21+
for (tag in MathMLFragments) {
22+
if (!FragmentHelper.isValidChildOfMrow(tag) ||
23+
FragmentHelper.isEmpty(tag))
24+
continue;
25+
// TODO: Add floats too?
26+
["display: none",
27+
"position: absolute",
28+
"position: fixed"
29+
].forEach(style => {
30+
document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\
31+
<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\
32+
<div style="display: inline-block"><math>${MathMLFragments[tag]}</math></div>\
33+
</div>`);
34+
var div = document.body.lastElementChild;
35+
36+
var elementContainer = div.firstElementChild;
37+
var elementContainerWidth = elementContainer.getBoundingClientRect().width;
38+
var element = FragmentHelper.element(elementContainer);
39+
FragmentHelper.forceNonEmptyElement(element);
40+
var allowInvalid = true;
41+
var child = FragmentHelper.appendChild(element, allowInvalid);
42+
child.setAttribute("style", style);
43+
44+
var referenceContainer = div.lastElementChild;
45+
var referenceContainerWidth = referenceContainer.getBoundingClientRect().width;
46+
var reference = FragmentHelper.element(referenceContainer);
47+
FragmentHelper.forceNonEmptyElement(reference);
48+
49+
var epsilon = 1;
50+
51+
test(function() {
52+
// FIXME(fwang): Feature detection should be done per-tag.
53+
assert_true(MathMLFeatureDetection.has_mspace());
54+
assert_approx_equals(elementContainerWidth, referenceContainerWidth, epsilon);
55+
}, `${tag} preferred width calculation is not affected by children with "${style}" style`);
56+
57+
test(function() {
58+
// FIXME(fwang): Feature detection should be done per-tag.
59+
assert_true(MathMLFeatureDetection.has_mspace());
60+
compareLayout(element, reference, epsilon);
61+
}, `${tag} layout is not affected by children with "${style}" style`);
62+
63+
div.style = "display: none;"; // Hide the div after measurement.
64+
});
65+
}
66+
67+
done();
68+
}
69+
</script>
70+
</head>
71+
<body>
72+
<div id="log"></div>
73+
</body>
74+
</html>

testing/web-platform/tests/mathml/support/layout-comparison.js

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,46 @@ function compareSize(element, reference, epsilon) {
3737
}
3838
}
3939

40-
function compareLayout(element, reference, epsilon) {
41-
if (element.children.length != reference.children.length)
42-
throw "Reference should have the same number of children."
40+
function participateToParentLayout(child) {
41+
var style = window.getComputedStyle(child);
42+
return style.getPropertyValue("display") !== "none" &&
43+
style.getPropertyValue("position") !== "absolute" &&
44+
style.getPropertyValue("position") !== "fixed";
45+
}
46+
47+
function childrenParticipatingToLayout(element) {
48+
var children = [];
49+
Array.from(element.children).forEach(child => {
50+
if (participateToParentLayout(child))
51+
children.push(child);
52+
})
53+
return children;
54+
}
4355

56+
function compareLayout(element, reference, epsilon) {
4457
// Compare sizes of elements and children.
4558
var param = getWritingMode(element, reference);
4659

4760
compareSize(element, reference, epsilon);
4861
var elementBox = element.getBoundingClientRect();
4962
var referenceBox = reference.getBoundingClientRect();
50-
for (var i = 0; i < element.children.length; i++) {
51-
var childDisplay = window.
52-
getComputedStyle(element.children[i]).getPropertyValue("display");
53-
var referenceChildDisplay = window.
54-
getComputedStyle(reference.children[i]).getPropertyValue("display");
55-
if (referenceChildDisplay !== childDisplay)
56-
throw "compareLayout: children of reference should have the same display values.";
57-
if (childDisplay === "none")
58-
continue;
5963

60-
compareSize(element.children[i], reference.children[i], epsilon);
64+
var elementChildren = childrenParticipatingToLayout(element);
65+
var referenceChildren = childrenParticipatingToLayout(reference);
66+
if (elementChildren.length != referenceChildren.length)
67+
throw "Reference should have the same number of children participating to layout."
68+
69+
for (var i = 0; i < elementChildren.length; i++) {
70+
compareSize(elementChildren[i], referenceChildren[i], epsilon);
6171

62-
var childBox = element.children[i].getBoundingClientRect();
63-
var referenceChildBox = reference.children[i].getBoundingClientRect();
72+
var childBox = elementChildren[i].getBoundingClientRect();
73+
var referenceChildBox = referenceChildren[i].getBoundingClientRect();
6474

6575
switch(param.mode) {
6676
case "horizontal-tb":
67-
if (!param.rtl)
68-
throw "compareLayout: unexpected writing-mode value";
69-
assert_approx_equals(elementBox.right - childBox.right,
77+
assert_approx_equals(param.rtl ?
78+
elementBox.right - childBox.right :
79+
childBox.left - elementBox.left,
7080
referenceChildBox.left - referenceBox.left,
7181
epsilon,
7282
`inline position (child ${i})`);

testing/web-platform/tests/mathml/support/mathml-fragments.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,25 @@ var FragmentHelper = {
138138
return fragment.getElementsByClassName('element')[0];
139139
},
140140

141-
forceNonEmptyElement: function(fragment) {
141+
appendChild: function(fragment, allowInvalid) {
142142
var element = this.element(fragment) || fragment;
143-
if (element.firstElementChild)
144-
return element.firstElementChild;
145-
if (element.classList.contains("mathml-container"))
146-
return element.appendChild(this.createElement("mrow"));
147143
if (element.classList.contains("foreign-container")) {
148144
var el = document.createElement("span");
149145
el.textContent = "a";
150146
return element.appendChild(el);
151147
}
152-
throw "Cannot make the element nonempty";
148+
if (element.classList.contains("mathml-container") || allowInvalid) {
149+
var el = this.createElement("mi");
150+
el.textContent = "a";
151+
return element.appendChild(el);
152+
}
153+
throw "Cannot append child to the element";
154+
},
155+
156+
forceNonEmptyElement: function(fragment) {
157+
var element = this.element(fragment) || fragment;
158+
if (element.firstElementChild)
159+
return element.firstElementChild;
160+
return this.appendChild(fragment);
153161
}
154162
}

0 commit comments

Comments
 (0)