void TreeScope::setParentTreeScope(TreeScope& newParentScope) { // A document node cannot be re-parented. DCHECK(!rootNode().isDocumentNode()); m_parentTreeScope = &newParentScope; setDocument(newParentScope.document()); }
AtomicString SVGURIReference::fragmentIdentifierFromIRIString( const String& urlString, const TreeScope& treeScope) { SVGURLReferenceResolver resolver(urlString, treeScope.document()); if (!resolver.isLocal()) return emptyAtom; return resolver.fragmentIdentifier(); }
void TreeScope::setParentTreeScope(TreeScope& newParentScope) { // A document node cannot be re-parented. ASSERT(!rootNode().isDocumentNode()); newParentScope.guardRef(); if (m_parentTreeScope) m_parentTreeScope->guardDeref(); m_parentTreeScope = &newParentScope; setDocument(newParentScope.document()); }
AtomicString SVGURIReference::fragmentIdentifierFromIRIString(const String& url, const TreeScope& treeScope) { size_t start = url.find('#'); if (start == kNotFound) return emptyAtom; const Document& document = treeScope.document(); KURL base = start ? KURL(document.baseURI(), url.substring(0, start)) : document.baseURI(); if (equalIgnoringFragmentIdentifier(base, document.url())) return AtomicString(url.substring(start + 1)); return emptyAtom; }
static inline KURL urlFromIRIStringWithFragmentIdentifier(const String& url, const TreeScope& treeScope, AtomicString& fragmentIdentifier) { size_t startOfFragmentIdentifier = url.find('#'); if (startOfFragmentIdentifier == kNotFound) return KURL(); const Document& document = treeScope.document(); // Exclude the '#' character when determining the fragmentIdentifier. fragmentIdentifier = AtomicString(url.substring(startOfFragmentIdentifier + 1)); if (startOfFragmentIdentifier) { KURL base(document.baseURI(), url.substring(0, startOfFragmentIdentifier)); return KURL(base, url.substring(startOfFragmentIdentifier)); } return KURL(document.baseURI(), url.substring(startOfFragmentIdentifier)); }
void ScopedStyleResolver::keyframesRulesAdded(const TreeScope& treeScope) { // Called when @keyframes rules are about to be added/removed from a // TreeScope. @keyframes rules may apply to animations on elements in the // same TreeScope as the stylesheet, or the host element in the parent // TreeScope if the TreeScope is a shadow tree. ScopedStyleResolver* resolver = treeScope.scopedStyleResolver(); ScopedStyleResolver* parentResolver = treeScope.parentTreeScope() ? treeScope.parentTreeScope()->scopedStyleResolver() : nullptr; bool hadUnresolvedKeyframes = false; if (resolver && resolver->m_hasUnresolvedKeyframesRule) { resolver->m_hasUnresolvedKeyframesRule = false; hadUnresolvedKeyframes = true; } if (parentResolver && parentResolver->m_hasUnresolvedKeyframesRule) { parentResolver->m_hasUnresolvedKeyframesRule = false; hadUnresolvedKeyframes = true; } if (hadUnresolvedKeyframes) { // If an animation ended up not being started because no @keyframes // rules were found for the animation-name, we need to recalculate style // for the elements in the scope, including its shadow host if // applicable. invalidationRootForTreeScope(treeScope).setNeedsStyleRecalc( SubtreeStyleChange, StyleChangeReasonForTracing::create( StyleChangeReason::StyleSheetChange)); return; } // If we have animations running, added/removed @keyframes may affect these. treeScope.document().timeline().invalidateKeyframeEffects(treeScope); }
PassRefPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* parentFilter, RenderObject* renderer, FilterEffect* previousEffect, const ReferenceFilterOperation* filterOperation) { if (!renderer) return nullptr; TreeScope* treeScope = &renderer->node()->treeScope(); if (DocumentResourceReference* documentResourceRef = documentResourceReference(filterOperation)) { DocumentResource* cachedSVGDocument = documentResourceRef->document(); // If we have an SVG document, this is an external reference. Otherwise // we look up the referenced node in the current document. if (cachedSVGDocument) treeScope = cachedSVGDocument->document(); } if (!treeScope) return nullptr; Element* filter = treeScope->getElementById(filterOperation->fragment()); if (!filter) { // Although we did not find the referenced filter, it might exist later // in the document. treeScope->document().accessSVGExtensions().addPendingResource(filterOperation->fragment(), toElement(renderer->node())); return nullptr; } if (!isSVGFilterElement(*filter)) return nullptr; SVGFilterElement& filterElement = toSVGFilterElement(*filter); // FIXME: Figure out what to do with SourceAlpha. Right now, we're // using the alpha of the original input layer, which is obviously // wrong. We should probably be extracting the alpha from the // previousEffect, but this requires some more processing. // This may need a spec clarification. RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(previousEffect, SourceAlpha::create(parentFilter)); ColorSpace filterColorSpace = ColorSpaceDeviceRGB; bool useFilterColorSpace = getSVGElementColorSpace(&filterElement, filterColorSpace); for (SVGElement* element = Traversal<SVGElement>::firstChild(filterElement); element; element = Traversal<SVGElement>::nextSibling(*element)) { if (!element->isFilterEffect()) continue; SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFilterPrimitiveStandardAttributes*>(element); RefPtr<FilterEffect> effect = effectElement->build(builder.get(), parentFilter); if (!effect) continue; effectElement->setStandardAttributes(effect.get()); effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement.primitiveUnits()->currentValue()->enumValue(), parentFilter->sourceImageRect())); ColorSpace colorSpace = filterColorSpace; if (useFilterColorSpace || getSVGElementColorSpace(effectElement, colorSpace)) effect->setOperatingColorSpace(colorSpace); builder->add(AtomicString(effectElement->result()->currentValue()->value()), effect); } return builder->lastEffect(); }