summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/CSSCursorImageValue.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/css/CSSCursorImageValue.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/css/CSSCursorImageValue.cpp')
-rw-r--r--Source/WebCore/css/CSSCursorImageValue.cpp193
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
{