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 "Document.h"
32#include "Element.h"
33#include "MemoryCache.h"
34#include "StyleCachedImage.h"
35#include "StylePendingImage.h"
36
37namespace WebCore {
38
39CSSImageValue::CSSImageValue(const String& url)
40    : CSSValue(ImageClass)
41    , m_url(url)
42    , m_accessedImage(false)
43{
44}
45
46CSSImageValue::CSSImageValue(const String& url, StyleImage* image)
47    : CSSValue(ImageClass)
48    , m_url(url)
49    , m_image(image)
50    , m_accessedImage(true)
51{
52}
53
54inline void CSSImageValue::detachPendingImage()
55{
56    if (m_image && m_image->isPendingImage())
57        static_cast<StylePendingImage&>(*m_image).detachFromCSSValue();
58}
59
60CSSImageValue::~CSSImageValue()
61{
62    detachPendingImage();
63}
64
65StyleImage* CSSImageValue::cachedOrPendingImage()
66{
67    if (!m_image)
68        m_image = StylePendingImage::create(this);
69
70    return m_image.get();
71}
72
73StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader)
74{
75    ASSERT(loader);
76
77    if (!m_accessedImage) {
78        m_accessedImage = true;
79
80        CachedResourceRequest request(ResourceRequest(loader->document()->completeURL(m_url)));
81        if (m_initiatorName.isEmpty())
82            request.setInitiator(cachedResourceRequestInitiators().css);
83        else
84            request.setInitiator(m_initiatorName);
85        if (CachedResourceHandle<CachedImage> cachedImage = loader->requestImage(request)) {
86            detachPendingImage();
87            m_image = StyleCachedImage::create(cachedImage.get());
88        }
89    }
90
91    return (m_image && m_image->isCachedImage()) ? static_cast<StyleCachedImage*>(m_image.get()) : 0;
92}
93
94bool CSSImageValue::hasFailedOrCanceledSubresources() const
95{
96    if (!m_image || !m_image->isCachedImage())
97        return false;
98    CachedResource* cachedResource = static_cast<StyleCachedImage*>(m_image.get())->cachedImage();
99    if (!cachedResource)
100        return true;
101    return cachedResource->loadFailedOrCanceled();
102}
103
104bool CSSImageValue::equals(const CSSImageValue& other) const
105{
106    return m_url == other.m_url;
107}
108
109String CSSImageValue::customCssText() const
110{
111    return "url(" + quoteCSSURLIfNeeded(m_url) + ')';
112}
113
114PassRefPtr<CSSValue> CSSImageValue::cloneForCSSOM() const
115{
116    // NOTE: We expose CSSImageValues as URI primitive values in CSSOM to maintain old behavior.
117    RefPtr<CSSPrimitiveValue> uriValue = CSSPrimitiveValue::create(m_url, CSSPrimitiveValue::CSS_URI);
118    uriValue->setCSSOMSafe();
119    return uriValue.release();
120}
121
122bool CSSImageValue::knownToBeOpaque(const RenderObject* renderer) const
123{
124    return m_image ? m_image->knownToBeOpaque(renderer) : false;
125}
126
127} // namespace WebCore
128