static void associateReplacementCloneWithOriginal(SVGElement& replacementClone, SVGElement& originalClone) { auto* correspondingElement = originalClone.correspondingElement(); ASSERT(correspondingElement); originalClone.setCorrespondingElement(nullptr); replacementClone.setCorrespondingElement(correspondingElement); }
static void associateClonesWithOriginals(SVGElement& clone, SVGElement& original) { // This assertion checks that we don't call this with the arguments backwards. // The clone is new and so it's not installed in a parent yet. ASSERT(!clone.parentNode()); // The loop below works because we are associating these clones immediately, before // doing transformations like removing disallowed elements or expanding elements. clone.setCorrespondingElement(&original); for (auto pair : descendantsOfType<SVGElement>(clone, original)) pair.first.setCorrespondingElement(&pair.second); }
void SVGElement::invalidateInstances() { if (instanceUpdatesBlocked()) return; auto& instances = this->instances(); while (!instances.isEmpty()) { SVGElement* instance = *instances.begin(); if (SVGUseElement* useElement = instance->correspondingUseElement()) useElement->invalidateShadowTree(); instance->setCorrespondingElement(nullptr); } while (!instances.isEmpty()); }
void SVGUseElement::associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance) { if (!target || !targetInstance) return; SVGElement* originalElement = targetInstance->correspondingElement(); if (originalElement->hasTagName(SVGNames::useTag)) { // <use> gets replaced by <g> ASSERT(target->nodeName() == SVGNames::gTag); } else if (originalElement->hasTagName(SVGNames::symbolTag)) { // <symbol> gets replaced by <svg> ASSERT(target->nodeName() == SVGNames::svgTag); } else ASSERT(target->nodeName() == originalElement->nodeName()); SVGElement* element = 0; if (target->isSVGElement()) element = toSVGElement(target); ASSERT(!targetInstance->shadowTreeElement()); targetInstance->setShadowTreeElement(element); element->setCorrespondingElement(originalElement); Node* node = target->firstChild(); for (SVGElementInstance* instance = targetInstance->firstChild(); node && instance; instance = instance->nextSibling()) { // Skip any non-svg elements in shadow tree while (node && !node->isSVGElement()) node = node->nextSibling(); if (!node) break; associateInstancesWithShadowTreeElements(node, instance); node = node->nextSibling(); } }