static void updateContainerOffset(SVGElementInstance* targetInstance) { // Depth-first used to write the method in early exit style, no particular other reason. for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) updateContainerOffset(instance); SVGElement* correspondingElement = targetInstance->correspondingElement(); ASSERT(correspondingElement); if (!correspondingElement->hasTagName(SVGNames::useTag)) return; SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); ASSERT(shadowTreeElement); ASSERT(shadowTreeElement->hasTagName(SVGNames::gTag)); if (!static_cast<SVGGElement*>(shadowTreeElement)->isShadowTreeContainerElement()) return; // Spec: An additional transformation translate(x,y) is appended to the end // (i.e., right-side) of the transform attribute on the generated 'g', where x // and y represent the values of the x and y attributes on the 'use' element. SVGUseElement* useElement = static_cast<SVGUseElement*>(correspondingElement); SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(shadowTreeElement); containerElement->setContainerOffset(useElement->x(), useElement->y()); }
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); }