1(function() { 2// Test is initiated from body.onload, so explicit done() call is required. 3setup({ explicit_done: true }); 4 5function checkSubtreeExpectedValues(t, parent, prefix) 6{ 7 var checkedLayout = checkExpectedValues(t, parent, prefix); 8 Array.prototype.forEach.call(parent.childNodes, function(node) { 9 checkedLayout |= checkSubtreeExpectedValues(t, node, prefix); 10 }); 11 return checkedLayout; 12} 13 14function checkAttribute(output, node, attribute) 15{ 16 var result = node.getAttribute && node.getAttribute(attribute); 17 output.checked |= !!result; 18 return result; 19} 20 21function assert_tolerance(actual, expected, message) 22{ 23 if (isNaN(expected) || Math.abs(actual - expected) >= 1) { 24 assert_equals(actual, Number(expected), message); 25 } 26} 27 28function checkExpectedValues(t, node, prefix) 29{ 30 var output = { checked: false }; 31 32 var expectedWidth = checkAttribute(output, node, "data-expected-width"); 33 if (expectedWidth) { 34 assert_tolerance(node.offsetWidth, expectedWidth, prefix + "width"); 35 } 36 37 var expectedHeight = checkAttribute(output, node, "data-expected-height"); 38 if (expectedHeight) { 39 assert_tolerance(node.offsetHeight, expectedHeight, prefix + "height"); 40 } 41 42 var expectedOffset = checkAttribute(output, node, "data-offset-x"); 43 if (expectedOffset) { 44 assert_tolerance(node.offsetLeft, expectedOffset, prefix + "offsetLeft"); 45 } 46 47 var expectedOffset = checkAttribute(output, node, "data-offset-y"); 48 if (expectedOffset) { 49 assert_tolerance(node.offsetTop, expectedOffset, prefix + "offsetTop"); 50 } 51 52 var expectedWidth = checkAttribute(output, node, "data-expected-client-width"); 53 if (expectedWidth) { 54 assert_tolerance(node.clientWidth, expectedWidth, prefix + "clientWidth"); 55 } 56 57 var expectedHeight = checkAttribute(output, node, "data-expected-client-height"); 58 if (expectedHeight) { 59 assert_tolerance(node.clientHeight, expectedHeight, prefix + "clientHeight"); 60 } 61 62 var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width"); 63 if (expectedWidth) { 64 assert_tolerance(node.scrollWidth, expectedWidth, prefix + "scrollWidth"); 65 } 66 67 var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height"); 68 if (expectedHeight) { 69 assert_tolerance(node.scrollHeight, expectedHeight, prefix + "scrollHeight"); 70 } 71 72 var expectedWidth = checkAttribute(output, node, "data-expected-bounding-client-rect-width"); 73 if (expectedWidth) { 74 assert_tolerance(node.getBoundingClientRect().width, expectedWidth, prefix + "getBoundingClientRect().width"); 75 } 76 77 var expectedOffset = checkAttribute(output, node, "data-total-x"); 78 if (expectedOffset) { 79 var totalLeft = node.clientLeft + node.offsetLeft; 80 assert_tolerance(totalLeft, expectedOffset, prefix + 81 "clientLeft+offsetLeft (" + node.clientLeft + " + " + node.offsetLeft + ")"); 82 } 83 84 var expectedOffset = checkAttribute(output, node, "data-total-y"); 85 if (expectedOffset) { 86 var totalTop = node.clientTop + node.offsetTop; 87 assert_tolerance(totalTop, expectedOffset, prefix + 88 "clientTop+offsetTop (" + node.clientTop + " + " + node.offsetTop + ")"); 89 } 90 91 var expectedDisplay = checkAttribute(output, node, "data-expected-display"); 92 if (expectedDisplay) { 93 var actualDisplay = getComputedStyle(node).display; 94 assert_equals(actualDisplay, expectedDisplay, prefix + "display"); 95 } 96 97 var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top"); 98 if (expectedPaddingTop) { 99 var actualPaddingTop = getComputedStyle(node).paddingTop; 100 // Trim the unit "px" from the output. 101 actualPaddingTop = actualPaddingTop.slice(0, -2); 102 assert_equals(actualPaddingTop, expectedPaddingTop, prefix + "padding-top"); 103 } 104 105 var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom"); 106 if (expectedPaddingBottom) { 107 var actualPaddingBottom = getComputedStyle(node).paddingBottom; 108 // Trim the unit "px" from the output. 109 actualPaddingBottom = actualPaddingBottom.slice(0, -2); 110 assert_equals(actualPaddingBottom, expectedPaddingBottom, prefix + "padding-bottom"); 111 } 112 113 var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left"); 114 if (expectedPaddingLeft) { 115 var actualPaddingLeft = getComputedStyle(node).paddingLeft; 116 // Trim the unit "px" from the output. 117 actualPaddingLeft = actualPaddingLeft.slice(0, -2); 118 assert_equals(actualPaddingLeft, expectedPaddingLeft, prefix + "padding-left"); 119 } 120 121 var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right"); 122 if (expectedPaddingRight) { 123 var actualPaddingRight = getComputedStyle(node).paddingRight; 124 // Trim the unit "px" from the output. 125 actualPaddingRight = actualPaddingRight.slice(0, -2); 126 assert_equals(actualPaddingRight, expectedPaddingRight, prefix + "padding-right"); 127 } 128 129 var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top"); 130 if (expectedMarginTop) { 131 var actualMarginTop = getComputedStyle(node).marginTop; 132 // Trim the unit "px" from the output. 133 actualMarginTop = actualMarginTop.slice(0, -2); 134 assert_equals(actualMarginTop, expectedMarginTop, prefix + "margin-top"); 135 } 136 137 var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom"); 138 if (expectedMarginBottom) { 139 var actualMarginBottom = getComputedStyle(node).marginBottom; 140 // Trim the unit "px" from the output. 141 actualMarginBottom = actualMarginBottom.slice(0, -2); 142 assert_equals(actualMarginBottom, expectedMarginBottom, prefix + "margin-bottom"); 143 } 144 145 var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left"); 146 if (expectedMarginLeft) { 147 var actualMarginLeft = getComputedStyle(node).marginLeft; 148 // Trim the unit "px" from the output. 149 actualMarginLeft = actualMarginLeft.slice(0, -2); 150 assert_equals(actualMarginLeft, expectedMarginLeft, prefix + "margin-left"); 151 } 152 153 var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right"); 154 if (expectedMarginRight) { 155 var actualMarginRight = getComputedStyle(node).marginRight; 156 // Trim the unit "px" from the output. 157 actualMarginRight = actualMarginRight.slice(0, -2); 158 assert_equals(actualMarginRight, expectedMarginRight, prefix + "margin-right"); 159 } 160 161 return output.checked; 162} 163 164var testNumber = 0; 165 166window.checkLayout = function(selectorList, callDone = true) 167{ 168 if (!selectorList) { 169 console.error("You must provide a CSS selector of nodes to check."); 170 return; 171 } 172 var nodes = document.querySelectorAll(selectorList); 173 nodes = Array.prototype.slice.call(nodes); 174 var checkedLayout = false; 175 Array.prototype.forEach.call(nodes, function(node) { 176 test(function(t) { 177 var container = node.parentNode.className == 'container' ? node.parentNode : node; 178 var prefix = "\n" + container.outerHTML + "\n"; 179 var passed = false; 180 try { 181 checkedLayout |= checkExpectedValues(t, node.parentNode, prefix); 182 checkedLayout |= checkSubtreeExpectedValues(t, node, prefix); 183 passed = true; 184 } finally { 185 checkedLayout |= !passed; 186 } 187 }, selectorList + ' ' + String(++testNumber)); 188 }); 189 if (!checkedLayout) { 190 console.error("No valid data-* attributes found in selector list : " + selectorList); 191 } 192 if (callDone) 193 done(); 194}; 195 196})(); 197