1/* 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2008, 2013 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21#include "config.h" 22#include "CSSImageValue.h" 23 24#include "CSSCursorImageValue.h" 25#include "CSSParser.h" 26#include "CSSValueKeywords.h" 27#include "CachedImage.h" 28#include "CachedResourceLoader.h" 29#include "CachedResourceRequest.h" 30#include "CachedResourceRequestInitiators.h" 31#include "CrossOriginAccessControl.h" 32#include "Document.h" 33#include "Element.h" 34#include "MemoryCache.h" 35#include "StyleCachedImage.h" 36#include "StylePendingImage.h" 37 38namespace WebCore { 39 40CSSImageValue::CSSImageValue(const String& url) 41 : CSSValue(ImageClass) 42 , m_url(url) 43 , m_accessedImage(false) 44{ 45} 46 47CSSImageValue::CSSImageValue(const String& url, StyleImage* image) 48 : CSSValue(ImageClass) 49 , m_url(url) 50 , m_image(image) 51 , m_accessedImage(true) 52{ 53} 54 55inline void CSSImageValue::detachPendingImage() 56{ 57 if (m_image && m_image->isPendingImage()) 58 toStylePendingImage(*m_image).detachFromCSSValue(); 59} 60 61CSSImageValue::~CSSImageValue() 62{ 63 detachPendingImage(); 64} 65 66StyleImage* CSSImageValue::cachedOrPendingImage() 67{ 68 if (!m_image) 69 m_image = StylePendingImage::create(this); 70 71 return m_image.get(); 72} 73 74StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const ResourceLoaderOptions& options) 75{ 76 ASSERT(loader); 77 78 if (!m_accessedImage) { 79 m_accessedImage = true; 80 81 CachedResourceRequest request(ResourceRequest(loader->document()->completeURL(m_url)), options); 82 if (m_initiatorName.isEmpty()) 83 request.setInitiator(cachedResourceRequestInitiators().css); 84 else 85 request.setInitiator(m_initiatorName); 86 87 if (options.requestOriginPolicy() == PotentiallyCrossOriginEnabled) 88 updateRequestForAccessControl(request.mutableResourceRequest(), loader->document()->securityOrigin(), options.allowCredentials()); 89 90 if (CachedResourceHandle<CachedImage> cachedImage = loader->requestImage(request)) { 91 detachPendingImage(); 92 m_image = StyleCachedImage::create(cachedImage.get()); 93 } 94 } 95 96 return (m_image && m_image->isCachedImage()) ? toStyleCachedImage(m_image.get()) : nullptr; 97} 98 99StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader) 100{ 101 return cachedImage(loader, CachedResourceLoader::defaultCachedResourceOptions()); 102} 103 104bool CSSImageValue::hasFailedOrCanceledSubresources() const 105{ 106 if (!m_image || !m_image->isCachedImage()) 107 return false; 108 CachedResource* cachedResource = toStyleCachedImage(*m_image).cachedImage(); 109 if (!cachedResource) 110 return true; 111 return cachedResource->loadFailedOrCanceled(); 112} 113 114bool CSSImageValue::equals(const CSSImageValue& other) const 115{ 116 return m_url == other.m_url; 117} 118 119String CSSImageValue::customCSSText() const 120{ 121 return "url(" + quoteCSSURLIfNeeded(m_url) + ')'; 122} 123 124PassRefPtr<CSSValue> CSSImageValue::cloneForCSSOM() const 125{ 126 // NOTE: We expose CSSImageValues as URI primitive values in CSSOM to maintain old behavior. 127 RefPtr<CSSPrimitiveValue> uriValue = CSSPrimitiveValue::create(m_url, CSSPrimitiveValue::CSS_URI); 128 uriValue->setCSSOMSafe(); 129 return uriValue.release(); 130} 131 132bool CSSImageValue::knownToBeOpaque(const RenderElement* renderer) const 133{ 134 return m_image ? m_image->knownToBeOpaque(renderer) : false; 135} 136 137} // namespace WebCore 138