This source file includes following definitions.
- m_scaleFactor
- fillImageSet
- bestImageForScaleFactor
- cachedImageSet
- cachedImageSet
- cachedOrPendingImageSet
- customCSSText
- hasFailedOrCanceledSubresources
- m_scaleFactor
- cloneForCSSOM
#include "config.h"
#include "core/css/CSSImageSetValue.h"
#include "FetchInitiatorTypeNames.h"
#include "core/css/CSSImageValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/dom/Document.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ImageResource.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/rendering/style/StyleFetchedImageSet.h"
#include "core/rendering/style/StylePendingImage.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
CSSImageSetValue::CSSImageSetValue()
: CSSValueList(ImageSetClass, CommaSeparator)
, m_accessedBestFitImage(false)
, m_scaleFactor(1)
{
}
CSSImageSetValue::~CSSImageSetValue()
{
if (m_imageSet && m_imageSet->isImageResourceSet())
toStyleFetchedImageSet(m_imageSet)->clearImageSetValue();
}
void CSSImageSetValue::fillImageSet()
{
size_t length = this->length();
size_t i = 0;
while (i < length) {
CSSValue* imageValue = item(i);
String imageURL = toCSSImageValue(imageValue)->url();
++i;
ASSERT_WITH_SECURITY_IMPLICATION(i < length);
CSSValue* scaleFactorValue = item(i);
float scaleFactor = toCSSPrimitiveValue(scaleFactorValue)->getFloatValue();
ImageWithScale image;
image.imageURL = imageURL;
image.scaleFactor = scaleFactor;
m_imagesInSet.append(image);
++i;
}
std::sort(m_imagesInSet.begin(), m_imagesInSet.end(), CSSImageSetValue::compareByScaleFactor);
}
CSSImageSetValue::ImageWithScale CSSImageSetValue::bestImageForScaleFactor()
{
ImageWithScale image;
size_t numberOfImages = m_imagesInSet.size();
for (size_t i = 0; i < numberOfImages; ++i) {
image = m_imagesInSet.at(i);
if (image.scaleFactor >= m_scaleFactor)
return image;
}
return image;
}
StyleFetchedImageSet* CSSImageSetValue::cachedImageSet(ResourceFetcher* loader, float deviceScaleFactor, const ResourceLoaderOptions& options)
{
ASSERT(loader);
m_scaleFactor = deviceScaleFactor;
if (!m_imagesInSet.size())
fillImageSet();
if (!m_accessedBestFitImage) {
ImageWithScale image = bestImageForScaleFactor();
if (Document* document = loader->document()) {
FetchRequest request(ResourceRequest(document->completeURL(image.imageURL)), FetchInitiatorTypeNames::css, options);
if (options.corsEnabled == IsCORSEnabled)
request.setCrossOriginAccessControl(loader->document()->securityOrigin(), options.allowCredentials, options.credentialsRequested);
if (ResourcePtr<ImageResource> cachedImage = loader->fetchImage(request)) {
m_imageSet = StyleFetchedImageSet::create(cachedImage.get(), image.scaleFactor, this);
m_accessedBestFitImage = true;
}
}
}
return (m_imageSet && m_imageSet->isImageResourceSet()) ? toStyleFetchedImageSet(m_imageSet) : 0;
}
StyleFetchedImageSet* CSSImageSetValue::cachedImageSet(ResourceFetcher* fetcher, float deviceScaleFactor)
{
return cachedImageSet(fetcher, deviceScaleFactor, ResourceFetcher::defaultResourceOptions());
}
StyleImage* CSSImageSetValue::cachedOrPendingImageSet(float deviceScaleFactor)
{
if (!m_imageSet) {
m_imageSet = StylePendingImage::create(this);
} else if (!m_imageSet->isPendingImage()) {
if (deviceScaleFactor != m_scaleFactor) {
m_accessedBestFitImage = false;
m_imageSet = StylePendingImage::create(this);
}
}
return m_imageSet.get();
}
String CSSImageSetValue::customCSSText() const
{
StringBuilder result;
result.append("-webkit-image-set(");
size_t length = this->length();
size_t i = 0;
while (i < length) {
if (i > 0)
result.append(", ");
const CSSValue* imageValue = item(i);
result.append(imageValue->cssText());
result.append(' ');
++i;
ASSERT_WITH_SECURITY_IMPLICATION(i < length);
const CSSValue* scaleFactorValue = item(i);
result.append(scaleFactorValue->cssText());
result.append('x');
++i;
}
result.append(")");
return result.toString();
}
bool CSSImageSetValue::hasFailedOrCanceledSubresources() const
{
if (!m_imageSet || !m_imageSet->isImageResourceSet())
return false;
if (Resource* cachedResource = toStyleFetchedImageSet(m_imageSet)->cachedImage())
return cachedResource->loadFailedOrCanceled();
return true;
}
CSSImageSetValue::CSSImageSetValue(const CSSImageSetValue& cloneFrom)
: CSSValueList(cloneFrom)
, m_accessedBestFitImage(false)
, m_scaleFactor(1)
{
}
PassRefPtrWillBeRawPtr<CSSImageSetValue> CSSImageSetValue::cloneForCSSOM() const
{
return adoptRefWillBeRefCountedGarbageCollected(new CSSImageSetValue(*this));
}
}