bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, ContainerNode* targetInstance, SVGElement*& newTarget) { ASSERT(referencedScope()); Element* targetElement = SVGURIReference::targetElementFromIRIString(use->hrefString(), *referencedScope()); newTarget = 0; if (targetElement && targetElement->isSVGElement()) newTarget = toSVGElement(targetElement); if (!newTarget) return false; // Shortcut for self-references if (newTarget == this) return true; AtomicString targetId = newTarget->getIdAttribute(); ContainerNode* instance = targetInstance->parentNode(); while (instance && instance->isSVGElement()) { SVGElement* element = toSVGElement(instance); if (element->hasID() && element->getIdAttribute() == targetId && element->document() == newTarget->document()) return true; instance = instance->parentNode(); } return false; }
RenderSVGResourceContainer::RenderSVGResourceContainer(SVGElement& element, PassRef<RenderStyle> style) : RenderSVGHiddenContainer(element, std::move(style)) , m_id(element.getIdAttribute()) , m_registered(false) , m_isInvalidating(false) { }
static void dumpInstanceTree(unsigned int& depth, String& text, SVGElementInstance* targetInstance) { SVGElement* element = targetInstance->correspondingElement(); ASSERT(element); if (element->hasTagName(SVGNames::useTag)) { if (toSVGUseElement(element)->cachedDocumentIsStillLoading()) return; } SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); ASSERT(shadowTreeElement); SVGUseElement* directUseElement = targetInstance->directUseElement(); String directUseElementName = directUseElement ? directUseElement->nodeName() : "null"; String elementId = element->getIdAttribute(); String elementNodeName = element->nodeName(); String shadowTreeElementNodeName = shadowTreeElement->nodeName(); String parentNodeName = element->parentNode() ? element->parentNode()->nodeName() : "null"; String firstChildNodeName = element->firstChild() ? element->firstChild()->nodeName() : "null"; for (unsigned int i = 0; i < depth; ++i) text += " "; text += String::format("SVGElementInstance this=%p, (parentNode=%s (%p), firstChild=%s (%p), correspondingElement=%s (%p), directUseElement=%s (%p), shadowTreeElement=%s (%p), id=%s)\n", targetInstance, parentNodeName.latin1().data(), element->parentNode(), firstChildNodeName.latin1().data(), element->firstChild(), elementNodeName.latin1().data(), element, directUseElementName.latin1().data(), directUseElement, shadowTreeElementNodeName.latin1().data(), shadowTreeElement, elementId.latin1().data()); for (unsigned int i = 0; i < depth; ++i) text += " "; const HashSet<SVGElementInstance*>& elementInstances = element->instancesForElement(); text += "Corresponding element is associated with " + String::number(elementInstances.size()) + " instance(s):\n"; const HashSet<SVGElementInstance*>::const_iterator end = elementInstances.end(); for (HashSet<SVGElementInstance*>::const_iterator it = elementInstances.begin(); it != end; ++it) { for (unsigned int i = 0; i < depth; ++i) text += " "; text += String::format(" -> SVGElementInstance this=%p, (refCount: %i, shadowTreeElement in document? %i)\n", *it, (*it)->refCount(), (*it)->shadowTreeElement()->inDocument()); } ++depth; for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) dumpInstanceTree(depth, text, instance); --depth; }
static void writeSVGPaintingResource(TextStream& ts, RenderSVGResource* resource) { if (resource->resourceType() == SolidColorResourceType) { ts << "[type=SOLID] [color=" << static_cast<RenderSVGResourceSolidColor*>(resource)->color() << "]"; return; } // All other resources derive from RenderSVGResourceContainer RenderSVGResourceContainer* container = static_cast<RenderSVGResourceContainer*>(resource); SVGElement* element = container->element(); ASSERT(element); if (resource->resourceType() == PatternResourceType) ts << "[type=PATTERN]"; else if (resource->resourceType() == LinearGradientResourceType) ts << "[type=LINEAR-GRADIENT]"; else if (resource->resourceType() == RadialGradientResourceType) ts << "[type=RADIAL-GRADIENT]"; ts << " [id=\"" << element->getIdAttribute() << "\"]"; }
static void writeSVGPaintingResource(TextStream& ts, const SVGPaintDescription& paintDescription) { ASSERT(paintDescription.isValid); if (!paintDescription.resource) { ts << "[type=SOLID] [color=" << paintDescription.color << "]"; return; } LayoutSVGResourcePaintServer* paintServerContainer = paintDescription.resource; SVGElement* element = paintServerContainer->element(); ASSERT(element); if (paintServerContainer->resourceType() == PatternResourceType) ts << "[type=PATTERN]"; else if (paintServerContainer->resourceType() == LinearGradientResourceType) ts << "[type=LINEAR-GRADIENT]"; else if (paintServerContainer->resourceType() == RadialGradientResourceType) ts << "[type=RADIAL-GRADIENT]"; ts << " [id=\"" << element->getIdAttribute() << "\"]"; }