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.
24
#include "SVGForeignObjectElement.h"
26
#include "Attribute.h"
27
#include "CSSPropertyNames.h"
28
#include "NodeRenderingContext.h"
29
#include "RenderSVGForeignObject.h"
30
#include "RenderSVGResource.h"
31
#include "SVGElementInstance.h"
32
#include "SVGLength.h"
34
#include <wtf/Assertions.h>
38
// Animated property definitions
39
DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::xAttr, X, x)
40
DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::yAttr, Y, y)
41
DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::widthAttr, Width, width)
42
DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::heightAttr, Height, height)
43
DEFINE_ANIMATED_STRING(SVGForeignObjectElement, XLinkNames::hrefAttr, Href, href)
44
DEFINE_ANIMATED_BOOLEAN(SVGForeignObjectElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
46
BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGForeignObjectElement)
47
REGISTER_LOCAL_ANIMATED_PROPERTY(x)
48
REGISTER_LOCAL_ANIMATED_PROPERTY(y)
49
REGISTER_LOCAL_ANIMATED_PROPERTY(width)
50
REGISTER_LOCAL_ANIMATED_PROPERTY(height)
51
REGISTER_LOCAL_ANIMATED_PROPERTY(href)
52
REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
53
REGISTER_PARENT_ANIMATED_PROPERTIES(SVGStyledTransformableElement)
54
REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
55
END_REGISTER_ANIMATED_PROPERTIES
57
inline SVGForeignObjectElement::SVGForeignObjectElement(const QualifiedName& tagName, Document* document)
58
: SVGStyledTransformableElement(tagName, document)
59
, m_x(LengthModeWidth)
60
, m_y(LengthModeHeight)
61
, m_width(LengthModeWidth)
62
, m_height(LengthModeHeight)
64
ASSERT(hasTagName(SVGNames::foreignObjectTag));
65
registerAnimatedPropertiesForSVGForeignObjectElement();
68
PassRefPtr<SVGForeignObjectElement> SVGForeignObjectElement::create(const QualifiedName& tagName, Document* document)
70
return adoptRef(new SVGForeignObjectElement(tagName, document));
73
bool SVGForeignObjectElement::isSupportedAttribute(const QualifiedName& attrName)
75
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
76
if (supportedAttributes.isEmpty()) {
77
SVGTests::addSupportedAttributes(supportedAttributes);
78
SVGLangSpace::addSupportedAttributes(supportedAttributes);
79
SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
80
supportedAttributes.add(SVGNames::xAttr);
81
supportedAttributes.add(SVGNames::yAttr);
82
supportedAttributes.add(SVGNames::widthAttr);
83
supportedAttributes.add(SVGNames::heightAttr);
85
return supportedAttributes.contains<QualifiedName, SVGAttributeHashTranslator>(attrName);
88
void SVGForeignObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
90
SVGParsingError parseError = NoError;
92
if (!isSupportedAttribute(name))
93
SVGStyledTransformableElement::parseAttribute(name, value);
94
else if (name == SVGNames::xAttr)
95
setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
96
else if (name == SVGNames::yAttr)
97
setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
98
else if (name == SVGNames::widthAttr)
99
setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
100
else if (name == SVGNames::heightAttr)
101
setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
102
else if (SVGTests::parseAttribute(name, value)
103
|| SVGLangSpace::parseAttribute(name, value)
104
|| SVGExternalResourcesRequired::parseAttribute(name, value)) {
106
ASSERT_NOT_REACHED();
108
reportAttributeParsingError(parseError, name, value);
111
void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
113
if (!isSupportedAttribute(attrName)) {
114
SVGStyledTransformableElement::svgAttributeChanged(attrName);
118
SVGElementInstance::InvalidationGuard invalidationGuard(this);
120
bool isLengthAttribute = attrName == SVGNames::xAttr
121
|| attrName == SVGNames::yAttr
122
|| attrName == SVGNames::widthAttr
123
|| attrName == SVGNames::heightAttr;
125
if (isLengthAttribute)
126
updateRelativeLengthsInformation();
128
if (SVGTests::handleAttributeChange(this, attrName))
131
if (RenderObject* renderer = this->renderer())
132
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
135
RenderObject* SVGForeignObjectElement::createRenderer(RenderArena* arena, RenderStyle*)
137
return new (arena) RenderSVGForeignObject(this);
140
bool SVGForeignObjectElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
142
// Disallow arbitary SVG content. Only allow proper <svg xmlns="svgNS"> subdocuments.
143
if (childContext.node()->isSVGElement())
144
return childContext.node()->hasTagName(SVGNames::svgTag);
146
// Skip over SVG rules which disallow non-SVG kids
147
return StyledElement::childShouldCreateRenderer(childContext);
150
bool SVGForeignObjectElement::rendererIsNeeded(const NodeRenderingContext& context)
152
// Suppress foreignObject renderers in SVG hidden containers.
153
// (https://bugs.webkit.org/show_bug.cgi?id=87297)
154
// Note that we currently do not support foreignObject instantiation via <use>, hence it is safe
155
// to use parentElement() here. If that changes, this method should be updated to use
156
// parentOrHostElement() instead.
157
Element* ancestor = parentElement();
158
while (ancestor && ancestor->isSVGElement()) {
159
if (ancestor->renderer() && ancestor->renderer()->isSVGHiddenContainer())
162
ancestor = ancestor->parentElement();
165
return SVGStyledTransformableElement::rendererIsNeeded(context);
168
bool SVGForeignObjectElement::selfHasRelativeLengths() const
170
return x().isRelative()
172
|| width().isRelative()
173
|| height().isRelative();