11cb0ef41Sopenharmony_ci(function() {
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_cifunction insertAfter(nodeToAdd, referenceNode)
41cb0ef41Sopenharmony_ci{
51cb0ef41Sopenharmony_ci    if (referenceNode == document.body) {
61cb0ef41Sopenharmony_ci        document.body.appendChild(nodeToAdd);
71cb0ef41Sopenharmony_ci        return;
81cb0ef41Sopenharmony_ci    }
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci    if (referenceNode.nextSibling)
111cb0ef41Sopenharmony_ci        referenceNode.parentNode.insertBefore(nodeToAdd, referenceNode.nextSibling);
121cb0ef41Sopenharmony_ci    else
131cb0ef41Sopenharmony_ci        referenceNode.parentNode.appendChild(nodeToAdd);
141cb0ef41Sopenharmony_ci}
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cifunction positionedAncestor(node)
171cb0ef41Sopenharmony_ci{
181cb0ef41Sopenharmony_ci    var ancestor = node.parentNode;
191cb0ef41Sopenharmony_ci    while (getComputedStyle(ancestor).position == 'static')
201cb0ef41Sopenharmony_ci        ancestor = ancestor.parentNode;
211cb0ef41Sopenharmony_ci    return ancestor;
221cb0ef41Sopenharmony_ci}
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_cifunction checkSubtreeExpectedValues(parent, failures)
251cb0ef41Sopenharmony_ci{
261cb0ef41Sopenharmony_ci    var checkedLayout = checkExpectedValues(parent, failures);
271cb0ef41Sopenharmony_ci    Array.prototype.forEach.call(parent.childNodes, function(node) {
281cb0ef41Sopenharmony_ci        checkedLayout |= checkSubtreeExpectedValues(node, failures);
291cb0ef41Sopenharmony_ci    });
301cb0ef41Sopenharmony_ci    return checkedLayout;
311cb0ef41Sopenharmony_ci}
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cifunction checkAttribute(output, node, attribute)
341cb0ef41Sopenharmony_ci{
351cb0ef41Sopenharmony_ci    var result = node.getAttribute && node.getAttribute(attribute);
361cb0ef41Sopenharmony_ci    output.checked |= !!result;
371cb0ef41Sopenharmony_ci    return result;
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_cifunction checkExpectedValues(node, failures)
411cb0ef41Sopenharmony_ci{
421cb0ef41Sopenharmony_ci    var output = { checked: false };
431cb0ef41Sopenharmony_ci    var expectedWidth = checkAttribute(output, node, "data-expected-width");
441cb0ef41Sopenharmony_ci    if (expectedWidth) {
451cb0ef41Sopenharmony_ci        if (isNaN(expectedWidth) || Math.abs(node.offsetWidth - expectedWidth) >= 1)
461cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedWidth + " for width, but got " + node.offsetWidth + ". ");
471cb0ef41Sopenharmony_ci    }
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci    var expectedHeight = checkAttribute(output, node, "data-expected-height");
501cb0ef41Sopenharmony_ci    if (expectedHeight) {
511cb0ef41Sopenharmony_ci        if (isNaN(expectedHeight) || Math.abs(node.offsetHeight - expectedHeight) >= 1)
521cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedHeight + " for height, but got " + node.offsetHeight + ". ");
531cb0ef41Sopenharmony_ci    }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci    var expectedOffset = checkAttribute(output, node, "data-offset-x");
561cb0ef41Sopenharmony_ci    if (expectedOffset) {
571cb0ef41Sopenharmony_ci        if (isNaN(expectedOffset) || Math.abs(node.offsetLeft - expectedOffset) >= 1)
581cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedOffset + " for offsetLeft, but got " + node.offsetLeft + ". ");
591cb0ef41Sopenharmony_ci    }
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci    var expectedOffset = checkAttribute(output, node, "data-offset-y");
621cb0ef41Sopenharmony_ci    if (expectedOffset) {
631cb0ef41Sopenharmony_ci        if (isNaN(expectedOffset) || Math.abs(node.offsetTop - expectedOffset) >= 1)
641cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedOffset + " for offsetTop, but got " + node.offsetTop + ". ");
651cb0ef41Sopenharmony_ci    }
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci    var expectedOffset = checkAttribute(output, node, "data-positioned-offset-x");
681cb0ef41Sopenharmony_ci    if (expectedOffset) {
691cb0ef41Sopenharmony_ci        var actualOffset = node.getBoundingClientRect().left - positionedAncestor(node).getBoundingClientRect().left;
701cb0ef41Sopenharmony_ci        if (isNaN(expectedOffset) || Math.abs(actualOffset - expectedOffset) >= 1)
711cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedOffset + " for getBoundingClientRect().left offset, but got " + actualOffset + ". ");
721cb0ef41Sopenharmony_ci    }
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci    var expectedOffset = checkAttribute(output, node, "data-positioned-offset-y");
751cb0ef41Sopenharmony_ci    if (expectedOffset) {
761cb0ef41Sopenharmony_ci        var actualOffset = node.getBoundingClientRect().top - positionedAncestor(node).getBoundingClientRect().top;
771cb0ef41Sopenharmony_ci        if (isNaN(expectedOffset) || Math.abs(actualOffset - expectedOffset) >= 1)
781cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedOffset + " for getBoundingClientRect().top offset, but got " + actualOffset + ". ");
791cb0ef41Sopenharmony_ci    }
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci    var expectedWidth = checkAttribute(output, node, "data-expected-client-width");
821cb0ef41Sopenharmony_ci    if (expectedWidth) {
831cb0ef41Sopenharmony_ci        if (isNaN(expectedWidth) || Math.abs(node.clientWidth - expectedWidth) >= 1)
841cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedWidth + " for clientWidth, but got " + node.clientWidth + ". ");
851cb0ef41Sopenharmony_ci    }
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci    var expectedHeight = checkAttribute(output, node, "data-expected-client-height");
881cb0ef41Sopenharmony_ci    if (expectedHeight) {
891cb0ef41Sopenharmony_ci        if (isNaN(expectedHeight) || Math.abs(node.clientHeight - expectedHeight) >= 1)
901cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedHeight + " for clientHeight, but got " + node.clientHeight + ". ");
911cb0ef41Sopenharmony_ci    }
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci    var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width");
941cb0ef41Sopenharmony_ci    if (expectedWidth) {
951cb0ef41Sopenharmony_ci        if (isNaN(expectedWidth) || Math.abs(node.scrollWidth - expectedWidth) >= 1)
961cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedWidth + " for scrollWidth, but got " + node.scrollWidth + ". ");
971cb0ef41Sopenharmony_ci    }
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci    var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height");
1001cb0ef41Sopenharmony_ci    if (expectedHeight) {
1011cb0ef41Sopenharmony_ci        if (isNaN(expectedHeight) || Math.abs(node.scrollHeight - expectedHeight) >= 1)
1021cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedHeight + " for scrollHeight, but got " + node.scrollHeight + ". ");
1031cb0ef41Sopenharmony_ci    }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci    var expectedOffset = checkAttribute(output, node, "data-total-x");
1061cb0ef41Sopenharmony_ci    if (expectedOffset) {
1071cb0ef41Sopenharmony_ci        var totalLeft = node.clientLeft + node.offsetLeft;
1081cb0ef41Sopenharmony_ci        if (isNaN(expectedOffset) || Math.abs(totalLeft - expectedOffset) >= 1)
1091cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedOffset + " for clientLeft+offsetLeft, but got " + totalLeft + ", clientLeft: " + node.clientLeft + ", offsetLeft: " + node.offsetLeft + ". ");
1101cb0ef41Sopenharmony_ci    }
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci    var expectedOffset = checkAttribute(output, node, "data-total-y");
1131cb0ef41Sopenharmony_ci    if (expectedOffset) {
1141cb0ef41Sopenharmony_ci        var totalTop = node.clientTop + node.offsetTop;
1151cb0ef41Sopenharmony_ci        if (isNaN(expectedOffset) || Math.abs(totalTop - expectedOffset) >= 1)
1161cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedOffset + " for clientTop+offsetTop, but got " + totalTop + ", clientTop: " + node.clientTop + ", + offsetTop: " + node.offsetTop + ". ");
1171cb0ef41Sopenharmony_ci    }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci    var expectedDisplay = checkAttribute(output, node, "data-expected-display");
1201cb0ef41Sopenharmony_ci    if (expectedDisplay) {
1211cb0ef41Sopenharmony_ci        var actualDisplay = getComputedStyle(node).display;
1221cb0ef41Sopenharmony_ci        if (actualDisplay != expectedDisplay)
1231cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedDisplay + " for display, but got " + actualDisplay + ". ");
1241cb0ef41Sopenharmony_ci    }
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci    var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top");
1271cb0ef41Sopenharmony_ci    if (expectedPaddingTop) {
1281cb0ef41Sopenharmony_ci        var actualPaddingTop = getComputedStyle(node).paddingTop;
1291cb0ef41Sopenharmony_ci        // Trim the unit "px" from the output.
1301cb0ef41Sopenharmony_ci        actualPaddingTop = actualPaddingTop.substring(0, actualPaddingTop.length - 2);
1311cb0ef41Sopenharmony_ci        if (actualPaddingTop != expectedPaddingTop)
1321cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedPaddingTop + " for padding-top, but got " + actualPaddingTop + ". ");
1331cb0ef41Sopenharmony_ci    }
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci    var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom");
1361cb0ef41Sopenharmony_ci    if (expectedPaddingBottom) {
1371cb0ef41Sopenharmony_ci        var actualPaddingBottom = getComputedStyle(node).paddingBottom;
1381cb0ef41Sopenharmony_ci        // Trim the unit "px" from the output.
1391cb0ef41Sopenharmony_ci        actualPaddingBottom = actualPaddingBottom.substring(0, actualPaddingBottom.length - 2);
1401cb0ef41Sopenharmony_ci        if (actualPaddingBottom != expectedPaddingBottom)
1411cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedPaddingBottom + " for padding-bottom, but got " + actualPaddingBottom + ". ");
1421cb0ef41Sopenharmony_ci    }
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci    var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left");
1451cb0ef41Sopenharmony_ci    if (expectedPaddingLeft) {
1461cb0ef41Sopenharmony_ci        var actualPaddingLeft = getComputedStyle(node).paddingLeft;
1471cb0ef41Sopenharmony_ci        // Trim the unit "px" from the output.
1481cb0ef41Sopenharmony_ci        actualPaddingLeft = actualPaddingLeft.substring(0, actualPaddingLeft.length - 2);
1491cb0ef41Sopenharmony_ci        if (actualPaddingLeft != expectedPaddingLeft)
1501cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedPaddingLeft + " for padding-left, but got " + actualPaddingLeft + ". ");
1511cb0ef41Sopenharmony_ci    }
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci    var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right");
1541cb0ef41Sopenharmony_ci    if (expectedPaddingRight) {
1551cb0ef41Sopenharmony_ci        var actualPaddingRight = getComputedStyle(node).paddingRight;
1561cb0ef41Sopenharmony_ci        // Trim the unit "px" from the output.
1571cb0ef41Sopenharmony_ci        actualPaddingRight = actualPaddingRight.substring(0, actualPaddingRight.length - 2);
1581cb0ef41Sopenharmony_ci        if (actualPaddingRight != expectedPaddingRight)
1591cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedPaddingRight + " for padding-right, but got " + actualPaddingRight + ". ");
1601cb0ef41Sopenharmony_ci    }
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci    var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top");
1631cb0ef41Sopenharmony_ci    if (expectedMarginTop) {
1641cb0ef41Sopenharmony_ci        var actualMarginTop = getComputedStyle(node).marginTop;
1651cb0ef41Sopenharmony_ci        // Trim the unit "px" from the output.
1661cb0ef41Sopenharmony_ci        actualMarginTop = actualMarginTop.substring(0, actualMarginTop.length - 2);
1671cb0ef41Sopenharmony_ci        if (actualMarginTop != expectedMarginTop)
1681cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedMarginTop + " for margin-top, but got " + actualMarginTop + ". ");
1691cb0ef41Sopenharmony_ci    }
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci    var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom");
1721cb0ef41Sopenharmony_ci    if (expectedMarginBottom) {
1731cb0ef41Sopenharmony_ci        var actualMarginBottom = getComputedStyle(node).marginBottom;
1741cb0ef41Sopenharmony_ci        // Trim the unit "px" from the output.
1751cb0ef41Sopenharmony_ci        actualMarginBottom = actualMarginBottom.substring(0, actualMarginBottom.length - 2);
1761cb0ef41Sopenharmony_ci        if (actualMarginBottom != expectedMarginBottom)
1771cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedMarginBottom + " for margin-bottom, but got " + actualMarginBottom + ". ");
1781cb0ef41Sopenharmony_ci    }
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci    var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left");
1811cb0ef41Sopenharmony_ci    if (expectedMarginLeft) {
1821cb0ef41Sopenharmony_ci        var actualMarginLeft = getComputedStyle(node).marginLeft;
1831cb0ef41Sopenharmony_ci        // Trim the unit "px" from the output.
1841cb0ef41Sopenharmony_ci        actualMarginLeft = actualMarginLeft.substring(0, actualMarginLeft.length - 2);
1851cb0ef41Sopenharmony_ci        if (actualMarginLeft != expectedMarginLeft)
1861cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedMarginLeft + " for margin-left, but got " + actualMarginLeft + ". ");
1871cb0ef41Sopenharmony_ci    }
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci    var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right");
1901cb0ef41Sopenharmony_ci    if (expectedMarginRight) {
1911cb0ef41Sopenharmony_ci        var actualMarginRight = getComputedStyle(node).marginRight;
1921cb0ef41Sopenharmony_ci        // Trim the unit "px" from the output.
1931cb0ef41Sopenharmony_ci        actualMarginRight = actualMarginRight.substring(0, actualMarginRight.length - 2);
1941cb0ef41Sopenharmony_ci        if (actualMarginRight != expectedMarginRight)
1951cb0ef41Sopenharmony_ci            failures.push("Expected " + expectedMarginRight + " for margin-right, but got " + actualMarginRight + ". ");
1961cb0ef41Sopenharmony_ci    }
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci    return output.checked;
1991cb0ef41Sopenharmony_ci}
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ciwindow.checkLayout = function(selectorList, outputContainer)
2021cb0ef41Sopenharmony_ci{
2031cb0ef41Sopenharmony_ci    var result = true;
2041cb0ef41Sopenharmony_ci    if (!selectorList) {
2051cb0ef41Sopenharmony_ci        document.body.appendChild(document.createTextNode("You must provide a CSS selector of nodes to check."));
2061cb0ef41Sopenharmony_ci        return;
2071cb0ef41Sopenharmony_ci    }
2081cb0ef41Sopenharmony_ci    var nodes = document.querySelectorAll(selectorList);
2091cb0ef41Sopenharmony_ci    nodes = Array.prototype.slice.call(nodes);
2101cb0ef41Sopenharmony_ci    nodes.reverse();
2111cb0ef41Sopenharmony_ci    var checkedLayout = false;
2121cb0ef41Sopenharmony_ci    Array.prototype.forEach.call(nodes, function(node) {
2131cb0ef41Sopenharmony_ci        var failures = [];
2141cb0ef41Sopenharmony_ci        checkedLayout |= checkExpectedValues(node.parentNode, failures);
2151cb0ef41Sopenharmony_ci        checkedLayout |= checkSubtreeExpectedValues(node, failures);
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci        var container = node.parentNode.className == 'container' ? node.parentNode : node;
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci        var pre = document.createElement('pre');
2201cb0ef41Sopenharmony_ci        if (failures.length) {
2211cb0ef41Sopenharmony_ci            pre.className = 'FAIL';
2221cb0ef41Sopenharmony_ci            result = false;
2231cb0ef41Sopenharmony_ci        }
2241cb0ef41Sopenharmony_ci        pre.appendChild(document.createTextNode(failures.length ? "FAIL:\n" + failures.join('\n') + '\n\n' + container.outerHTML : "PASS"));
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci        var referenceNode = container;
2271cb0ef41Sopenharmony_ci        if (outputContainer) {
2281cb0ef41Sopenharmony_ci            if (!outputContainer.lastChild) {
2291cb0ef41Sopenharmony_ci                // Inserting a text node so we have something to insertAfter.
2301cb0ef41Sopenharmony_ci                outputContainer.textContent = " ";
2311cb0ef41Sopenharmony_ci            }
2321cb0ef41Sopenharmony_ci            referenceNode = outputContainer.lastChild;
2331cb0ef41Sopenharmony_ci        }
2341cb0ef41Sopenharmony_ci        insertAfter(pre, referenceNode);
2351cb0ef41Sopenharmony_ci    });
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_ci    if (!checkedLayout) {
2381cb0ef41Sopenharmony_ci        document.body.appendChild(document.createTextNode("FAIL: No valid data-* attributes found in selector list : " + selectorList));
2391cb0ef41Sopenharmony_ci        return false;
2401cb0ef41Sopenharmony_ci    }
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci    return result;
2431cb0ef41Sopenharmony_ci}
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci})();
246