StyleImage* CSSCursorImageValue::cachedImage(ResourceFetcher* loader, float deviceScaleFactor) { if (m_imageValue->isImageSetValue()) return toCSSImageSetValue(m_imageValue.get())->cachedImageSet(loader, deviceScaleFactor); if (!m_accessedImage) { m_accessedImage = true; // 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()) { RefPtrWillBeRawPtr<CSSImageValue> imageValue = toCSSImageValue(m_imageValue.get()); // FIXME: This will fail if the <cursor> element is in a shadow DOM (bug 59827) if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(imageValue->url(), *loader->document())) { RefPtrWillBeRawPtr<CSSImageValue> svgImageValue = CSSImageValue::create(loader->document()->completeURL(cursorElement->href()->currentValue()->value())); svgImageValue->setReferrer(imageValue->referrer()); StyleFetchedImage* cachedImage = svgImageValue->cachedImage(loader); m_image = cachedImage; return cachedImage; } } if (m_imageValue->isImageValue()) m_image = toCSSImageValue(m_imageValue.get())->cachedImage(loader); } if (m_image && m_image->isImageResource()) return toStyleFetchedImage(m_image); return 0; }
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; // 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; } } if (m_imageValue.get().isImageValue()) { detachPendingImage(); m_image = toCSSImageValue(m_imageValue.get()).cachedImage(loader); } } if (m_image && m_image->isCachedImage()) return static_cast<StyleCachedImage*>(m_image.get()); return 0; }
CSSCrossfadeValue* CSSCrossfadeValue::valueWithURLsMadeAbsolute() { CSSValue* fromValue = m_fromValue; if (m_fromValue->isImageValue()) fromValue = toCSSImageValue(*m_fromValue).valueWithURLMadeAbsolute(); CSSValue* toValue = m_toValue; if (m_toValue->isImageValue()) toValue = toCSSImageValue(*m_toValue).valueWithURLMadeAbsolute(); return CSSCrossfadeValue::create(fromValue, toValue, m_percentageValue); }
void PageSerializer::retrieveResourcesForProperties(const StyleProperties* styleDeclaration, Document* document) { if (!styleDeclaration) return; // The background-image and list-style-image (for ul or ol) are the CSS properties // that make use of images. We iterate to make sure we include any other // image properties there might be. unsigned propertyCount = styleDeclaration->propertyCount(); for (unsigned i = 0; i < propertyCount; ++i) { RefPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value(); if (!cssValue->isImageValue()) continue; StyleImage* styleImage = toCSSImageValue(cssValue.get())->cachedOrPendingImage(); // Non cached-images are just place-holders and do not contain data. if (!styleImage || !styleImage->isCachedImage()) continue; CachedImage* image = toStyleCachedImage(styleImage)->cachedImage(); URL url = document->completeURL(image->url()); addImageToResources(image, 0, url); } }
CachedImage* CSSImageGeneratorValue::cachedImageForCSSValue(CSSValue* value, CachedResourceLoader* cachedResourceLoader) { if (!value) return nullptr; if (value->isImageValue()) { StyleCachedImage* styleCachedImage = toCSSImageValue(value)->cachedImage(cachedResourceLoader); if (!styleCachedImage) return nullptr; return styleCachedImage->cachedImage(); } if (value->isImageGeneratorValue()) { toCSSImageGeneratorValue(value)->loadSubimages(cachedResourceLoader); // FIXME: Handle CSSImageGeneratorValue (and thus cross-fades with gradients and canvas). return nullptr; } if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNone) return nullptr; ASSERT_NOT_REACHED(); return nullptr; }
bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element) { if (!element || !element->isSVGElement()) return false; if (!isSVGCursor()) return false; String url = toCSSImageValue(m_imageValue.get())->url(); if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, element->treeScope())) { // FIXME: This will override hot spot specified in CSS, which is probably incorrect. SVGLengthContext lengthContext(0); m_hasHotSpot = true; float x = roundf(cursorElement->x()->currentValue()->value(lengthContext)); m_hotSpot.setX(static_cast<int>(x)); float y = roundf(cursorElement->y()->currentValue()->value(lengthContext)); m_hotSpot.setY(static_cast<int>(y)); if (cachedImageURL() != element->document().completeURL(cursorElement->href()->currentValue()->value())) clearImageResource(); SVGElement* svgElement = toSVGElement(element); #if !ENABLE(OILPAN) m_referencedElements.add(svgElement); #endif svgElement->setCursorImageValue(this); cursorElement->addClient(svgElement); return true; } return false; }
bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValue& value) { // FIXME: should not require resolving styles for inherit/initial/unset. if (value.isCSSWideKeyword()) return true; if (value.isBasicShapeCircleValue()) return interpolationRequiresStyleResolve(toCSSBasicShapeCircleValue(value)); if (value.isBasicShapeEllipseValue()) return interpolationRequiresStyleResolve(toCSSBasicShapeEllipseValue(value)); if (value.isBasicShapePolygonValue()) return interpolationRequiresStyleResolve(toCSSBasicShapePolygonValue(value)); if (value.isBasicShapeInsetValue()) return interpolationRequiresStyleResolve(toCSSBasicShapeInsetValue(value)); if (value.isPrimitiveValue()) return interpolationRequiresStyleResolve(toCSSPrimitiveValue(value)); if (value.isQuadValue()) return interpolationRequiresStyleResolve(toCSSQuadValue(value)); if (value.isValueList()) return interpolationRequiresStyleResolve(toCSSValueList(value)); if (value.isValuePair()) return interpolationRequiresStyleResolve(toCSSValuePair(value)); if (value.isImageValue()) return interpolationRequiresStyleResolve(toCSSImageValue(value)); if (value.isShadowValue()) return interpolationRequiresStyleResolve(toCSSShadowValue(value)); if (value.isSVGDocumentValue()) return interpolationRequiresStyleResolve(toCSSSVGDocumentValue(value)); // FIXME: consider other custom types. return true; }
PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const { switch (classType()) { case PrimitiveClass: return toCSSPrimitiveValue(this)->cloneForCSSOM(); case ValueListClass: return toCSSValueList(this)->cloneForCSSOM(); case ImageClass: case CursorImageClass: return toCSSImageValue(this)->cloneForCSSOM(); #if ENABLE(CSS_FILTERS) case WebKitCSSFilterClass: return toWebKitCSSFilterValue(this)->cloneForCSSOM(); #endif case WebKitCSSTransformClass: return toWebKitCSSTransformValue(this)->cloneForCSSOM(); #if ENABLE(CSS_IMAGE_SET) case ImageSetClass: return toCSSImageSetValue(this)->cloneForCSSOM(); #endif #if ENABLE(SVG) case SVGColorClass: return toSVGColor(this)->cloneForCSSOM(); case SVGPaintClass: return toSVGPaint(this)->cloneForCSSOM(); #endif default: ASSERT(!isSubtypeExposedToCSSOM()); return TextCloneCSSValue::create(classType(), cssText()); } }
bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValue& value) { switch (value.cssValueType()) { case CSSValue::CSS_INHERIT: return true; case CSSValue::CSS_PRIMITIVE_VALUE: return interpolationRequiresStyleResolve(toCSSPrimitiveValue(value)); case CSSValue::CSS_VALUE_LIST: return interpolationRequiresStyleResolve(toCSSValueList(value)); case CSSValue::CSS_CUSTOM: if (value.isImageValue()) return interpolationRequiresStyleResolve(toCSSImageValue(value)); if (value.isShadowValue()) return interpolationRequiresStyleResolve(toCSSShadowValue(value)); if (value.isSVGDocumentValue()) return interpolationRequiresStyleResolve(toCSSSVGDocumentValue(value)); // FIXME: consider other custom types. return true; case CSSValue::CSS_INITIAL: // FIXME: should not require resolving styles for initial. return true; default: ASSERT_NOT_REACHED(); return true; } }
bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element) { 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 = downcast<SVGElement>(*element); m_referencedElements.add(&svgElement); svgElement.setCursorImageValue(this); cursorElement->addClient(&svgElement); return true; } return false; }
static ImageResourceContent* cachedImageForCSSValue(CSSValue* value, const Document& document) { if (!value) return nullptr; if (value->isImageValue()) { StyleImage* styleImageResource = toCSSImageValue(value)->cacheImage(document); if (!styleImageResource) return nullptr; return styleImageResource->cachedImage(); } if (value->isImageGeneratorValue()) { toCSSImageGeneratorValue(value)->loadSubimages(document); // FIXME: Handle CSSImageGeneratorValue (and thus cross-fades with gradients // and canvas). return nullptr; } ASSERT_NOT_REACHED(); return nullptr; }
String CSSValue::cssText() const { if (m_isTextClone) { ASSERT(isCSSOMSafe()); return toTextCloneCSSValue(this)->cssText(); } ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); switch (classType()) { case AspectRatioClass: return toCSSAspectRatioValue(this)->customCSSText(); case BorderImageSliceClass: return toCSSBorderImageSliceValue(this)->customCSSText(); case FontClass: return toCSSFontValue(this)->customCSSText(); case FontFaceSrcClass: return toCSSFontFaceSrcValue(this)->customCSSText(); case FontFeatureClass: return toCSSFontFeatureValue(this)->customCSSText(); case FunctionClass: return toCSSFunctionValue(this)->customCSSText(); case LinearGradientClass: return toCSSLinearGradientValue(this)->customCSSText(); case RadialGradientClass: return toCSSRadialGradientValue(this)->customCSSText(); case CrossfadeClass: return toCSSCrossfadeValue(this)->customCSSText(); case ImageClass: return toCSSImageValue(this)->customCSSText(); case InheritedClass: return toCSSInheritedValue(this)->customCSSText(); case InitialClass: return toCSSInitialValue(this)->customCSSText(); case PrimitiveClass: return toCSSPrimitiveValue(this)->customCSSText(); case ShadowClass: return toCSSShadowValue(this)->customCSSText(); case CubicBezierTimingFunctionClass: return toCSSCubicBezierTimingFunctionValue(this)->customCSSText(); case StepsTimingFunctionClass: return toCSSStepsTimingFunctionValue(this)->customCSSText(); case UnicodeRangeClass: return toCSSUnicodeRangeValue(this)->customCSSText(); case ValueListClass: return toCSSValueList(this)->customCSSText(); case CSSTransformClass: return toCSSTransformValue(this)->customCSSText(); case LineBoxContainClass: return toCSSLineBoxContainValue(this)->customCSSText(); case CalculationClass: return toCSSCalcValue(this)->customCSSText(); case ImageSetClass: return toCSSImageSetValue(this)->customCSSText(); case CSSFilterClass: return toCSSFilterValue(this)->customCSSText(); } ASSERT_NOT_REACHED(); return String(); }
bool CSSCursorImageValue::isSVGCursor() const { if (m_imageValue.get().isImageValue()) { URL kurl(ParsedURLString, toCSSImageValue(m_imageValue.get()).url()); return kurl.hasFragmentIdentifier(); } return false; }
bool CSSCursorImageValue::hasFragmentInURL() const { if (m_imageValue->isImageValue()) { CSSImageValue* imageValue = toCSSImageValue(m_imageValue.get()); KURL kurl(ParsedURLString, imageValue->url()); return kurl.hasFragmentIdentifier(); } return false; }
bool CSSCursorImageValue::isSVGCursor() const { if (m_imageValue->isImageValue()) { RefPtrWillBeRawPtr<CSSImageValue> imageValue = toCSSImageValue(m_imageValue.get()); KURL kurl(ParsedURLString, imageValue->url()); return kurl.hasFragmentIdentifier(); } return false; }
static bool subimageIsPending(CSSValue* value) { if (value->isImageValue()) return toCSSImageValue(value)->isCachePending(); if (value->isImageGeneratorValue()) return toCSSImageGeneratorValue(value)->isPending(); ASSERT_NOT_REACHED(); return false; }
SVGCursorElement* CSSCursorImageValue::getSVGCursorElement( Element* element) const { if (!element || !element->isSVGElement()) return nullptr; if (!hasFragmentInURL()) return nullptr; String url = toCSSImageValue(m_imageValue.get())->url(); return resourceReferencedByCursorElement(url, element->treeScope()); }
static bool subimageKnownToBeOpaque(CSSValue* value, const RenderObject* renderer) { if (value->isImageValue()) return toCSSImageValue(value)->knownToBeOpaque(renderer); if (value->isImageGeneratorValue()) return static_cast<CSSImageGeneratorValue*>(value)->knownToBeOpaque(renderer); ASSERT_NOT_REACHED(); return false; }
static bool subimageIsPending(CSSValue* value) { if (value->isImageValue()) return toCSSImageValue(value)->cachedOrPendingImage()->isPendingImage(); if (value->isImageGeneratorValue()) return static_cast<CSSImageGeneratorValue*>(value)->isPending(); ASSERT_NOT_REACHED(); return false; }
static bool subimageKnownToBeOpaque(CSSValue& value, const RenderElement* renderer) { if (value.isImageValue()) return toCSSImageValue(value).knownToBeOpaque(renderer); if (value.isImageGeneratorValue()) return toCSSImageGeneratorValue(value).knownToBeOpaque(renderer); ASSERT_NOT_REACHED(); return false; }
static bool subimageKnownToBeOpaque(CSSValue* value, const LayoutObject& layoutObject) { if (value->isImageValue()) return toCSSImageValue(value)->knownToBeOpaque(layoutObject); if (value->isImageGeneratorValue()) return toCSSImageGeneratorValue(value)->knownToBeOpaque(layoutObject); ASSERT_NOT_REACHED(); return false; }
bool CSSValue::hasFailedOrCanceledSubresources() const { if (isValueList()) return toCSSValueList(this)->hasFailedOrCanceledSubresources(); if (getClassType() == FontFaceSrcClass) return toCSSFontFaceSrcValue(this)->hasFailedOrCanceledSubresources(); if (getClassType() == ImageClass) return toCSSImageValue(this)->hasFailedOrCanceledSubresources(); if (getClassType() == CrossfadeClass) return toCSSCrossfadeValue(this)->hasFailedOrCanceledSubresources(); if (getClassType() == ImageSetClass) return toCSSImageSetValue(this)->hasFailedOrCanceledSubresources(); return false; }
StyleImage* CSSCursorImageValue::cacheImage(const Document& document, float deviceScaleFactor) { if (m_imageValue->isImageSetValue()) return toCSSImageSetValue(*m_imageValue) .cacheImage(document, deviceScaleFactor); if (m_isCachePending) { m_isCachePending = false; // 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 (hasFragmentInURL()) { CSSImageValue* imageValue = toCSSImageValue(m_imageValue.get()); // FIXME: This will fail if the <cursor> element is in a shadow DOM // (http://crbug/59827) if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(imageValue->url(), document)) { CSSImageValue* svgImageValue = CSSImageValue::create(document.completeURL( cursorElement->href()->currentValue()->value())); svgImageValue->setReferrer(imageValue->referrer()); m_cachedImage = svgImageValue->cacheImage(document); return m_cachedImage.get(); } } if (m_imageValue->isImageValue()) m_cachedImage = toCSSImageValue(*m_imageValue).cacheImage(document); } if (m_cachedImage && m_cachedImage->isImageResource()) return toStyleFetchedImage(m_cachedImage); return nullptr; }
bool CSSImageGeneratorValue::subimageIsPending(CSSValue* value) { if (value->isImageValue()) return toCSSImageValue(value)->cachedOrPendingImage()->isPendingImage(); if (value->isImageGeneratorValue()) return toCSSImageGeneratorValue(value)->isPending(); if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNone) return false; ASSERT_NOT_REACHED(); return false; }
PassRefPtrWillBeRawPtr<StyleImage> ElementStyleResources::styleImage(CSSPropertyID property, const CSSValue& value) { if (value.isImageValue()) return cachedOrPendingFromValue(property, toCSSImageValue(value)); if (value.isImageGeneratorValue()) return generatedOrPendingFromValue(property, toCSSImageGeneratorValue(value)); if (value.isImageSetValue()) return setOrPendingFromValue(property, toCSSImageSetValue(value)); if (value.isCursorImageValue()) return cursorOrPendingFromValue(property, toCSSCursorImageValue(value)); return nullptr; }
StyleImage* CSSCursorImageValue::cachedImage(ResourceFetcher* loader, float deviceScaleFactor) { if (m_imageValue->isImageSetValue()) return toCSSImageSetValue(m_imageValue.get())->cachedImageSet(loader, deviceScaleFactor); if (!m_accessedImage) { m_accessedImage = true; if (m_imageValue->isImageValue()) m_image = toCSSImageValue(m_imageValue.get())->cachedImage(loader); } if (m_image && m_image->isImageResource()) return toStyleFetchedImage(m_image); return 0; }
CSSCursorImageValue::~CSSCursorImageValue() { if (!isSVGCursor()) return; HashSet<SVGElement*>::const_iterator it = m_referencedElements.begin(); HashSet<SVGElement*>::const_iterator end = m_referencedElements.end(); String url = toCSSImageValue(m_imageValue.get())->url(); for (; it != end; ++it) { SVGElement* referencedElement = *it; referencedElement->cursorImageValueRemoved(); if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->document())) cursorElement->removeClient(referencedElement); } }
PassRefPtr<StyleImage> ElementStyleResources::styleImage(Document& document, const TextLinkColors& textLinkColors, Color currentColor, CSSPropertyID property, CSSValue* value) { if (value->isImageValue()) return cachedOrPendingFromValue(document, property, toCSSImageValue(value)); if (value->isImageGeneratorValue()) { if (value->isGradientValue()) return generatedOrPendingFromValue(property, toCSSGradientValue(value)->gradientWithStylesResolved(textLinkColors, currentColor).get()); return generatedOrPendingFromValue(property, toCSSImageGeneratorValue(value)); } if (value->isImageSetValue()) return setOrPendingFromValue(property, toCSSImageSetValue(value)); return nullptr; }
CSSCursorImageValue::~CSSCursorImageValue() { // The below teardown is all handled by weak pointer processing in oilpan. #if !ENABLE(OILPAN) if (!isSVGCursor()) return; String url = toCSSImageValue(m_imageValue.get())->url(); for (SVGElement* referencedElement : m_referencedElements) { referencedElement->cursorImageValueRemoved(); if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->treeScope())) cursorElement->removeClient(referencedElement); } #endif }
PassRefPtrWillBeRawPtr<StyleImage> ElementStyleResources::styleImage(Document& document, const TextLinkColors& textLinkColors, Color currentColor, CSSPropertyID property, CSSValue* value) { if (value->isImageValue()) return cachedOrPendingFromValue(document, property, toCSSImageValue(value)); if (value->isImageGeneratorValue()) return generatedOrPendingFromValue(property, toCSSImageGeneratorValue(value)); if (value->isImageSetValue()) return setOrPendingFromValue(property, toCSSImageSetValue(value)); if (value->isCursorImageValue()) return cursorOrPendingFromValue(property, toCSSCursorImageValue(value)); return nullptr; }