LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const { SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); ASSERT(svg); // When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size. if (!m_containerSize.isEmpty()) return m_containerSize.height(); if (hasReplacedLogicalHeight()) return RenderReplaced::computeReplacedLogicalHeight(); if (svg->heightAttributeEstablishesViewport()) { Length height = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties); if (height.isPercent()) { RenderBlock* cb = containingBlock(); ASSERT(cb); while (cb->isAnonymous()) { cb = cb->containingBlock(); cb->addPercentHeightDescendant(const_cast<RenderSVGRoot*>(this)); } } else RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this)); return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), containingBlock()->availableLogicalHeight()); } // Only SVGs embedded in <object> reach this point. ASSERT(isEmbeddedThroughFrameContainingSVGDocument()); return document()->frame()->ownerRenderer()->availableLogicalHeight(); }
LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const { // When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size. if (!m_containerSize.isEmpty()) return m_containerSize.height(); if (style()->logicalHeight().isSpecified() || style()->logicalMaxHeight().isSpecified()) return RenderReplaced::computeReplacedLogicalHeight(); if (svgSVGElement().heightAttributeEstablishesViewport()) { Length height = svgSVGElement().intrinsicHeight(SVGSVGElement::IgnoreCSSProperties); if (height.isPercent()) { RenderBlock* cb = containingBlock(); ASSERT(cb); while (cb->isAnonymous() && !cb->isRenderView()) { cb = cb->containingBlock(); cb->addPercentHeightDescendant(const_cast<RenderSVGRoot&>(*this)); } } else RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot&>(*this)); return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding), &view()); } // SVG embedded through object/embed/iframe. if (isEmbeddedThroughFrameContainingSVGDocument()) return frame().ownerRenderer()->availableLogicalHeight(IncludeMarginBorderPadding); // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG. return RenderReplaced::computeReplacedLogicalHeight(); }
bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const { Length logicalHeightLength = style()->logicalHeight(); if (logicalHeightLength.isAuto()) return true; // For percentage heights: The percentage is calculated with respect to the height of the generated box's // containing block. If the height of the containing block is not specified explicitly (i.e., it depends // on content height), and this element is not absolutely positioned, the value computes to 'auto'. if (!logicalHeightLength.isPercent() || isOutOfFlowPositioned() || document().inQuirksMode()) return false; // Anonymous block boxes are ignored when resolving percentage values that would refer to it: // the closest non-anonymous ancestor box is used instead. RenderBlock* cb = containingBlock(); while (cb->isAnonymous()) cb = cb->containingBlock(); // Matching RenderBox::percentageLogicalHeightIsResolvableFromBlock() by // ignoring table cell's attribute value, where it says that table cells violate // what the CSS spec says to do with heights. Basically we // don't care if the cell specified a height or not. if (cb->isTableCell()) return false; // Match RenderBox::availableLogicalHeightUsing by special casing // the render view. The available height is taken from the frame. if (cb->isRenderView()) return false; if (cb->isOutOfFlowPositioned() && !cb->style()->logicalTop().isAuto() && !cb->style()->logicalBottom().isAuto()) return false; // If the height of the containing block computes to 'auto', then it hasn't been 'specified explicitly'. return cb->hasAutoHeightOrContainingBlockWithAutoHeight(); }