1/* 2 * Copyright (C) 2006 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 4 * 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. 9 * 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. 14 * 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. 19 */ 20 21#include "config.h" 22#include "core/svg/SVGForeignObjectElement.h" 23 24#include "XLinkNames.h" 25#include "core/rendering/svg/RenderSVGForeignObject.h" 26#include "core/rendering/svg/RenderSVGResource.h" 27#include "core/svg/SVGElementInstance.h" 28#include "core/svg/SVGLength.h" 29#include "wtf/Assertions.h" 30 31namespace WebCore { 32 33// Animated property definitions 34DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::xAttr, X, x) 35DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::yAttr, Y, y) 36DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::widthAttr, Width, width) 37DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::heightAttr, Height, height) 38DEFINE_ANIMATED_STRING(SVGForeignObjectElement, XLinkNames::hrefAttr, Href, href) 39DEFINE_ANIMATED_BOOLEAN(SVGForeignObjectElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 40 41BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGForeignObjectElement) 42 REGISTER_LOCAL_ANIMATED_PROPERTY(x) 43 REGISTER_LOCAL_ANIMATED_PROPERTY(y) 44 REGISTER_LOCAL_ANIMATED_PROPERTY(width) 45 REGISTER_LOCAL_ANIMATED_PROPERTY(height) 46 REGISTER_LOCAL_ANIMATED_PROPERTY(href) 47 REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired) 48 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement) 49END_REGISTER_ANIMATED_PROPERTIES 50 51inline SVGForeignObjectElement::SVGForeignObjectElement(Document& document) 52 : SVGGraphicsElement(SVGNames::foreignObjectTag, document) 53 , m_x(LengthModeWidth) 54 , m_y(LengthModeHeight) 55 , m_width(LengthModeWidth) 56 , m_height(LengthModeHeight) 57{ 58 ScriptWrappable::init(this); 59 registerAnimatedPropertiesForSVGForeignObjectElement(); 60} 61 62PassRefPtr<SVGForeignObjectElement> SVGForeignObjectElement::create(Document& document) 63{ 64 return adoptRef(new SVGForeignObjectElement(document)); 65} 66 67bool SVGForeignObjectElement::isSupportedAttribute(const QualifiedName& attrName) 68{ 69 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 70 if (supportedAttributes.isEmpty()) { 71 SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); 72 supportedAttributes.add(SVGNames::xAttr); 73 supportedAttributes.add(SVGNames::yAttr); 74 supportedAttributes.add(SVGNames::widthAttr); 75 supportedAttributes.add(SVGNames::heightAttr); 76 } 77 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 78} 79 80void SVGForeignObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 81{ 82 SVGParsingError parseError = NoError; 83 84 if (!isSupportedAttribute(name)) 85 SVGGraphicsElement::parseAttribute(name, value); 86 else if (name == SVGNames::xAttr) 87 setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); 88 else if (name == SVGNames::yAttr) 89 setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); 90 else if (name == SVGNames::widthAttr) 91 setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); 92 else if (name == SVGNames::heightAttr) 93 setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); 94 else if (SVGExternalResourcesRequired::parseAttribute(name, value)) { 95 } else 96 ASSERT_NOT_REACHED(); 97 98 reportAttributeParsingError(parseError, name, value); 99} 100 101void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) 102{ 103 if (!isSupportedAttribute(attrName)) { 104 SVGGraphicsElement::svgAttributeChanged(attrName); 105 return; 106 } 107 108 SVGElementInstance::InvalidationGuard invalidationGuard(this); 109 110 bool isLengthAttribute = attrName == SVGNames::xAttr 111 || attrName == SVGNames::yAttr 112 || attrName == SVGNames::widthAttr 113 || attrName == SVGNames::heightAttr; 114 115 if (isLengthAttribute) 116 updateRelativeLengthsInformation(); 117 118 if (RenderObject* renderer = this->renderer()) 119 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 120} 121 122RenderObject* SVGForeignObjectElement::createRenderer(RenderStyle*) 123{ 124 return new RenderSVGForeignObject(this); 125} 126 127bool SVGForeignObjectElement::childShouldCreateRenderer(const Node& child) const 128{ 129 // Disallow arbitary SVG content. Only allow proper <svg xmlns="svgNS"> subdocuments. 130 if (child.isSVGElement()) 131 return child.hasTagName(SVGNames::svgTag); 132 133 // Skip over SVG rules which disallow non-SVG kids 134 return Element::childShouldCreateRenderer(child); 135} 136 137bool SVGForeignObjectElement::rendererIsNeeded(const RenderStyle& style) 138{ 139 // Suppress foreignObject renderers in SVG hidden containers. 140 // (https://bugs.webkit.org/show_bug.cgi?id=87297) 141 // Note that we currently do not support foreignObject instantiation via <use>, hence it is safe 142 // to use parentElement() here. If that changes, this method should be updated to use 143 // parentOrShadowHostElement() instead. 144 Element* ancestor = parentElement(); 145 while (ancestor && ancestor->isSVGElement()) { 146 if (ancestor->renderer() && ancestor->renderer()->isSVGHiddenContainer()) 147 return false; 148 149 ancestor = ancestor->parentElement(); 150 } 151 152 return SVGGraphicsElement::rendererIsNeeded(style); 153} 154 155bool SVGForeignObjectElement::selfHasRelativeLengths() const 156{ 157 return xCurrentValue().isRelative() 158 || yCurrentValue().isRelative() 159 || widthCurrentValue().isRelative() 160 || heightCurrentValue().isRelative(); 161} 162 163} 164