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/rendering/svg/RenderSVGForeignObject.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(LengthModeWidth), AllowNegativeLengths))
35 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
36 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
37 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), 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_NODE_FACTORY(SVGForeignObjectElement)
49 bool SVGForeignObjectElement::isSupportedAttribute(const QualifiedName& attrName)
51 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
52 if (supportedAttributes.isEmpty()) {
53 supportedAttributes.add(SVGNames::xAttr);
54 supportedAttributes.add(SVGNames::yAttr);
55 supportedAttributes.add(SVGNames::widthAttr);
56 supportedAttributes.add(SVGNames::heightAttr);
58 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
61 void SVGForeignObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
63 parseAttributeNew(name, value);
66 bool SVGForeignObjectElement::isPresentationAttribute(const QualifiedName& name) const
68 if (name == SVGNames::widthAttr || name == SVGNames::heightAttr)
70 return SVGGraphicsElement::isPresentationAttribute(name);
73 void SVGForeignObjectElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
75 if (name == SVGNames::widthAttr || name == SVGNames::heightAttr) {
76 RefPtr<SVGLength> length = SVGLength::create(LengthModeOther);
77 TrackExceptionState exceptionState;
78 length->setValueAsString(value, exceptionState);
79 if (!exceptionState.hadException()) {
80 if (name == SVGNames::widthAttr)
81 addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value);
82 else if (name == SVGNames::heightAttr)
83 addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value);
86 SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
90 void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
92 if (!isSupportedAttribute(attrName)) {
93 SVGGraphicsElement::svgAttributeChanged(attrName);
97 if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) {
98 invalidateSVGPresentationAttributeStyle();
99 setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::SVGContainerSizeChange));
102 SVGElement::InvalidationGuard invalidationGuard(this);
104 bool isLengthAttribute = attrName == SVGNames::xAttr
105 || attrName == SVGNames::yAttr
106 || attrName == SVGNames::widthAttr
107 || attrName == SVGNames::heightAttr;
109 if (isLengthAttribute) {
110 updateRelativeLengthsInformation();
111 if (RenderObject* renderer = this->renderer())
112 markForLayoutAndParentResourceInvalidation(renderer);
116 RenderObject* SVGForeignObjectElement::createRenderer(RenderStyle*)
118 return new RenderSVGForeignObject(this);
121 bool SVGForeignObjectElement::rendererIsNeeded(const RenderStyle& style)
123 // Suppress foreignObject renderers in SVG hidden containers.
124 // (https://bugs.webkit.org/show_bug.cgi?id=87297)
125 // Note that we currently do not support foreignObject instantiation via <use>, hence it is safe
126 // to use parentElement() here. If that changes, this method should be updated to use
127 // parentOrShadowHostElement() instead.
128 Element* ancestor = parentElement();
129 while (ancestor && ancestor->isSVGElement()) {
130 if (ancestor->renderer() && ancestor->renderer()->isSVGHiddenContainer())
133 ancestor = ancestor->parentElement();
136 return SVGGraphicsElement::rendererIsNeeded(style);
139 bool SVGForeignObjectElement::selfHasRelativeLengths() const
141 return m_x->currentValue()->isRelative()
142 || m_y->currentValue()->isRelative()
143 || m_width->currentValue()->isRelative()
144 || m_height->currentValue()->isRelative();