all-mathml-containers.html (4362B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>absolutely positioned in all MathML elements</title> 6 <link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> 7 <meta name="assert" content="Verify that absolutely positioned node works in all MathML elements."> 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/mathml-fragments.js"></script> 12 <style> 13 /* override display: none on children of maction/semantics */ 14 maction > *, semantics > * { 15 display: math; 16 } 17 </style> 18 <script> 19 20 setup({ explicit_done: true }); 21 window.addEventListener("load", runTests); 22 23 function runTests() { 24 ["absolute", "fixed"].forEach(positionValue => { 25 for (tag in MathMLFragments) { 26 if (!FragmentHelper.isValidChildOfMrow(tag) || 27 FragmentHelper.isEmpty(tag)) 28 continue; 29 document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\ 30 <math>${MathMLFragments[tag]}</math>\ 31 </div>`); 32 let div = document.body.lastElementChild; 33 let element = FragmentHelper.element(div.firstElementChild); 34 FragmentHelper.forceNonEmptyElement(element); 35 if (element.classList.contains("mathml-container") || 36 element.classList.contains("foreign-container")) { 37 for (let i = 0; i < 5; i++) { 38 FragmentHelper.appendChild(element); 39 } 40 } 41 42 let middleChild; 43 if (element.children.length >= 2) { 44 middleChild = FragmentHelper.appendChild(element, true /*allowInvalid*/); 45 middleChild.setAttribute("style", `position: ${positionValue}; left: 300px; top: 400px`); 46 let middlePosition = Math.floor(element.children.length/2); 47 element.insertBefore(middleChild, element.children[middlePosition]); 48 } 49 50 let firstChild = FragmentHelper.appendChild(element, true /*allowInvalid*/); 51 firstChild.setAttribute("style", `position: ${positionValue}; left: 100px; top: 200px`); 52 element.insertBefore(firstChild, element.firstElementChild); 53 54 let lastChild = FragmentHelper.appendChild(element, true /*allowInvalid*/); 55 lastChild.setAttribute("style", `position: ${positionValue}; left: 500px; top: 600px`); 56 57 let referenceBox; 58 switch (positionValue) { 59 case "absolute": 60 // Use the absolutely positioned div ancestor. 61 referenceBox = div.getBoundingClientRect(); 62 break 63 case "fixed": 64 // Use the viewport. 65 referenceBox = {left: 0, top: 0}; 66 break; 67 default: 68 throw "reference box not defined"; 69 } 70 71 let firstChildBox = firstChild.getBoundingClientRect(); 72 let lastChildBox = lastChild.getBoundingClientRect(); 73 let middleChildBox; 74 if (middleChild) { 75 middleChildBox = middleChild.getBoundingClientRect(); 76 } 77 78 let epsilon = 1; 79 80 test(function() { 81 assert_true(MathMLFeatureDetection[`has_${tag}`](), `${tag} is supported`); 82 assert_approx_equals(firstChildBox.left - referenceBox.left, 100, epsilon); 83 assert_approx_equals(firstChildBox.top - referenceBox.top, 200, epsilon); 84 if (middleChildBox) { 85 assert_approx_equals(middleChildBox.left - referenceBox.left, 300, epsilon); 86 assert_approx_equals(middleChildBox.top - referenceBox.top, 400, epsilon); 87 } 88 assert_approx_equals(lastChildBox.left - referenceBox.left, 500, epsilon); 89 assert_approx_equals(lastChildBox.top - referenceBox.top, 600, epsilon); 90 }, `position: ${positionValue}; children in ${tag}`); 91 92 div.style = "display: none;"; // Hide the div after measurement. 93 } 94 }); 95 96 done(); 97 } 98 </script> 99 </head> 100 <body> 101 <div id="log"></div> 102 </body> 103 </html>