Home | History | Annotate | Download | only in cache
      1 /*
      2     Copyright (C) 1998 Lars Knoll (knoll (at) mpi-hd.mpg.de)
      3     Copyright (C) 2001 Dirk Mueller (mueller (at) kde.org)
      4     Copyright (C) 2002 Waldo Bastian (bastian (at) kde.org)
      5     Copyright (C) 2006 Samuel Weinig (sam.weinig (at) gmail.com)
      6     Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
      7 
      8     This library is free software; you can redistribute it and/or
      9     modify it under the terms of the GNU Library General Public
     10     License as published by the Free Software Foundation; either
     11     version 2 of the License, or (at your option) any later version.
     12 
     13     This library is distributed in the hope that it will be useful,
     14     but WITHOUT ANY WARRANTY; without even the implied warranty of
     15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16     Library General Public License for more details.
     17 
     18     You should have received a copy of the GNU Library General Public License
     19     along with this library; see the file COPYING.LIB.  If not, write to
     20     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     21     Boston, MA 02110-1301, USA.
     22 
     23     This class provides all functionality needed for loading images, style sheets and html
     24     pages from the web. It has a memory cache for these objects.
     25 */
     26 
     27 #include "config.h"
     28 #include "CachedScript.h"
     29 
     30 #include "MemoryCache.h"
     31 #include "CachedResourceClient.h"
     32 #include "CachedResourceClientWalker.h"
     33 #include "SharedBuffer.h"
     34 #include "TextResourceDecoder.h"
     35 #include <wtf/Vector.h>
     36 
     37 #if USE(JSC)
     38 #include <parser/SourceProvider.h>
     39 #endif
     40 
     41 namespace WebCore {
     42 
     43 CachedScript::CachedScript(const String& url, const String& charset)
     44     : CachedResource(url, Script)
     45     , m_decoder(TextResourceDecoder::create("application/javascript", charset))
     46     , m_decodedDataDeletionTimer(this, &CachedScript::decodedDataDeletionTimerFired)
     47 {
     48     // It's javascript we want.
     49     // But some websites think their scripts are <some wrong mimetype here>
     50     // and refuse to serve them if we only accept application/x-javascript.
     51     setAccept("*/*");
     52 }
     53 
     54 CachedScript::~CachedScript()
     55 {
     56 }
     57 
     58 void CachedScript::didAddClient(CachedResourceClient* c)
     59 {
     60     if (m_decodedDataDeletionTimer.isActive())
     61         m_decodedDataDeletionTimer.stop();
     62 
     63     CachedResource::didAddClient(c);
     64 }
     65 
     66 void CachedScript::allClientsRemoved()
     67 {
     68     if (double interval = memoryCache()->deadDecodedDataDeletionInterval())
     69         m_decodedDataDeletionTimer.startOneShot(interval);
     70 }
     71 
     72 void CachedScript::setEncoding(const String& chs)
     73 {
     74     m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
     75 }
     76 
     77 String CachedScript::encoding() const
     78 {
     79     return m_decoder->encoding().name();
     80 }
     81 
     82 const String& CachedScript::script()
     83 {
     84     ASSERT(!isPurgeable());
     85 
     86     if (!m_script && m_data) {
     87         m_script = m_decoder->decode(m_data->data(), encodedSize());
     88         m_script += m_decoder->flush();
     89         setDecodedSize(m_script.length() * sizeof(UChar));
     90     }
     91     m_decodedDataDeletionTimer.startOneShot(0);
     92 
     93     return m_script;
     94 }
     95 
     96 void CachedScript::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
     97 {
     98     if (!allDataReceived)
     99         return;
    100 
    101     m_data = data;
    102     setEncodedSize(m_data.get() ? m_data->size() : 0);
    103     setLoading(false);
    104     checkNotify();
    105 }
    106 
    107 void CachedScript::error(CachedResource::Status status)
    108 {
    109     setStatus(status);
    110     ASSERT(errorOccurred());
    111     setLoading(false);
    112     checkNotify();
    113 }
    114 
    115 void CachedScript::destroyDecodedData()
    116 {
    117     m_script = String();
    118     unsigned extraSize = 0;
    119 #if USE(JSC)
    120     if (m_sourceProviderCache && m_clients.isEmpty())
    121         m_sourceProviderCache->clear();
    122 
    123     extraSize = m_sourceProviderCache ? m_sourceProviderCache->byteSize() : 0;
    124 #endif
    125     setDecodedSize(extraSize);
    126     if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
    127         makePurgeable(true);
    128 }
    129 
    130 void CachedScript::decodedDataDeletionTimerFired(Timer<CachedScript>*)
    131 {
    132     destroyDecodedData();
    133 }
    134 
    135 #if USE(JSC)
    136 JSC::SourceProviderCache* CachedScript::sourceProviderCache() const
    137 {
    138     if (!m_sourceProviderCache)
    139         m_sourceProviderCache = adoptPtr(new JSC::SourceProviderCache);
    140     return m_sourceProviderCache.get();
    141 }
    142 
    143 void CachedScript::sourceProviderCacheSizeChanged(int delta)
    144 {
    145     setDecodedSize(decodedSize() + delta);
    146 }
    147 #endif
    148 
    149 } // namespace WebCore
    150