chromium/third_party/blink/web_tests/paint/invalidation/svg/svg-layout-root-style-attr-update.html

<!DOCTYPE html>
<body style="overflow:hidden" onload="test()">
<div id="other"> </div>
<div>
  <div style="position:absolute; top: 0px; overflow:hidden; width:500px; height:500px;" id="grandparent">
    <div style="position:absolute; top: 0px; overflow:hidden; width:500px; height:500px;" id="root">
    </div>
  </div>
</div>
<script type="text/javascript">
function test() {
    // create some SVG
    var svgroot = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    svgroot.setAttribute("width", "100%");
    svgroot.setAttribute("height", "100%");
    document.getElementById("root").appendChild(svgroot);
    // add a red rectangle that will be covered up by the green rectangle
    var redRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    redRect.setAttribute("fill", "red");
    redRect.setAttribute("x", "50%");
    redRect.setAttribute("y", "10");
    redRect.setAttribute("width", "50%");
    redRect.setAttribute("height", "50%");
    svgroot.style.position = "absolute";
    svgroot.style.top="0px";
    svgroot.appendChild(redRect);
    // add a green rectangle to the left of the red one
    var greenRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    greenRect.setAttribute("fill", "green");
    greenRect.setAttribute("x", "0%");
    greenRect.setAttribute("y", "10");
    greenRect.setAttribute("width", "50%");
    svgroot.appendChild(greenRect);
    document.body.offsetLeft;
    // dirty an SVG attribute
    greenRect.setAttribute("height", "50%");
    // make sure the svg root's .style attribute is out of date
    svgroot.style.position = "absolute";
    // force layout. this will be rooted at the LayoutSVGRoot and will set m_posChildNeedsLayout on its
    // containing LayoutBlockFlow (corresponding to DIV#root)
    document.body.offsetWidth;
    // dirty an SVG attribute, will set FrameView::m_layoutRoot to the LayoutSVGRoot
    greenRect.setAttribute("width", "50%");
    // dirty a normal DOM attribute in a separate part of the DOM.  this is where things go awry since
    // FrameView::scheduleRelayoutOfSubtree will clear out its m_layoutRoot and call
    // LayoutObject::markContainingBlocksForLayout() on the LayoutSVGRoot.  Since the LayoutSVGRoot's
    // container already has m_posChildNeedsLayout set, the LayoutSVGRoot's container's container
    // (corresponding to the DIV#grandparent) will not have any needs layout flags set on it.
    document.getElementById('other').style.width="500px";
    // Run a layout pass.  This will propagate the render tree up to the DIV#other's render object but
    // will not traverse into the svg subtree at all since the DIV#grandparent's render object is
    // not marked as needing layout.
    document.body.offsetWidth;
    // This goes into the void since the LayoutSVGRoot is already marked as needsLayout but there is no
    // layout pending.
    greenRect.setAttribute("x", "50%");
}
</script>
</body>