1/* 2 * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@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 "SVGGElement.h" 23 24#include "RenderSVGHiddenContainer.h" 25#include "RenderSVGResource.h" 26#include "RenderSVGTransformableContainer.h" 27#include "SVGElementInstance.h" 28#include "SVGNames.h" 29#include <wtf/NeverDestroyed.h> 30 31namespace WebCore { 32 33// Animated property definitions 34DEFINE_ANIMATED_BOOLEAN(SVGGElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 35 36BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGElement) 37 REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired) 38 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement) 39END_REGISTER_ANIMATED_PROPERTIES 40 41SVGGElement::SVGGElement(const QualifiedName& tagName, Document& document) 42 : SVGGraphicsElement(tagName, document) 43{ 44 ASSERT(hasTagName(SVGNames::gTag)); 45 registerAnimatedPropertiesForSVGGElement(); 46} 47 48PassRefPtr<SVGGElement> SVGGElement::create(const QualifiedName& tagName, Document& document) 49{ 50 return adoptRef(new SVGGElement(tagName, document)); 51} 52 53bool SVGGElement::isSupportedAttribute(const QualifiedName& attrName) 54{ 55 static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; 56 if (supportedAttributes.get().isEmpty()) { 57 SVGLangSpace::addSupportedAttributes(supportedAttributes); 58 SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); 59 } 60 return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); 61} 62 63void SVGGElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 64{ 65 if (!isSupportedAttribute(name)) { 66 SVGGraphicsElement::parseAttribute(name, value); 67 return; 68 } 69 70 if (SVGLangSpace::parseAttribute(name, value)) 71 return; 72 if (SVGExternalResourcesRequired::parseAttribute(name, value)) 73 return; 74 75 ASSERT_NOT_REACHED(); 76} 77 78void SVGGElement::svgAttributeChanged(const QualifiedName& attrName) 79{ 80 if (!isSupportedAttribute(attrName)) { 81 SVGGraphicsElement::svgAttributeChanged(attrName); 82 return; 83 } 84 85 SVGElementInstance::InvalidationGuard invalidationGuard(this); 86 87 if (auto renderer = this->renderer()) 88 RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); 89} 90 91RenderPtr<RenderElement> SVGGElement::createElementRenderer(PassRef<RenderStyle> style) 92{ 93 // SVG 1.1 testsuite explicitely uses constructs like <g display="none"><linearGradient> 94 // We still have to create renderers for the <g> & <linearGradient> element, though the 95 // subtree may be hidden - we only want the resource renderers to exist so they can be 96 // referenced from somewhere else. 97 if (style.get().display() == NONE) 98 return createRenderer<RenderSVGHiddenContainer>(*this, WTF::move(style)); 99 100 return createRenderer<RenderSVGTransformableContainer>(*this, WTF::move(style)); 101} 102 103bool SVGGElement::rendererIsNeeded(const RenderStyle&) 104{ 105 // Unlike SVGElement::rendererIsNeeded(), we still create renderers, even if 106 // display is set to 'none' - which is special to SVG <g> container elements. 107 return parentOrShadowHostElement() && parentOrShadowHostElement()->isSVGElement(); 108} 109 110} 111