diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/css/CSSCursorImageValue.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/css/CSSCursorImageValue.cpp')
-rw-r--r-- | Source/WebCore/css/CSSCursorImageValue.cpp | 193 |
1 files changed, 40 insertions, 153 deletions
diff --git a/Source/WebCore/css/CSSCursorImageValue.cpp b/Source/WebCore/css/CSSCursorImageValue.cpp index 6d0806407..c9f0a7660 100644 --- a/Source/WebCore/css/CSSCursorImageValue.cpp +++ b/Source/WebCore/css/CSSCursorImageValue.cpp @@ -22,75 +22,34 @@ #include "config.h" #include "CSSCursorImageValue.h" +#include "CSSImageSetValue.h" #include "CSSImageValue.h" #include "CachedImage.h" #include "CachedResourceLoader.h" -#include "StyleCachedImage.h" -#include "StyleImage.h" -#include "StylePendingImage.h" +#include "SVGCursorElement.h" +#include "SVGLengthContext.h" +#include "SVGURIReference.h" #include "TreeScope.h" #include <wtf/MathExtras.h> #include <wtf/text/StringBuilder.h> #include <wtf/text/WTFString.h> -#if ENABLE(SVG) -#include "SVGCursorElement.h" -#include "SVGLengthContext.h" -#include "SVGNames.h" -#include "SVGURIReference.h" -#endif - -#if ENABLE(CSS_IMAGE_SET) -#include "CSSImageSetValue.h" -#include "StyleCachedImageSet.h" -#endif - namespace WebCore { -#if ENABLE(SVG) -static inline SVGCursorElement* resourceReferencedByCursorElement(const String& url, Document& document) -{ - Element* element = SVGURIReference::targetElementFromIRIString(url, document); - if (element && isSVGCursorElement(element)) - return toSVGCursorElement(element); - - return 0; -} -#endif - -CSSCursorImageValue::CSSCursorImageValue(PassRef<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot) +CSSCursorImageValue::CSSCursorImageValue(Ref<CSSValue>&& imageValue, bool hasHotSpot, const IntPoint& hotSpot) : CSSValue(CursorImageClass) - , m_imageValue(std::move(imageValue)) + , m_imageValue(WTFMove(imageValue)) , m_hasHotSpot(hasHotSpot) , m_hotSpot(hotSpot) - , m_accessedImage(false) -{ -} - -inline void CSSCursorImageValue::detachPendingImage() { - if (m_image && m_image->isPendingImage()) - static_cast<StylePendingImage&>(*m_image).detachFromCSSValue(); + if (is<CSSImageValue>(m_imageValue.get())) + m_originalURL = downcast<CSSImageValue>(m_imageValue.get()).url(); } CSSCursorImageValue::~CSSCursorImageValue() { - detachPendingImage(); - -#if ENABLE(SVG) - if (!isSVGCursor()) - return; - - HashSet<SVGElement*>::const_iterator it = m_referencedElements.begin(); - HashSet<SVGElement*>::const_iterator end = m_referencedElements.end(); - - for (; it != end; ++it) { - SVGElement* referencedElement = *it; - referencedElement->cursorImageValueRemoved(); - if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(toCSSImageValue(m_imageValue.get()).url(), referencedElement->document())) - cursorElement->removeClient(referencedElement); - } -#endif + for (auto* element : m_cursorElements) + element->removeClient(*this); } String CSSCursorImageValue::customCSSText() const @@ -106,124 +65,52 @@ String CSSCursorImageValue::customCSSText() const return result.toString(); } -bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element) +SVGCursorElement* CSSCursorImageValue::updateCursorElement(const Document& document) { -#if !ENABLE(SVG) - UNUSED_PARAM(element); -#else - if (!element || !element->isSVGElement()) - return false; - - if (!isSVGCursor()) - return false; - - if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(toCSSImageValue(m_imageValue.get()).url(), element->document())) { - // FIXME: This will override hot spot specified in CSS, which is probably incorrect. - SVGLengthContext lengthContext(0); - m_hasHotSpot = true; - float x = roundf(cursorElement->x().value(lengthContext)); - m_hotSpot.setX(static_cast<int>(x)); - - float y = roundf(cursorElement->y().value(lengthContext)); - m_hotSpot.setY(static_cast<int>(y)); - - if (cachedImageURL() != element->document().completeURL(cursorElement->href())) - clearCachedImage(); - - SVGElement* svgElement = toSVGElement(element); - m_referencedElements.add(svgElement); - svgElement->setCursorImageValue(this); - cursorElement->addClient(svgElement); - return true; - } -#endif + if (!m_originalURL.hasFragmentIdentifier()) + return nullptr; - return false; -} + auto* element = SVGURIReference::targetElementFromIRIString(m_originalURL, document); + if (!is<SVGCursorElement>(element)) + return nullptr; -StyleImage* CSSCursorImageValue::cachedImage(CachedResourceLoader* loader) -{ -#if ENABLE(CSS_IMAGE_SET) - if (m_imageValue.get().isImageSetValue()) - return toCSSImageSetValue(m_imageValue.get()).cachedImageSet(loader); -#endif - - if (!m_accessedImage) { - m_accessedImage = true; - -#if ENABLE(SVG) - // For SVG images we need to lazily substitute in the correct URL. Rather than attempt - // to change the URL of the CSSImageValue (which would then change behavior like cssText), - // we create an alternate CSSImageValue to use. - if (isSVGCursor() && loader && loader->document()) { - // FIXME: This will fail if the <cursor> element is in a shadow DOM (bug 59827) - if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(toCSSImageValue(m_imageValue.get()).url(), *loader->document())) { - detachPendingImage(); - Ref<CSSImageValue> svgImageValue(CSSImageValue::create(cursorElement->href())); - StyleCachedImage* cachedImage = svgImageValue->cachedImage(loader); - m_image = cachedImage; - return cachedImage; - } - } -#endif - - if (m_imageValue.get().isImageValue()) { - detachPendingImage(); - m_image = toCSSImageValue(m_imageValue.get()).cachedImage(loader); - } + auto& cursorElement = downcast<SVGCursorElement>(*element); + if (m_cursorElements.add(&cursorElement).isNewEntry) { + cursorElementChanged(cursorElement); + cursorElement.addClient(*this); } - - if (m_image && m_image->isCachedImage()) - return static_cast<StyleCachedImage*>(m_image.get()); - - return 0; + return &cursorElement; } -StyleImage* CSSCursorImageValue::cachedOrPendingImage(Document& document) +void CSSCursorImageValue::cursorElementRemoved(SVGCursorElement& cursorElement) { -#if ENABLE(CSS_IMAGE_SET) - // Need to delegate completely so that changes in device scale factor can be handled appropriately. - if (m_imageValue.get().isImageSetValue()) - return toCSSImageSetValue(m_imageValue.get()).cachedOrPendingImageSet(document); -#else - UNUSED_PARAM(document); -#endif - - if (!m_image) - m_image = StylePendingImage::create(this); - - return m_image.get(); + m_cursorElements.remove(&cursorElement); } -#if ENABLE(SVG) -bool CSSCursorImageValue::isSVGCursor() const +void CSSCursorImageValue::cursorElementChanged(SVGCursorElement& cursorElement) { - if (m_imageValue.get().isImageValue()) { - URL kurl(ParsedURLString, toCSSImageValue(m_imageValue.get()).url()); - return kurl.hasFragmentIdentifier(); - } - return false; + // FIXME: This will override hot spot specified in CSS, which is probably incorrect. + SVGLengthContext lengthContext(nullptr); + m_hasHotSpot = true; + float x = std::round(cursorElement.x().value(lengthContext)); + m_hotSpot.setX(static_cast<int>(x)); + + float y = std::round(cursorElement.y().value(lengthContext)); + m_hotSpot.setY(static_cast<int>(y)); } -String CSSCursorImageValue::cachedImageURL() +std::pair<CachedImage*, float> CSSCursorImageValue::loadImage(CachedResourceLoader& loader, const ResourceLoaderOptions& options) { - if (!m_image || !m_image->isCachedImage()) - return String(); - return static_cast<StyleCachedImage*>(m_image.get())->cachedImage()->url(); -} + if (is<CSSImageSetValue>(m_imageValue.get())) + return downcast<CSSImageSetValue>(m_imageValue.get()).loadBestFitImage(loader, options); -void CSSCursorImageValue::clearCachedImage() -{ - detachPendingImage(); - m_image = nullptr; - m_accessedImage = false; -} + if (auto* cursorElement = updateCursorElement(*loader.document())) { + if (cursorElement->href() != downcast<CSSImageValue>(m_imageValue.get()).url()) + m_imageValue = CSSImageValue::create(loader.document()->completeURL(cursorElement->href())); + } -void CSSCursorImageValue::removeReferencedElement(SVGElement* element) -{ - m_referencedElements.remove(element); + return { downcast<CSSImageValue>(m_imageValue.get()).loadImage(loader, options), 1 }; } -#endif bool CSSCursorImageValue::equals(const CSSCursorImageValue& other) const { |