static void cloneDataAndChildren(SVGElement& replacementClone, SVGElement& originalClone) { // This assertion checks that we don't call this with the arguments backwards. // The replacement clone is new and so it's not installed in a parent yet. ASSERT(!replacementClone.parentNode()); replacementClone.cloneDataFromElement(originalClone); originalClone.cloneChildNodes(&replacementClone); associateReplacementClonesWithOriginals(replacementClone, originalClone); removeDisallowedElementsFromSubtree(replacementClone); }
static void associateReplacementClonesWithOriginals(SVGElement& replacementClone, SVGElement& originalClone) { // This assertion checks that we don't call this with the arguments backwards. // The replacement clone is new and so it's not installed in a parent yet. ASSERT(!replacementClone.parentNode()); // The loop below works because we are associating these clones immediately, before // doing transformations like removing disallowed elements or expanding elements. associateReplacementCloneWithOriginal(replacementClone, originalClone); for (auto pair : descendantsOfType<SVGElement>(replacementClone, originalClone)) associateReplacementCloneWithOriginal(pair.first, pair.second); }
void dumpInstanceTree(unsigned int& depth, String& text, SVGElementInstance* targetInstance) { SVGElement* element = targetInstance->correspondingElement(); ASSERT(element); String elementId = element->getIDAttribute(); String elementNodeName = element->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 (parentNode=%s, firstChild=%s, correspondingElement=%s, id=%s)\n", parentNodeName.latin1().data(), firstChildNodeName.latin1().data(), elementNodeName.latin1().data(), elementId.latin1().data()); depth++; for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) dumpInstanceTree(depth, text, instance); depth--; }
void SVGUseElement::updateContainerOffsets() { if (!m_targetElementInstance) return; // Update root container offset (not reachable through instance tree) SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement(); ASSERT(shadowRoot); Node* parentNode = shadowRoot->parentNode(); ASSERT(parentNode); ASSERT(parentNode->isSVGElement()); ASSERT(parentNode->hasTagName(SVGNames::gTag)); ASSERT(static_cast<SVGGElement*>(parentNode)->isShadowTreeContainerElement()); SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(parentNode); containerElement->setContainerOffset(x(), y()); // Update whole subtree, scanning for shadow container elements, marking a cloned use subtree updateContainerOffset(m_targetElementInstance.get()); if (renderer()) renderer()->setNeedsLayout(true); }
void SVGUseElement::updateContainerOffsets() { if (!m_targetElementInstance) return; // Update root container offset (not reachable through instance tree) SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement(); ASSERT(shadowRoot); ContainerNode* parentNode = shadowRoot->parentNode(); ASSERT(parentNode); ASSERT(parentNode->isSVGElement()); ASSERT(parentNode->hasTagName(SVGNames::gTag)); ASSERT(static_cast<SVGGElement*>(parentNode)->isShadowTreeContainerElement()); SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(parentNode); containerElement->setContainerOffset(x(), y()); // Update whole subtree, scanning for shadow container elements, marking a cloned use subtree updateContainerOffset(m_targetElementInstance.get()); if (RenderObject* object = renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); }