RenderSVGResourceMasker* MaskImageOperation::getSVGMasker(RenderElement& renderer) { if (image()) return nullptr; // Identify the element referenced by the fragmentId. CachedSVGDocumentReference* svgDocumentReference = cachedSVGDocumentReference(); Element* elementForMasking = nullptr; RenderObject* svgResourceForMasking = nullptr; if (svgDocumentReference && svgDocumentReference->document()) { SVGDocument* svgDocument = svgDocumentReference->document()->document(); if (svgDocument && svgDocument->rootElement()) elementForMasking = svgDocument->rootElement()->getElementById(fragment()); } else elementForMasking = renderer.document().getElementById(fragment()); if (elementForMasking) svgResourceForMasking = elementForMasking->renderer(); // Check if it's the correct type if (svgResourceForMasking && svgResourceForMasking->isSVGResourceContainer() && downcast<RenderSVGResourceContainer>(svgResourceForMasking)->resourceType() == MaskerResourceType) return static_cast<RenderSVGResourceMasker*>(svgResourceForMasking); return nullptr; }
void MaskImageOperation::notifyFinished(CachedResource* resource) { // The only one notifying us should be the SVG document we hold. CachedSVGDocument* cachedSVGDocument = ensureCachedSVGDocumentReference()->document(); if ((CachedResource*)cachedSVGDocument != resource || !resource) { ASSERT_NOT_REACHED(); return; } // Check if we find a valid masking element in this SVG document. SVGDocument* svgDocument = cachedSVGDocument->document(); bool validMaskFound = false; if (svgDocument && svgDocument->rootElement()) { // Are we looking for a specific element in the SVG document? if (fragment().length()) { if (Element* maskingElement = svgDocument->rootElement()->getElementById(fragment())) { if (is<SVGMaskElement>(maskingElement)) validMaskFound = true; } } } // If no valid mask was found, this is not a valid SVG document or it specified an invalid fragment identifier. // Fallback to the normal way of loading the document in an Image object. if (!validMaskFound) { // Get the resource loader, acquire the resource buffer and load it into an image. ASSERT(cachedSVGDocument->loader()); if (SubresourceLoader* loader = cachedSVGDocument->loader()) { if (SharedBuffer* dataBuffer = loader->resourceData()) { m_styleImage = StyleCachedImage::create(new CachedImage(cachedSVGDocument->resourceRequest(), cachedSVGDocument->sessionID())); if (m_renderLayerImageClient) m_styleImage->cachedImage()->addClient(m_renderLayerImageClient); for (auto itClient : m_rendererImageClients) m_styleImage->addClient(itClient.key); m_styleImage->cachedImage()->setResponse(cachedSVGDocument->response()); m_styleImage->cachedImage()->finishLoading(dataBuffer); // Let the cached resource loader of the document which requested this mask keep a handle to this // cached image to ensure it only gets deleted when it should. if (m_cachedResourceLoader.get()) m_cachedResourceLoader->addCachedResource(*m_styleImage->cachedImage()); } // Destroy the current SVG document as its no longer needed m_cachedSVGDocumentReference = nullptr; } } }
JSValue jsSVGDocumentRootElement(ExecState* exec, JSValue slotBase, const Identifier&) { JSSVGDocument* castedThis = static_cast<JSSVGDocument*>(asObject(slotBase)); UNUSED_PARAM(exec); SVGDocument* imp = static_cast<SVGDocument*>(castedThis->impl()); JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->rootElement())); return result; }
JSValue* JSSVGDocument::getValueProperty(ExecState* exec, int token) const { switch (token) { case RootElementAttrNum: { SVGDocument* imp = static_cast<SVGDocument*>(impl()); return toJS(exec, WTF::getPtr(imp->rootElement())); } } return 0; }