⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 applicationcachegroup.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    m_manifestHandle = 0;    // Check if the manifest was not modified.    if (isUpgradeAttempt) {        ApplicationCacheResource* newestManifest = m_newestCache->manifestResource();        ASSERT(newestManifest);            if (!m_manifestResource || // The resource will be null if HTTP response was 304 Not Modified.            newestManifest->data()->size() == m_manifestResource->data()->size() && !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size())) {            m_completionType = NoUpdate;            m_manifestResource = 0;            deliverDelayedMainResources();            return;        }    }        Manifest manifest;    if (!parseManifest(m_manifestURL, m_manifestResource->data()->data(), m_manifestResource->data()->size(), manifest)) {        cacheUpdateFailed();        return;    }    ASSERT(!m_cacheBeingUpdated);    m_cacheBeingUpdated = ApplicationCache::create();    m_cacheBeingUpdated->setGroup(this);    HashSet<DocumentLoader*>::const_iterator masterEnd = m_pendingMasterResourceLoaders.end();    for (HashSet<DocumentLoader*>::const_iterator iter = m_pendingMasterResourceLoaders.begin(); iter != masterEnd; ++iter)        associateDocumentLoaderWithCache(*iter, m_cacheBeingUpdated.get());    // We have the manifest, now download the resources.    m_updateStatus = Downloading;        postListenerTask(&DOMApplicationCache::callDownloadingListener, m_associatedDocumentLoaders);    ASSERT(m_pendingEntries.isEmpty());    if (isUpgradeAttempt) {        ApplicationCache::ResourceMap::const_iterator end = m_newestCache->end();        for (ApplicationCache::ResourceMap::const_iterator it = m_newestCache->begin(); it != end; ++it) {            unsigned type = it->second->type();            if (type & (ApplicationCacheResource::Master | ApplicationCacheResource::Dynamic))                addEntry(it->first, type);        }    }        HashSet<String>::const_iterator end = manifest.explicitURLs.end();    for (HashSet<String>::const_iterator it = manifest.explicitURLs.begin(); it != end; ++it)        addEntry(*it, ApplicationCacheResource::Explicit);    size_t fallbackCount = manifest.fallbackURLs.size();    for (size_t i = 0; i  < fallbackCount; ++i)        addEntry(manifest.fallbackURLs[i].second, ApplicationCacheResource::Fallback);        m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs);    m_cacheBeingUpdated->setFallbackURLs(manifest.fallbackURLs);        startLoadingEntry();}void ApplicationCacheGroup::cacheUpdateFailed(){    stopLoading();    m_manifestResource = 0;    // Wait for master resource loads to finish.    m_completionType = Failure;    deliverDelayedMainResources();}    void ApplicationCacheGroup::manifestNotFound(){    makeObsolete();    postListenerTask(&DOMApplicationCache::callObsoleteListener, m_associatedDocumentLoaders);    postListenerTask(&DOMApplicationCache::callErrorListener, m_pendingMasterResourceLoaders);    stopLoading();    ASSERT(m_pendingEntries.isEmpty());    m_manifestResource = 0;    while (!m_pendingMasterResourceLoaders.isEmpty()) {        HashSet<DocumentLoader*>::iterator it = m_pendingMasterResourceLoaders.begin();                ASSERT((*it)->candidateApplicationCacheGroup() == this);        ASSERT(!(*it)->applicationCache());        (*it)->setCandidateApplicationCacheGroup(0);        m_pendingMasterResourceLoaders.remove(it);    }    m_updateStatus = Idle;        m_frame = 0;        if (m_caches.isEmpty()) {        ASSERT(m_associatedDocumentLoaders.isEmpty());        ASSERT(!m_cacheBeingUpdated);        delete this;    }}void ApplicationCacheGroup::checkIfLoadIsComplete(){    if (m_manifestHandle || !m_pendingEntries.isEmpty() || !m_pendingMasterResourceLoaders.isEmpty())        return;        // We're done, all resources have finished downloading (successfully or not).    bool isUpgradeAttempt = m_newestCache;    switch (m_completionType) {    case None:        ASSERT_NOT_REACHED();        return;    case NoUpdate:        ASSERT(isUpgradeAttempt);        ASSERT(!m_cacheBeingUpdated);        ASSERT(m_storageID);        postListenerTask(&DOMApplicationCache::callNoUpdateListener, m_associatedDocumentLoaders);        break;    case Failure:        ASSERT(!m_cacheBeingUpdated);        postListenerTask(&DOMApplicationCache::callErrorListener, m_associatedDocumentLoaders);        if (m_caches.isEmpty()) {            ASSERT(m_associatedDocumentLoaders.isEmpty());            delete this;            return;        }        break;    case Completed: {        // FIXME: Fetch the resource from manifest URL again, and check whether it is identical to the one used for update (in case the application was upgraded server-side in the meanwhile). (<rdar://problem/6467625>)        ASSERT(m_cacheBeingUpdated);        m_cacheBeingUpdated->setManifestResource(m_manifestResource.release());        RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? 0 : m_newestCache;        setNewestCache(m_cacheBeingUpdated.release());        cacheStorage().storeNewestCache(this);        if (oldNewestCache)            cacheStorage().remove(oldNewestCache.get());        postListenerTask(isUpgradeAttempt ? &DOMApplicationCache::callUpdateReadyListener : &DOMApplicationCache::callCachedListener, m_associatedDocumentLoaders);        break;    }    }    m_completionType = None;    m_updateStatus = Idle;    m_frame = 0;}void ApplicationCacheGroup::startLoadingEntry(){    ASSERT(m_cacheBeingUpdated);    if (m_pendingEntries.isEmpty()) {        m_completionType = Completed;        deliverDelayedMainResources();        return;    }        EntryMap::const_iterator it = m_pendingEntries.begin();    postListenerTask(&DOMApplicationCache::callProgressListener, m_associatedDocumentLoaders);    ASSERT(!m_currentHandle);        m_currentHandle = createResourceHandle(KURL(it->first), m_newestCache ? m_newestCache->resourceForURL(it->first) : 0);}void ApplicationCacheGroup::deliverDelayedMainResources(){    // Need to copy loaders, because the cache group may be destroyed at the end of iteration.    Vector<DocumentLoader*> loaders;    copyToVector(m_pendingMasterResourceLoaders, loaders);    size_t count = loaders.size();    for (size_t i = 0; i != count; ++i) {        DocumentLoader* loader = loaders[i];        if (loader->isLoadingMainResource())            continue;        const ResourceError& error = loader->mainDocumentError();        if (error.isNull())            finishedLoadingMainResource(loader);        else            failedLoadingMainResource(loader);    }    if (!count)        checkIfLoadIsComplete();}void ApplicationCacheGroup::addEntry(const String& url, unsigned type){    ASSERT(m_cacheBeingUpdated);        // Don't add the URL if we already have an master resource in the cache    // (i.e., the main resource finished loading before the manifest).    if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) {        ASSERT(resource->type() & ApplicationCacheResource::Master);        ASSERT(!m_frame->loader()->documentLoader()->isLoadingMainResource());            resource->addType(type);        return;    }    // Don't add the URL if it's the same as the manifest URL.    ASSERT(m_manifestResource);    if (m_manifestResource->url() == url) {        m_manifestResource->addType(type);        return;    }        pair<EntryMap::iterator, bool> result = m_pendingEntries.add(url, type);        if (!result.second)        result.first->second |= type;}void ApplicationCacheGroup::associateDocumentLoaderWithCache(DocumentLoader* loader, ApplicationCache* cache){    // If teardown started already, revive the group.    if (!m_newestCache && !m_cacheBeingUpdated)        m_newestCache = cache;    ASSERT(!m_isObsolete);    loader->setApplicationCache(cache);    ASSERT(!m_associatedDocumentLoaders.contains(loader));    m_associatedDocumentLoaders.add(loader);} class CallCacheListenerTask : public ScriptExecutionContext::Task {    typedef void (DOMApplicationCache::*ListenerFunction)();public:    static PassRefPtr<CallCacheListenerTask> create(ListenerFunction listenerFunction)    {        return adoptRef(new CallCacheListenerTask(listenerFunction));    }    virtual void performTask(ScriptExecutionContext* context)    {        ASSERT(context->isDocument());        if (DOMWindow* window = static_cast<Document*>(context)->domWindow()) {            if (DOMApplicationCache* domCache = window->optionalApplicationCache())                (domCache->*m_listenerFunction)();        }    }private:    CallCacheListenerTask(ListenerFunction listenerFunction)        : m_listenerFunction(listenerFunction)    {    }    ListenerFunction m_listenerFunction;};void ApplicationCacheGroup::postListenerTask(ListenerFunction listenerFunction, const HashSet<DocumentLoader*>& loaderSet){    HashSet<DocumentLoader*>::const_iterator loaderSetEnd = loaderSet.end();    for (HashSet<DocumentLoader*>::const_iterator iter = loaderSet.begin(); iter != loaderSetEnd; ++iter)        postListenerTask(listenerFunction, *iter);}void ApplicationCacheGroup::postListenerTask(ListenerFunction listenerFunction, DocumentLoader* loader){    Frame* frame = loader->frame();    if (!frame)        return;        ASSERT(frame->loader()->documentLoader() == loader);    frame->document()->postTask(CallCacheListenerTask::create(listenerFunction));}void ApplicationCacheGroup::clearStorageID(){    m_storageID = 0;        HashSet<ApplicationCache*>::const_iterator end = m_caches.end();    for (HashSet<ApplicationCache*>::const_iterator it = m_caches.begin(); it != end; ++it)        (*it)->clearStorageID();}    }#endif // ENABLE(OFFLINE_WEB_APPLICATIONS)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -