Bug 1548985: Don't let 'contain:size' suppress the intrinsic size of document-root SVG elements. r=TYLin

Differential Revision: https://phabricator.services.mozilla.com/D30259

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Daniel Holbert 2019-05-08 23:05:04 +00:00
parent 0e4063bd7b
commit d4b5b44718
4 changed files with 36 additions and 3 deletions

View File

@ -0,0 +1,16 @@
<!-- a -->
<style>
:root { contain: size }
</style>
<script>
window.requestIdleCallback(window.close)
function go() {
a.appendChild(document.head)
let b = d.getRootNode({composed: true})
b.replaceChild(c, b.childNodes[1])
}
</script>
<body onload=go()>
<svg id="c">
<feTile id="d" />
<foreignObject id="a">

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg"
style="contain:size">
<rect width="100px" height="100px" fill="lime"/>
</svg>

After

Width:  |  Height:  |  Size: 125 B

View File

@ -227,3 +227,5 @@ load 1504072.html
load 1072758.html
load 1536892.html
load 1539318-1.svg
load 1548985-1.html
load 1548985-2.svg

View File

@ -89,6 +89,17 @@ static inline bool DependsOnIntrinsicSize(const nsIFrame* aEmbeddingFrame) {
return !width.ConvertsToLength() || !height.ConvertsToLength();
}
// The CSS Containment spec says that size-contained replaced elements must be
// treated as having an intrinsic width and height of 0. That's applicable to
// outer SVG frames, unless they're the outermost element (in which case
// they're not really "replaced", and there's no outer context to contain sizes
// from leaking into). Hence, we check for a parent element before we bother
// testing for 'contain:size'.
static inline bool IsReplacedAndContainSize(const nsSVGOuterSVGFrame* aFrame) {
return aFrame->GetContent()->GetParent() &&
aFrame->StyleDisplay()->IsContainSize();
}
void nsSVGOuterSVGFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) {
NS_ASSERTION(aContent->IsSVGElement(nsGkAtoms::svg),
@ -168,7 +179,7 @@ nscoord nsSVGOuterSVGFrame::GetPrefISize(gfxContext* aRenderingContext) {
wm.IsVertical() ? svg->mLengthAttributes[SVGSVGElement::ATTR_HEIGHT]
: svg->mLengthAttributes[SVGSVGElement::ATTR_WIDTH];
if (StyleDisplay()->IsContainSize()) {
if (IsReplacedAndContainSize(this)) {
result = nscoord(0);
} else if (isize.IsPercentage()) {
// It looks like our containing block's isize may depend on our isize. In
@ -205,7 +216,7 @@ IntrinsicSize nsSVGOuterSVGFrame::GetIntrinsicSize() {
// XXXjwatt Note that here we want to return the CSS width/height if they're
// specified and we're embedded inside an nsIObjectLoadingContent.
if (StyleDisplay()->IsContainSize()) {
if (IsReplacedAndContainSize(this)) {
// Intrinsic size of 'contain:size' replaced elements is 0,0.
return IntrinsicSize(0, 0);
}
@ -235,7 +246,7 @@ IntrinsicSize nsSVGOuterSVGFrame::GetIntrinsicSize() {
/* virtual */
AspectRatio nsSVGOuterSVGFrame::GetIntrinsicRatio() {
if (StyleDisplay()->IsContainSize()) {
if (IsReplacedAndContainSize(this)) {
return AspectRatio();
}