Index: Source/core/svg/SVGSVGElement.cpp |
diff --git a/Source/core/svg/SVGSVGElement.cpp b/Source/core/svg/SVGSVGElement.cpp |
index 6e407203f3d155a745ad9100436d685a0f559cd0..0de4dbd7f4c1f51af322eeb568ff88b43cefb261 100644 |
--- a/Source/core/svg/SVGSVGElement.cpp |
+++ b/Source/core/svg/SVGSVGElement.cpp |
@@ -258,24 +258,54 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString |
reportAttributeParsingError(parseError, name, value); |
} |
+bool SVGSVGElement::isPresentationAttribute(const QualifiedName& name) const |
+{ |
+ if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr)) |
+ return true; |
+ return SVGGraphicsElement::isPresentationAttribute(name); |
+} |
+ |
+void SVGSVGElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style) |
+{ |
+ if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr)) { |
+ RefPtr<SVGLength> length = SVGLength::create(LengthModeOther); |
+ length->setValueAsString(value, IGNORE_EXCEPTION); |
+ if (length->unitType() != LengthTypeUnknown) { |
+ if (name == SVGNames::widthAttr) |
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value); |
+ else if (name == SVGNames::heightAttr) |
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value); |
+ } |
+ } else { |
+ SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style); |
+ } |
+} |
+ |
void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName) |
{ |
bool updateRelativeLengthsOrViewBox = false; |
bool widthChanged = attrName == SVGNames::widthAttr; |
- if (widthChanged |
- || attrName == SVGNames::heightAttr |
+ bool heightChanged = attrName == SVGNames::heightAttr; |
+ if (widthChanged || heightChanged |
|| attrName == SVGNames::xAttr |
|| attrName == SVGNames::yAttr) { |
updateRelativeLengthsOrViewBox = true; |
updateRelativeLengthsInformation(); |
invalidateRelativeLengthClients(); |
- // At the SVG/HTML boundary (aka RenderSVGRoot), the width attribute can |
- // affect the replaced size so we need to mark it for updating. |
- if (widthChanged) { |
+ // At the SVG/HTML boundary (aka RenderSVGRoot), the width and |
+ // height attributes can affect the replaced size so we need |
+ // to mark it for updating. |
+ // |
+ // FIXME: For width/height animated as XML attributes on SVG |
+ // roots, there is an attribute synchronization missing. See |
+ // http://crbug.com/364807 |
+ if (widthChanged || heightChanged) { |
RenderObject* renderObject = renderer(); |
- if (renderObject && renderObject->isSVGRoot()) |
- toRenderSVGRoot(renderObject)->setNeedsLayoutAndPrefWidthsRecalc(); |
+ if (renderObject && renderObject->isSVGRoot()) { |
+ invalidateSVGPresentationAttributeStyle(); |
+ setNeedsStyleRecalc(LocalStyleChange); |
+ } |
} |
} |
@@ -595,22 +625,18 @@ FloatRect SVGSVGElement::currentViewBoxRect() const |
if (!toRenderSVGRoot(renderer())->isEmbeddedThroughSVGImage()) |
return FloatRect(); |
- Length intrinsicWidth = this->intrinsicWidth(); |
- Length intrinsicHeight = this->intrinsicHeight(); |
- if (!intrinsicWidth.isFixed() || !intrinsicHeight.isFixed()) |
- return FloatRect(); |
- |
// If no viewBox is specified but non-relative width/height values, then we |
// should always synthesize a viewBox if we're embedded through a SVGImage. |
- return FloatRect(FloatPoint(), FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0))); |
+ return FloatRect(FloatPoint(), FloatSize(floatValueForLength(intrinsicWidth(), 0), floatValueForLength(intrinsicHeight(), 0))); |
} |
FloatSize SVGSVGElement::currentViewportSize() const |
{ |
- Length intrinsicWidth = this->intrinsicWidth(); |
- Length intrinsicHeight = this->intrinsicHeight(); |
- if (intrinsicWidth.isFixed() && intrinsicHeight.isFixed()) |
+ if (hasIntrinsicWidth() && hasIntrinsicHeight()) { |
+ Length intrinsicWidth = this->intrinsicWidth(); |
+ Length intrinsicHeight = this->intrinsicHeight(); |
return FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0)); |
+ } |
if (!renderer()) |
return FloatSize(); |
@@ -624,80 +650,32 @@ FloatSize SVGSVGElement::currentViewportSize() const |
return FloatSize(viewportRect.width(), viewportRect.height()); |
} |
-bool SVGSVGElement::widthAttributeEstablishesViewport() const |
+bool SVGSVGElement::hasIntrinsicWidth() const |
{ |
- if (!renderer() || renderer()->isSVGViewportContainer()) |
- return true; |
- |
- // Spec: http://www.w3.org/TR/SVG/coords.html#ViewportSpace |
- // The ‘width’ attribute on the outermost svg element establishes the viewport's width, unless the following conditions are met: |
- // - the SVG content is a separately stored resource that is embedded by reference (such as the ‘object’ element in XHTML [XHTML]), or |
- // the SVG content is embedded inline within a containing document; |
- // - and the referencing element or containing document is styled using CSS [CSS2] or XSL [XSL]; |
- // - and there are CSS-compatible positioning properties ([CSS2], section 9.3) specified on the referencing element (e.g., the ‘object’ element) |
- // or on the containing document's outermost svg element that are sufficient to establish the width of the viewport. Under these conditions, |
- // the positioning properties establish the viewport's width. |
- RenderSVGRoot* root = toRenderSVGRoot(renderer()); |
- |
- // SVG embedded through object/embed/iframe. |
- if (root->isEmbeddedThroughFrameContainingSVGDocument()) |
- return !root->hasReplacedLogicalWidth() && !document().frame()->ownerRenderer()->hasReplacedLogicalWidth(); |
- |
- // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG. |
- if (root->isEmbeddedThroughSVGImage() || document().documentElement() != this) |
- return !root->hasReplacedLogicalWidth(); |
- |
- return true; |
+ return width()->currentValue()->unitType() != LengthTypePercentage; |
} |
-bool SVGSVGElement::heightAttributeEstablishesViewport() const |
+bool SVGSVGElement::hasIntrinsicHeight() const |
{ |
- if (!renderer() || renderer()->isSVGViewportContainer()) |
- return true; |
- |
- // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing |
- // Similarly, if there are positioning properties specified on the referencing element or on the outermost svg element |
- // that are sufficient to establish the height of the viewport, then these positioning properties establish the viewport's |
- // height; otherwise, the ‘height’ attribute on the outermost svg element establishes the viewport's height. |
- RenderSVGRoot* root = toRenderSVGRoot(renderer()); |
- |
- // SVG embedded through object/embed/iframe. |
- if (root->isEmbeddedThroughFrameContainingSVGDocument()) |
- return !root->hasReplacedLogicalHeight() && !document().frame()->ownerRenderer()->hasReplacedLogicalHeight(); |
- |
- // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG. |
- if (root->isEmbeddedThroughSVGImage() || document().documentElement() != this) |
- return !root->hasReplacedLogicalHeight(); |
- |
- return true; |
+ return height()->currentValue()->unitType() != LengthTypePercentage; |
} |
-Length SVGSVGElement::intrinsicWidth(ConsiderCSSMode mode) const |
+Length SVGSVGElement::intrinsicWidth() const |
{ |
- if (widthAttributeEstablishesViewport() || mode == IgnoreCSSProperties) { |
- if (m_width->currentValue()->unitType() == LengthTypePercentage) |
- return Length(m_width->currentValue()->valueAsPercentage() * 100, Percent); |
- |
- SVGLengthContext lengthContext(this); |
- return Length(m_width->currentValue()->value(lengthContext), Fixed); |
- } |
+ if (width()->currentValue()->unitType() == LengthTypePercentage) |
+ return Length(0, Fixed); |
- ASSERT(renderer()); |
- return renderer()->style()->width(); |
+ SVGLengthContext lengthContext(this); |
+ return Length(width()->currentValue()->value(lengthContext), Fixed); |
} |
-Length SVGSVGElement::intrinsicHeight(ConsiderCSSMode mode) const |
+Length SVGSVGElement::intrinsicHeight() const |
{ |
- if (heightAttributeEstablishesViewport() || mode == IgnoreCSSProperties) { |
- if (m_height->currentValue()->unitType() == LengthTypePercentage) |
- return Length(m_height->currentValue()->valueAsPercentage() * 100, Percent); |
- |
- SVGLengthContext lengthContext(this); |
- return Length(m_height->currentValue()->value(lengthContext), Fixed); |
- } |
+ if (height()->currentValue()->unitType() == LengthTypePercentage) |
+ return Length(0, Fixed); |
- ASSERT(renderer()); |
- return renderer()->style()->height(); |
+ SVGLengthContext lengthContext(this); |
+ return Length(height()->currentValue()->value(lengthContext), Fixed); |
} |
AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const |