2 * Copyright (C) 2006 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
22 #include "core/svg/SVGForeignObjectElement.h"
24 #include "core/XLinkNames.h"
25 #include "core/frame/UseCounter.h"
26 #include "core/layout/svg/LayoutSVGForeignObject.h"
27 #include "core/svg/SVGLength.h"
28 #include "wtf/Assertions.h"
32 inline SVGForeignObjectElement::SVGForeignObjectElement(Document
& document
)
33 : SVGGraphicsElement(SVGNames::foreignObjectTag
, document
)
34 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr
, SVGLength::create(SVGLengthMode::Width
), AllowNegativeLengths
))
35 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr
, SVGLength::create(SVGLengthMode::Height
), AllowNegativeLengths
))
36 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr
, SVGLength::create(SVGLengthMode::Width
), ForbidNegativeLengths
))
37 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr
, SVGLength::create(SVGLengthMode::Height
), ForbidNegativeLengths
))
39 addToPropertyMap(m_x
);
40 addToPropertyMap(m_y
);
41 addToPropertyMap(m_width
);
42 addToPropertyMap(m_height
);
44 UseCounter::count(document
, UseCounter::SVGForeignObjectElement
);
47 DEFINE_TRACE(SVGForeignObjectElement
)
51 visitor
->trace(m_width
);
52 visitor
->trace(m_height
);
53 SVGGraphicsElement::trace(visitor
);
56 DEFINE_NODE_FACTORY(SVGForeignObjectElement
)
58 bool SVGForeignObjectElement::isPresentationAttribute(const QualifiedName
& name
) const
60 if (name
== SVGNames::xAttr
|| name
== SVGNames::yAttr
61 || name
== SVGNames::widthAttr
|| name
== SVGNames::heightAttr
)
63 return SVGGraphicsElement::isPresentationAttribute(name
);
66 bool SVGForeignObjectElement::isPresentationAttributeWithSVGDOM(const QualifiedName
& attrName
) const
68 if (attrName
== SVGNames::xAttr
|| attrName
== SVGNames::yAttr
69 || attrName
== SVGNames::widthAttr
|| attrName
== SVGNames::heightAttr
)
71 return SVGGraphicsElement::isPresentationAttributeWithSVGDOM(attrName
);
74 void SVGForeignObjectElement::collectStyleForPresentationAttribute(const QualifiedName
& name
, const AtomicString
& value
, MutableStylePropertySet
* style
)
76 RefPtrWillBeRawPtr
<SVGAnimatedPropertyBase
> property
= propertyFromAttribute(name
);
77 if (property
== m_width
)
78 addSVGLengthPropertyToPresentationAttributeStyle(style
, CSSPropertyWidth
, *m_width
->currentValue());
79 else if (property
== m_height
)
80 addSVGLengthPropertyToPresentationAttributeStyle(style
, CSSPropertyHeight
, *m_height
->currentValue());
81 else if (property
== m_x
)
82 addSVGLengthPropertyToPresentationAttributeStyle(style
, CSSPropertyX
, *m_x
->currentValue());
83 else if (property
== m_y
)
84 addSVGLengthPropertyToPresentationAttributeStyle(style
, CSSPropertyY
, *m_y
->currentValue());
86 SVGGraphicsElement::collectStyleForPresentationAttribute(name
, value
, style
);
89 void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName
& attrName
)
91 bool isWidthHeightAttribute
= attrName
== SVGNames::widthAttr
92 || attrName
== SVGNames::heightAttr
;
93 bool isXYAttribute
= attrName
== SVGNames::xAttr
|| attrName
== SVGNames::yAttr
;
95 if (isXYAttribute
|| isWidthHeightAttribute
) {
96 SVGElement::InvalidationGuard
invalidationGuard(this);
98 invalidateSVGPresentationAttributeStyle();
99 setNeedsStyleRecalc(LocalStyleChange
,
100 isWidthHeightAttribute
? StyleChangeReasonForTracing::create(StyleChangeReason::SVGContainerSizeChange
) : StyleChangeReasonForTracing::fromAttribute(attrName
));
102 updateRelativeLengthsInformation();
103 if (LayoutObject
* layoutObject
= this->layoutObject())
104 markForLayoutAndParentResourceInvalidation(layoutObject
);
109 SVGGraphicsElement::svgAttributeChanged(attrName
);
112 LayoutObject
* SVGForeignObjectElement::createLayoutObject(const ComputedStyle
&)
114 return new LayoutSVGForeignObject(this);
117 bool SVGForeignObjectElement::layoutObjectIsNeeded(const ComputedStyle
& style
)
119 // Suppress foreignObject layoutObjects in SVG hidden containers.
120 // (https://bugs.webkit.org/show_bug.cgi?id=87297)
121 // Note that we currently do not support foreignObject instantiation via <use>, hence it is safe
122 // to use parentElement() here. If that changes, this method should be updated to use
123 // parentOrShadowHostElement() instead.
124 Element
* ancestor
= parentElement();
125 while (ancestor
&& ancestor
->isSVGElement()) {
126 if (ancestor
->layoutObject() && ancestor
->layoutObject()->isSVGHiddenContainer())
129 ancestor
= ancestor
->parentElement();
132 return SVGGraphicsElement::layoutObjectIsNeeded(style
);
135 bool SVGForeignObjectElement::selfHasRelativeLengths() const
137 return m_x
->currentValue()->isRelative()
138 || m_y
->currentValue()->isRelative()
139 || m_width
->currentValue()->isRelative()
140 || m_height
->currentValue()->isRelative();