15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 University of Szeged 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGUseElement.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 29197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionStatePlaceholder.h" 305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/XLinkNames.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 32e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/dom/ElementTraversal.h" 3306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/Event.h" 34e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ElementShadow.h" 35e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h" 36e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/FetchRequest.h" 37e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourceFetcher.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGResource.h" 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGTransformableContainer.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGGElement.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGLengthContext.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGSVGElement.h" 4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/parser/XMLDocumentParser.h" 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 45c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 47d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)inline SVGUseElement::SVGUseElement(Document& document) 4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) : SVGGraphicsElement(SVGNames::useTag, document) 4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , SVGURIReference(this) 5007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths)) 5107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths)) 5207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths)) 5307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths)) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_haveFiredLoadEvent(false) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_needsShadowTreeRecreation(false) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(hasCustomStyleCallbacks()); 5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) addToPropertyMap(m_x); 6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) addToPropertyMap(m_y); 6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) addToPropertyMap(m_width); 6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) addToPropertyMap(m_height); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 66d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)PassRefPtrWillBeRawPtr<SVGUseElement> SVGUseElement::create(Document& document) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 68aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch // Always build a user agent #shadow-root for SVGUseElement. 695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<SVGUseElement> use = adoptRefWillBeNoop(new SVGUseElement(document)); 70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) use->ensureUserAgentShadowRoot(); 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return use.release(); 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGUseElement::~SVGUseElement() 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 763c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch setDocumentResource(0); 77f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#if !ENABLE(OILPAN) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearResourceReferences(); 79f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGUseElement::isSupportedAttribute(const QualifiedName& attrName) 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (supportedAttributes.isEmpty()) { 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGURIReference::addSupportedAttributes(supportedAttributes); 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::xAttr); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::yAttr); 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::widthAttr); 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::heightAttr); 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 92591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGUseElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 97c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) parseAttributeNew(name, value); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isWellFormedDocument(Document* document) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (document->isXMLDocument()) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return static_cast<XMLDocumentParser*>(document->parser())->wellFormed(); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#endif 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node::InsertionNotificationRequest SVGUseElement::insertedInto(ContainerNode* rootParent) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied. 112591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SVGGraphicsElement::insertedInto(rootParent); 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rootParent->inDocument()) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return InsertionDone; 1158abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document())); 1168abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(!hasPendingResources() || !isWellFormedDocument(&document())); 117d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) invalidateShadowTree(); 118d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!isStructurallyExternal()) 119d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) sendSVGLoadEventIfPossibleAsynchronously(); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return InsertionDone; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGUseElement::removedFrom(ContainerNode* rootParent) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 125591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SVGGraphicsElement::removedFrom(rootParent); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rootParent->inDocument()) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearResourceReferences(); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13010f88d5669dbd969c059d61ba09fa37dd72ac559Ben MurdochTreeScope* SVGUseElement::referencedScope() const 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!isExternalURIReference(hrefString(), document())) 13310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return &treeScope(); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return externalDocument(); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Document* SVGUseElement::externalDocument() const 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1393c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (m_resource && m_resource->isLoaded()) { 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Gracefully handle error condition. 1413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (m_resource->errorOccurred()) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1433c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch ASSERT(m_resource->document()); 1443c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return m_resource->document(); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 149323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGElement* shadowElement, const SVGElement& originalElement) 150323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){ 1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci DEFINE_STATIC_LOCAL(const AtomicString, hundredPercentString, ("100%", AtomicString::ConstructFromLiteral)); 152323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) ASSERT(shadowElement); 153323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (isSVGSymbolElement(*shadowElement)) { 154323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Spec (<use> on <symbol>): This generated 'svg' will always have explicit values for attributes width and height. 155323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // If attributes width and/or height are provided on the 'use' element, then these attributes 156323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // will be transferred to the generated 'svg'. If attributes width and/or height are not specified, 157323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // the generated 'svg' element will use values of 100% for these attributes. 1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci shadowElement->setAttribute(SVGNames::widthAttr, use.width()->isSpecified() ? AtomicString(use.width()->currentValue()->valueAsString()) : hundredPercentString); 1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci shadowElement->setAttribute(SVGNames::heightAttr, use.height()->isSpecified() ? AtomicString(use.height()->currentValue()->valueAsString()) : hundredPercentString); 160323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) } else if (isSVGSVGElement(*shadowElement)) { 161323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Spec (<use> on <svg>): If attributes width and/or height are provided on the 'use' element, then these 162323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // values will override the corresponding attributes on the 'svg' in the generated tree. 163323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (use.width()->isSpecified()) 164323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) shadowElement->setAttribute(SVGNames::widthAttr, AtomicString(use.width()->currentValue()->valueAsString())); 165323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) else 166323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) shadowElement->setAttribute(SVGNames::widthAttr, originalElement.getAttribute(SVGNames::widthAttr)); 167323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (use.height()->isSpecified()) 168323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) shadowElement->setAttribute(SVGNames::heightAttr, AtomicString(use.height()->currentValue()->valueAsString())); 169323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) else 170323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) shadowElement->setAttribute(SVGNames::heightAttr, originalElement.getAttribute(SVGNames::heightAttr)); 171323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) } 172323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)} 173323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isSupportedAttribute(attrName)) { 177591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SVGGraphicsElement::svgAttributeChanged(attrName); 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 181323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) SVGElement::InvalidationGuard invalidationGuard(this); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* renderer = this->renderer(); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (attrName == SVGNames::xAttr 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || attrName == SVGNames::yAttr 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || attrName == SVGNames::widthAttr 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || attrName == SVGNames::heightAttr) { 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateRelativeLengthsInformation(); 189323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (m_targetElementInstance) { 190323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) ASSERT(m_targetElementInstance->correspondingElement()); 1915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_targetElementInstance->correspondingElement()); 192323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) } 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (renderer) 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (SVGURIReference::isKnownAttribute(attrName)) { 19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bool isExternalReference = isExternalURIReference(hrefString(), document()); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isExternalReference) { 20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) KURL url = document().completeURL(hrefString()); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (url.hasFragmentIdentifier()) { 2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci FetchRequest request(ResourceRequest(url), localName()); 2048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) setDocumentResource(document().fetcher()->fetchSVGDocument(request)); 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2063c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch } else { 2073c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch setDocumentResource(0); 2083c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch } 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 210d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) invalidateShadowTree(); 211926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!renderer) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isDisallowedElement(Node* node) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: "Any 'svg', 'symbol', 'g', graphics element or other 'use' is potentially a template object that can be re-used 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (i.e., "instanced") in the SVG document via a 'use' element." 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // "Graphics Element" is defined as 'circle', 'ellipse', 'image', 'line', 'path', 'polygon', 'polyline', 'rect', 'text' 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Excluded are anything that is used by reference or that only make sense to appear once in a document. 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We must also allow the shadow roots of other use elements. 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node->isShadowRoot() || node->isTextNode()) 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!node->isSVGElement()) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Element* element = toElement(node); 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, allowedElementTags, ()); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (allowedElementTags.isEmpty()) { 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::aTag); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::circleTag); 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::descTag); 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::ellipseTag); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::gTag); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::imageTag); 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::lineTag); 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::metadataTag); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::pathTag); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::polygonTag); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::polylineTag); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::rectTag); 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::svgTag); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::switchTag); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::symbolTag); 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::textTag); 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::textPathTag); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::titleTag); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::tspanTag); 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowedElementTags.add(SVGNames::useTag); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 259591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return !allowedElementTags.contains<SVGAttributeHashTranslator>(element->tagQName()); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool subtreeContainsDisallowedElement(Node* start) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isDisallowedElement(start)) 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (Node* cur = start->firstChild(); cur; cur = cur->nextSibling()) { 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (subtreeContainsDisallowedElement(cur)) 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void SVGUseElement::scheduleShadowTreeRecreation() 27609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 27710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!referencedScope() || inUseShadowTree()) 27809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 27909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_needsShadowTreeRecreation = true; 28009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) document().scheduleUseShadowTreeUpdate(*this); 28109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 28209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGUseElement::clearResourceReferences() 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (m_targetElementInstance) 286d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_targetElementInstance = nullptr; 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 288323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // FIXME: We should try to optimize this, to at least allow partial reclones. 289323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) 290323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) shadowTreeRootElement->removeChildren(); 291323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needsShadowTreeRecreation = false; 29309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) document().unscheduleUseShadowTreeUpdate(*this); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 295197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch removeAllOutgoingReferences(); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGUseElement::buildPendingResource() 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 30010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!referencedScope() || inUseShadowTree()) 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearResourceReferences(); 303926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!inDocument()) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 30609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) AtomicString id; 30710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), treeScope(), &id, externalDocument()); 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!target || !target->inDocument()) { 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we can't find the target of an external element, just give up. 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We can't observe if the target somewhen enters the external document, nor should we do it. 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (externalDocument()) 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (id.isEmpty()) 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 31610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch referencedScope()->document().accessSVGExtensions().addPendingResource(id, this); 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(hasPendingResources()); 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (target->isSVGElement()) { 322926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) buildShadowAndInstanceTree(toSVGElement(target)); 323926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) invalidateDependentShadowTrees(); 324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 325926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_needsShadowTreeRecreation); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)static PassRefPtrWillBeRawPtr<Node> cloneNodeAndAssociate(Node& toClone) 3305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){ 3315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<Node> clone = toClone.cloneNode(false); 3325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!clone->isSVGElement()) 3335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return clone.release(); 3345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3355d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) SVGElement& svgElement = toSVGElement(toClone); 3365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ASSERT(!svgElement.correspondingElement()); 3375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) toSVGElement(clone.get())->setCorrespondingElement(&svgElement); 3385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (EventTargetData* data = toClone.eventTargetData()) 3395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(clone.get()); 3405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) TrackExceptionState exceptionState; 3415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* node = toClone.firstChild(); node && !exceptionState.hadException(); node = node->nextSibling()) 3425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) clone->appendChild(cloneNodeAndAssociate(*node), exceptionState); 3435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return clone.release(); 3445d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)} 3455d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_targetElementInstance); 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 350aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch // <use> creates a "user agent" shadow root. Do not build the shadow/instance tree for <use> 351aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch // elements living in a user agent shadow tree because they will get expanded in a second 352aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch // pass -- see expandUseElementsInShadowTree(). 35310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (inUseShadowTree()) 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do not allow self-referencing. 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 'target' may be null, if it's a non SVG namespaced element. 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!target || target == this) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Set up root SVG element in shadow tree. 3625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<Element> newChild = target->cloneElementWithoutChildren(); 3635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) m_targetElementInstance = toSVGElement(newChild.get()); 3645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); 3655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) shadowTreeRootElement->appendChild(newChild.release()); 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Clone the target subtree into the shadow tree, not handling <use> and <symbol> yet. 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // SVG specification does not say a word about <use> & cycles. My view on this is: just ignore it! 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Non-appearing <use> content is easier to debug, then half-appearing content. 3715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!buildShadowTree(target, m_targetElementInstance.get(), false)) { 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearResourceReferences(); 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (instanceTreeIsLoading(m_targetElementInstance.get())) 3775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return; 3785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Assure shadow tree building was successfull 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_targetElementInstance); 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_targetElementInstance->correspondingUseElement() == this); 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_targetElementInstance->correspondingElement() == target); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Expand all <use> elements in the shadow tree. 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Expand means: replace the actual <use> element by what it references. 3865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!expandUseElementsInShadowTree(m_targetElementInstance.get())) { 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clearResourceReferences(); 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Expand all <symbol> elements in the shadow tree. 3925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Expand means: replace the actual <symbol> element by the <svg> element. 3935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) expandSymbolElementsInShadowTree(toSVGElement(shadowTreeRootElement->firstChild())); 394323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 3955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) m_targetElementInstance = toSVGElement(shadowTreeRootElement->firstChild()); 3965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_targetElementInstance->correspondingElement()); 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ASSERT(m_targetElementInstance->parentNode() == shadowTreeRootElement); 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Update relative length information. 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateRelativeLengthsInformation(); 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 404591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochRenderObject* SVGUseElement::createRenderer(RenderStyle*) 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 406f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return new RenderSVGTransformableContainer(this); 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 409c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static bool isDirectReference(const SVGElement& element) 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 411c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return isSVGPathElement(element) 412c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) || isSVGRectElement(element) 413c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) || isSVGCircleElement(element) 414c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) || isSVGEllipseElement(element) 415c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) || isSVGPolygonElement(element) 416c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) || isSVGPolylineElement(element) 417c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) || isSVGTextElement(element); 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGUseElement::toClipPath(Path& path) 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(path.isEmpty()); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 424323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) Node* n = userAgentShadowRoot()->firstChild(); 425c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (!n || !n->isSVGElement()) 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 427c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) SVGElement& element = toSVGElement(*n); 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 429c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (element.isSVGGraphicsElement()) { 430c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (!isDirectReference(element)) { 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: Indirect references are an error (14.3.5) 432d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) document().accessSVGExtensions().reportError("Not allowed to use indirect reference in <clip-path>"); 4338abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } else { 434c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) toSVGGraphicsElement(element).toClipPath(path); 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Avoid manual resolution of x/y here. Its potentially harmful. 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGLengthContext lengthContext(this); 43709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) path.translate(FloatSize(m_x->currentValue()->value(lengthContext), m_y->currentValue()->value(lengthContext))); 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) path.transform(animatedLocalTransform()); 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderObject* SVGUseElement::rendererClipChild() const 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 445323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (Node* n = userAgentShadowRoot()->firstChild()) { 446c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (n->isSVGElement() && isDirectReference(toSVGElement(*n))) 447c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return n->renderer(); 448323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) } 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)bool SVGUseElement::buildShadowTree(SVGElement* target, SVGElement* targetInstance, bool foundUse) 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(target); 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(targetInstance); 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree. 4605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (isSVGUseElement(*target)) { 461926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // We only need to track first degree <use> dependencies. Indirect references are handled 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // as the invalidation bubbles up the dependency chain. 463197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!foundUse && !isStructurallyExternal()) { 464197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch addReferenceTo(target); 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) foundUse = true; 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (isDisallowedElement(target)) { 4685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) targetInstance->setCorrespondingElement(target); 4725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (EventTargetData* data = target->eventTargetData()) 4735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(targetInstance); 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* child = target->firstChild(); child; child = child->nextSibling()) { 47643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // Skip any disallowed element. 4775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (isDisallowedElement(child)) 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<Node> newChild = child->cloneNode(false); 4815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) targetInstance->appendChild(newChild.get()); 4825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (newChild->isSVGElement()) { 4835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Enter recursion, appending new instance tree nodes to the "instance" object. 4845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!buildShadowTree(toSVGElement(child), toSVGElement(newChild), foundUse)) 4855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 4865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return true; 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, ContainerNode* targetInstance, SVGElement*& newTarget) 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 49310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch ASSERT(referencedScope()); 49410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch Element* targetElement = SVGURIReference::targetElementFromIRIString(use->hrefString(), *referencedScope()); 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newTarget = 0; 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (targetElement && targetElement->isSVGElement()) 497926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) newTarget = toSVGElement(targetElement); 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!newTarget) 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Shortcut for self-references 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newTarget == this) 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AtomicString targetId = newTarget->getIdAttribute(); 5075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ContainerNode* instance = targetInstance->parentNode(); 5085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) while (instance && instance->isSVGElement()) { 5095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) SVGElement* element = toSVGElement(instance); 5101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (element->hasID() && element->getIdAttribute() == targetId && element->document() == newTarget->document()) 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) instance = instance->parentNode(); 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 51851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline void removeDisallowedElementsFromSubtree(Element& subtree) 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 52051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ASSERT(!subtree.inDocument()); 521926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Element* element = ElementTraversal::firstWithin(subtree); 522926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while (element) { 523926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (isDisallowedElement(element)) { 52451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) Element* next = ElementTraversal::nextSkippingChildren(*element, &subtree); 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The subtree is not in document so this won't generate events that could mutate the tree. 526926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) element->parentNode()->removeChild(element); 527926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) element = next; 52851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } else { 52951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) element = ElementTraversal::next(*element, &subtree); 53051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)bool SVGUseElement::expandUseElementsInShadowTree(SVGElement* element) 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 536d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(element); 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Why expand the <use> elements in the shadow tree here, and not just 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // do this directly in buildShadowTree, if we encounter a <use> element? 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 540aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch // Short answer: Because we may miss to expand some elements. For example, if a <symbol> 541aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch // contains <use> tags, we'd miss them. So once we're done with setting up the 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // actual shadow tree (after the special case modification for svg/symbol) we have 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to walk it completely and expand all <use> elements. 544d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isSVGUseElement(*element)) { 5457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch SVGUseElement* use = toSVGUseElement(element); 5463c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch ASSERT(!use->resourceIsStillLoading()); 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGElement* target = 0; 5495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (hasCycleUseReferencing(toSVGUseElement(use->correspondingElement()), use, target)) 5505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5525d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (target && isDisallowedElement(target)) 5535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't ASSERT(target) here, it may be "pending", too. 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Setup sub-shadow tree root node 556d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<SVGGElement> cloneParent = SVGGElement::create(referencedScope()->document()); 5575d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) cloneParent->setCorrespondingElement(use->correspondingElement()); 5585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 5595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Move already cloned elements to the new <g> element 5605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* child = use->firstChild(); child; ) { 5615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Node* nextChild = child->nextSibling(); 5625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) cloneParent->appendChild(child); 5635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) child = nextChild; 5645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 'use' element except for x, y, width, height and xlink:href are transferred to the generated 'g' element. 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) transferUseAttributesToReplacedElement(use, cloneParent.get()); 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (target) { 5715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target); 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(newChild->isSVGElement()); 573323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get()), *target); 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cloneParent->appendChild(newChild.release()); 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We don't walk the target tree element-by-element, and clone each element, 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // but instead use cloneElementWithChildren(). This is an optimization for the common 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // case where <use> doesn't contain disallowed elements (ie. <foreignObject>). 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Though if there are disallowed elements in the subtree, we have to remove them. 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For instance: <use> on <g> containing <foreignObject> (indirect case). 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (subtreeContainsDisallowedElement(cloneParent.get())) 58351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) removeDisallowedElementsFromSubtree(*cloneParent); 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get()); 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Replace <use> with referenced content. 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(use->parentNode()); 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) use->parentNode()->replaceChild(cloneParent.release(), use); 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Expand the siblings because the *element* is replaced and we will 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // lose the sibling chain when we are back from recursion. 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element = replacingElement.get(); 5945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (RefPtrWillBeRawPtr<SVGElement> sibling = Traversal<SVGElement>::nextSibling(*element); sibling; sibling = Traversal<SVGElement>::nextSibling(*sibling)) { 5955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!expandUseElementsInShadowTree(sibling.get())) 5965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 5975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChild(*element); child; child = Traversal<SVGElement>::nextSibling(*child)) { 6015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!expandUseElementsInShadowTree(child.get())) 6025d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 6035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 6045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return true; 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void SVGUseElement::expandSymbolElementsInShadowTree(SVGElement* element) 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 609d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(element); 610d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isSVGSymbolElement(*element)) { 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree, 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // with the exception that the 'symbol' is replaced by an 'svg'. This generated 'svg' will 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // always have explicit values for attributes width and height. If attributes width and/or 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // height are provided on the 'use' element, then these attributes will be transferred to 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the generated 'svg'. If attributes width and/or height are not specified, the generated 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 'svg' element will use values of 100% for these attributes. 61710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch ASSERT(referencedScope()); 618d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(referencedScope()->document()); 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Transfer all data (attributes, etc.) from <symbol> to the new <svg> element. 6205d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) svgElement->cloneDataFromElement(*element); 6215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) svgElement->setCorrespondingElement(element->correspondingElement()); 6225d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 6235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Move already cloned elements to the new <svg> element 6245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (Node* child = element->firstChild(); child; ) { 6255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Node* nextChild = child->nextSibling(); 6265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) svgElement->appendChild(child); 6275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) child = nextChild; 6285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We don't walk the target tree element-by-element, and clone each element, 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // but instead use cloneNode(deep=true). This is an optimization for the common 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // case where <use> doesn't contain disallowed elements (ie. <foreignObject>). 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Though if there are disallowed elements in the subtree, we have to remove them. 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For instance: <use> on <g> containing <foreignObject> (indirect case). 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (subtreeContainsDisallowedElement(svgElement.get())) 63651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) removeDisallowedElementsFromSubtree(*svgElement); 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get()); 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Replace <symbol> with <svg>. 6415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ASSERT(element->parentNode()); 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element->parentNode()->replaceChild(svgElement.release(), element); 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Expand the siblings because the *element* is replaced and we will 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // lose the sibling chain when we are back from recursion. 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element = replacingElement.get(); 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChild(*element); child; child = Traversal<SVGElement>::nextSibling(*child)) 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) expandSymbolElementsInShadowTree(child.get()); 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGUseElement::invalidateShadowTree() 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 65519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (!inActiveDocument() || m_needsShadowTreeRecreation) 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 65709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) scheduleShadowTreeRecreation(); 658926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) invalidateDependentShadowTrees(); 659926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 660926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 661926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGUseElement::invalidateDependentShadowTrees() 662926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 663926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Recursively invalidate dependent <use> shadow trees 664323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = instancesForElement(); 665323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end(); 666323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) { 667926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (SVGUseElement* element = (*it)->correspondingUseElement()) { 668926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(element->inDocument()); 669926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) element->invalidateShadowTree(); 670926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 671926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const 6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(from); 6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(to); 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to->cloneDataFromElement(*from); 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to->removeAttribute(SVGNames::xAttr); 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to->removeAttribute(SVGNames::yAttr); 6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to->removeAttribute(SVGNames::widthAttr); 6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to->removeAttribute(SVGNames::heightAttr); 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to->removeAttribute(XLinkNames::hrefAttr); 6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGUseElement::selfHasRelativeLengths() const 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 69009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_x->currentValue()->isRelative() 69109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) || m_y->currentValue()->isRelative() 69209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) || m_width->currentValue()->isRelative() 69309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) || m_height->currentValue()->isRelative()) 6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_targetElementInstance) 6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6995d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return m_targetElementInstance->hasRelativeLengths(); 7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 702fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid SVGUseElement::notifyFinished(Resource* resource) 7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!inDocument()) 7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) invalidateShadowTree(); 7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (resource->errorOccurred()) 7091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) dispatchEvent(Event::create(EventTypeNames::error)); 71009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) else if (!resource->wasCanceled()) { 711d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (m_haveFiredLoadEvent) 71209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 71309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!isStructurallyExternal()) 71409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 71509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(!m_haveFiredLoadEvent); 71609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_haveFiredLoadEvent = true; 717d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) sendSVGLoadEventIfPossibleAsynchronously(); 71809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochbool SVGUseElement::resourceIsStillLoading() 7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7233c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (m_resource && m_resource->isLoading()) 7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)bool SVGUseElement::instanceTreeIsLoading(SVGElement* targetInstance) 7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) for (SVGElement* element = Traversal<SVGElement>::firstChild(*targetInstance); element; element = Traversal<SVGElement>::nextSibling(*element)) { 7315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (SVGUseElement* use = element->correspondingUseElement()) { 7323c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (use->resourceIsStillLoading()) 7333c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return true; 7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7355d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (element->hasChildren() && instanceTreeIsLoading(element)) 7365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return true; 7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochvoid SVGUseElement::setDocumentResource(ResourcePtr<DocumentResource> resource) 742926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 7433c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (m_resource == resource) 744926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 745926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 7463c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (m_resource) 7473c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch m_resource->removeClient(this); 748926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 7493c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch m_resource = resource; 7503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (m_resource) 7513c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch m_resource->addClient(this); 752926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 753926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 754323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void SVGUseElement::trace(Visitor* visitor) 755323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){ 756323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) visitor->trace(m_targetElementInstance); 757323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) SVGGraphicsElement::trace(visitor); 758323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)} 759323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 761