File indexing completed on 2024-04-28 11:39:14
0001 /* 0002 Copyright (C) 2006 Apple Computer, Inc. 0003 (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 0004 0005 This file is part of the WebKit project 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT) 0024 #include "SVGForeignObjectElement.h" 0025 0026 #include "CSSPropertyNames.h" 0027 #include "RenderForeignObject.h" 0028 #include "SVGNames.h" 0029 #include "SVGLength.h" 0030 0031 #include <wtf/Assertions.h> 0032 0033 namespace WebCore 0034 { 0035 0036 SVGForeignObjectElement::SVGForeignObjectElement(const QualifiedName &tagName, Document *doc) 0037 : SVGStyledTransformableElement(tagName, doc) 0038 , SVGTests() 0039 , SVGLangSpace() 0040 , SVGExternalResourcesRequired() 0041 , m_x(this, LengthModeWidth) 0042 , m_y(this, LengthModeHeight) 0043 , m_width(this, LengthModeWidth) 0044 , m_height(this, LengthModeHeight) 0045 { 0046 } 0047 0048 SVGForeignObjectElement::~SVGForeignObjectElement() 0049 { 0050 } 0051 0052 ANIMATED_PROPERTY_DEFINITIONS(SVGForeignObjectElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) 0053 ANIMATED_PROPERTY_DEFINITIONS(SVGForeignObjectElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) 0054 ANIMATED_PROPERTY_DEFINITIONS(SVGForeignObjectElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) 0055 ANIMATED_PROPERTY_DEFINITIONS(SVGForeignObjectElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) 0056 0057 void SVGForeignObjectElement::parseMappedAttribute(MappedAttribute *attr) 0058 { 0059 const AtomicString &value = attr->value(); 0060 if (attr->name() == SVGNames::xAttr) { 0061 setXBaseValue(SVGLength(this, LengthModeWidth, value)); 0062 } else if (attr->name() == SVGNames::yAttr) { 0063 setYBaseValue(SVGLength(this, LengthModeHeight, value)); 0064 } else if (attr->name() == SVGNames::widthAttr) { 0065 setWidthBaseValue(SVGLength(this, LengthModeWidth, value)); 0066 } else if (attr->name() == SVGNames::heightAttr) { 0067 setHeightBaseValue(SVGLength(this, LengthModeHeight, value)); 0068 } else { 0069 if (SVGTests::parseMappedAttribute(attr)) { 0070 return; 0071 } 0072 if (SVGLangSpace::parseMappedAttribute(attr)) { 0073 return; 0074 } 0075 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) { 0076 return; 0077 } 0078 SVGStyledTransformableElement::parseMappedAttribute(attr); 0079 } 0080 } 0081 0082 // TODO: Move this function in some SVG*Element base class, as SVGSVGElement / SVGImageElement will need the same logic! 0083 0084 // This function mimics addCSSProperty and StyledElement::attributeChanged. 0085 // In HTML code, you'd always call addCSSProperty from your derived parseMappedAttribute() 0086 // function - though in SVG code we need to move this logic into svgAttributeChanged, in 0087 // order to support SVG DOM changes (which don't use the parseMappedAttribute/attributeChanged). 0088 // If we'd ignore SVG DOM, we could use _exactly_ the same logic as HTML. 0089 static inline void addCSSPropertyAndNotifyAttributeMap(StyledElement *element, const QualifiedName &name, int cssProperty, const String &value) 0090 { 0091 ASSERT(element); 0092 0093 if (!element) { 0094 return; 0095 } 0096 0097 NamedMappedAttrMap *attrs = element->mappedAttributes(); 0098 ASSERT(attrs); 0099 0100 if (!attrs) { 0101 return; 0102 } 0103 0104 MappedAttribute *mappedAttr = attrs->getAttributeItem(name); 0105 if (!mappedAttr) { 0106 return; 0107 } 0108 0109 // This logic is only meant to be used for entries that have to be parsed and are mapped to eNone. Assert that. 0110 MappedAttributeEntry entry; 0111 bool needToParse = element->mapToEntry(mappedAttr->name(), entry); 0112 0113 ASSERT(needToParse); 0114 ASSERT(entry == eNone); 0115 0116 if (!needToParse || entry != eNone) { 0117 return; 0118 } 0119 0120 if (mappedAttr->decl()) { 0121 mappedAttr->setDecl(0); 0122 attrs->declRemoved(); 0123 } 0124 0125 element->setChanged(); 0126 element->addCSSProperty(mappedAttr, cssProperty, value); 0127 0128 if (CSSMappedAttributeDeclaration *decl = mappedAttr->decl()) { 0129 // Add the decl to the table in the appropriate spot. 0130 element->setMappedAttributeDecl(entry, mappedAttr, decl); 0131 0132 decl->setMappedState(entry, mappedAttr->name(), mappedAttr->value()); 0133 decl->setParent(0); 0134 decl->setNode(0); 0135 0136 attrs->declAdded(); 0137 } 0138 } 0139 0140 void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName &attrName) 0141 { 0142 SVGStyledTransformableElement::svgAttributeChanged(attrName); 0143 0144 if (attrName == SVGNames::widthAttr) { 0145 addCSSPropertyAndNotifyAttributeMap(this, attrName, CSSPropertyWidth, width().valueAsString()); 0146 return; 0147 } else if (attrName == SVGNames::heightAttr) { 0148 addCSSPropertyAndNotifyAttributeMap(this, attrName, CSSPropertyHeight, height().valueAsString()); 0149 return; 0150 } 0151 0152 if (!renderer()) { 0153 return; 0154 } 0155 0156 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || 0157 SVGTests::isKnownAttribute(attrName) || 0158 SVGLangSpace::isKnownAttribute(attrName) || 0159 SVGExternalResourcesRequired::isKnownAttribute(attrName) || 0160 SVGStyledTransformableElement::isKnownAttribute(attrName)) { 0161 renderer()->setNeedsLayout(true); 0162 } 0163 } 0164 0165 RenderObject *SVGForeignObjectElement::createRenderer(RenderArena *arena, RenderStyle *style) 0166 { 0167 return new(arena) RenderForeignObject(this); 0168 } 0169 0170 bool SVGForeignObjectElement::childShouldCreateRenderer(Node *child) const 0171 { 0172 // Skip over SVG rules which disallow non-SVG kids 0173 return StyledElement::childShouldCreateRenderer(child); 0174 } 0175 0176 } // namespace WebCore 0177 0178 #endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)