1 /* 2 * Copyright (C) 2006 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann (at) 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 23 #if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT) 24 #include "SVGForeignObjectElement.h" 25 26 #include "Attribute.h" 27 #include "CSSPropertyNames.h" 28 #include "RenderSVGForeignObject.h" 29 #include "RenderSVGResource.h" 30 #include "SVGLength.h" 31 #include "SVGNames.h" 32 #include <wtf/Assertions.h> 33 34 namespace WebCore { 35 36 // Animated property definitions 37 DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::xAttr, X, x) 38 DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::yAttr, Y, y) 39 DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::widthAttr, Width, width) 40 DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::heightAttr, Height, height) 41 DEFINE_ANIMATED_STRING(SVGForeignObjectElement, XLinkNames::hrefAttr, Href, href) 42 DEFINE_ANIMATED_BOOLEAN(SVGForeignObjectElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 43 44 inline SVGForeignObjectElement::SVGForeignObjectElement(const QualifiedName& tagName, Document* document) 45 : SVGStyledTransformableElement(tagName, document) 46 , m_x(LengthModeWidth) 47 , m_y(LengthModeHeight) 48 , m_width(LengthModeWidth) 49 , m_height(LengthModeHeight) 50 { 51 } 52 53 PassRefPtr<SVGForeignObjectElement> SVGForeignObjectElement::create(const QualifiedName& tagName, Document* document) 54 { 55 return adoptRef(new SVGForeignObjectElement(tagName, document)); 56 } 57 58 void SVGForeignObjectElement::parseMappedAttribute(Attribute* attr) 59 { 60 const AtomicString& value = attr->value(); 61 if (attr->name() == SVGNames::xAttr) 62 setXBaseValue(SVGLength(LengthModeWidth, value)); 63 else if (attr->name() == SVGNames::yAttr) 64 setYBaseValue(SVGLength(LengthModeHeight, value)); 65 else if (attr->name() == SVGNames::widthAttr) 66 setWidthBaseValue(SVGLength(LengthModeWidth, value)); 67 else if (attr->name() == SVGNames::heightAttr) 68 setHeightBaseValue(SVGLength(LengthModeHeight, value)); 69 else { 70 if (SVGTests::parseMappedAttribute(attr)) 71 return; 72 if (SVGLangSpace::parseMappedAttribute(attr)) 73 return; 74 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) 75 return; 76 SVGStyledTransformableElement::parseMappedAttribute(attr); 77 } 78 } 79 80 void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) 81 { 82 SVGStyledTransformableElement::svgAttributeChanged(attrName); 83 84 bool isLengthAttribute = attrName == SVGNames::xAttr 85 || attrName == SVGNames::yAttr 86 || attrName == SVGNames::widthAttr 87 || attrName == SVGNames::heightAttr; 88 89 if (isLengthAttribute) 90 updateRelativeLengthsInformation(); 91 92 if (SVGTests::handleAttributeChange(this, attrName)) 93 return; 94 95 RenderObject* renderer = this->renderer(); 96 if (!renderer) 97 return; 98 99 if (isLengthAttribute 100 || SVGLangSpace::isKnownAttribute(attrName) 101 || SVGExternalResourcesRequired::isKnownAttribute(attrName)) 102 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 103 } 104 105 void SVGForeignObjectElement::synchronizeProperty(const QualifiedName& attrName) 106 { 107 SVGStyledTransformableElement::synchronizeProperty(attrName); 108 109 if (attrName == anyQName()) { 110 synchronizeX(); 111 synchronizeY(); 112 synchronizeWidth(); 113 synchronizeHeight(); 114 synchronizeExternalResourcesRequired(); 115 synchronizeHref(); 116 SVGTests::synchronizeProperties(this, attrName); 117 return; 118 } 119 120 if (attrName == SVGNames::xAttr) 121 synchronizeX(); 122 else if (attrName == SVGNames::yAttr) 123 synchronizeY(); 124 else if (attrName == SVGNames::widthAttr) 125 synchronizeWidth(); 126 else if (attrName == SVGNames::heightAttr) 127 synchronizeHeight(); 128 else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) 129 synchronizeExternalResourcesRequired(); 130 else if (SVGTests::isKnownAttribute(attrName)) 131 SVGTests::synchronizeProperties(this, attrName); 132 } 133 134 AttributeToPropertyTypeMap& SVGForeignObjectElement::attributeToPropertyTypeMap() 135 { 136 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); 137 return s_attributeToPropertyTypeMap; 138 } 139 140 void SVGForeignObjectElement::fillAttributeToPropertyTypeMap() 141 { 142 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap(); 143 144 SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap); 145 attributeToPropertyTypeMap.set(SVGNames::xAttr, AnimatedLength); 146 attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedLength); 147 attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength); 148 attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength); 149 attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedString); 150 } 151 152 RenderObject* SVGForeignObjectElement::createRenderer(RenderArena* arena, RenderStyle*) 153 { 154 return new (arena) RenderSVGForeignObject(this); 155 } 156 157 bool SVGForeignObjectElement::childShouldCreateRenderer(Node* child) const 158 { 159 // Disallow arbitary SVG content. Only allow proper <svg xmlns="svgNS"> subdocuments. 160 if (child->isSVGElement()) 161 return child->hasTagName(SVGNames::svgTag); 162 163 // Skip over SVG rules which disallow non-SVG kids 164 return StyledElement::childShouldCreateRenderer(child); 165 } 166 167 bool SVGForeignObjectElement::selfHasRelativeLengths() const 168 { 169 return x().isRelative() 170 || y().isRelative() 171 || width().isRelative() 172 || height().isRelative(); 173 } 174 175 } 176 177 #endif 178