Chromium Code Reviews| Index: Source/core/inspector/InspectorResourceContentLoader.cpp |
| diff --git a/Source/core/inspector/InspectorResourceContentLoader.cpp b/Source/core/inspector/InspectorResourceContentLoader.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..039b607acca7fe3437b3ef7e0e39445fa2ba3077 |
| --- /dev/null |
| +++ b/Source/core/inspector/InspectorResourceContentLoader.cpp |
| @@ -0,0 +1,138 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "config.h" |
| +#include "core/inspector/InspectorResourceContentLoader.h" |
| + |
| +#include "FetchInitiatorTypeNames.h" |
| +#include "core/css/CSSStyleSheet.h" |
| +#include "core/css/StyleSheetContents.h" |
| +#include "core/fetch/CSSStyleSheetResource.h" |
| +#include "core/fetch/Resource.h" |
| +#include "core/fetch/ResourceFetcher.h" |
| +#include "core/fetch/ResourcePtr.h" |
| +#include "core/fetch/StyleSheetResourceClient.h" |
| +#include "core/frame/LocalFrame.h" |
| +#include "core/html/VoidCallback.h" |
| +#include "core/inspector/InspectorCSSAgent.h" |
| +#include "core/inspector/InspectorPageAgent.h" |
| +#include "core/page/Page.h" |
| + |
| +namespace WebCore { |
| + |
| + |
| +class InspectorResourceContentLoader::ResourceClient FINAL : private StyleSheetResourceClient { |
|
apavlov
2014/06/18 14:33:59
IRCL::CSSResourceClient for clarity?
vsevik
2014/06/18 14:49:56
It is going to be used for document resource as we
|
| +public: |
| + ResourceClient(InspectorResourceContentLoader*); |
| + |
| + void waitForResource(Resource*); |
| +private: |
|
apavlov
2014/06/18 14:33:59
blank line above
vsevik
2014/06/18 14:49:56
Done.
|
| + InspectorResourceContentLoader* m_loader; |
| + |
| + virtual void setCSSStyleSheet(const String&, const KURL&, const String&, const CSSStyleSheetResource*) OVERRIDE; |
| + |
| + friend class InspectorResourceContentLoader; |
| +}; |
| + |
| +InspectorResourceContentLoader::ResourceClient::ResourceClient(InspectorResourceContentLoader* loader) |
|
apavlov
2014/06/18 14:33:59
This could be inlined into the class declaration
vsevik
2014/06/18 14:49:56
Done.
|
| + : m_loader(loader) |
| +{ |
| +} |
| + |
| +void InspectorResourceContentLoader::ResourceClient::waitForResource(Resource* resource) |
|
apavlov
2014/06/18 14:33:59
ditto - it is trivial
vsevik
2014/06/18 14:49:56
Done.
|
| +{ |
| + resource->addClient(this); |
| +} |
| + |
| +void InspectorResourceContentLoader::ResourceClient::setCSSStyleSheet(const String&, const KURL& url, const String&, const CSSStyleSheetResource* resource) |
| +{ |
| + if (m_loader) |
| + m_loader->resourceFinished(this); |
| + const_cast<CSSStyleSheetResource*>(resource)->removeClient(this); |
| + delete this; |
| +} |
| + |
| +InspectorResourceContentLoader::InspectorResourceContentLoader(Page* page) |
| + : m_allRequestsStarted(false) |
| +{ |
| + Vector<Document*> documents; |
| + for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) { |
| + if (!frame->isLocalFrame()) |
| + continue; |
| + LocalFrame* localFrame = toLocalFrame(frame); |
| + documents.append(localFrame->document()); |
| + documents.appendVector(InspectorPageAgent::importsForFrame(localFrame)); |
| + } |
| + for (Vector<Document*>::const_iterator it = documents.begin(); it != documents.end(); ++it) { |
|
apavlov
2014/06/18 14:33:59
docIt?
vsevik
2014/06/18 14:49:56
Done.
|
| + Document* document = *it; |
| + |
| + HashSet<String> urlsToFetch; |
| + Vector<CSSStyleSheet*> styleSheets; |
| + InspectorCSSAgent::collectAllDocumentStyleSheets(document, styleSheets); |
| + for (Vector<CSSStyleSheet*>::const_iterator it2 = styleSheets.begin(); it2 != styleSheets.end(); ++it2) { |
|
apavlov
2014/06/18 14:33:59
cssIt?
vsevik
2014/06/18 14:49:56
Done.
|
| + CSSStyleSheet* styleSheet = *it2; |
| + if (styleSheet->isInline() || !styleSheet->contents()->loadCompleted()) |
| + continue; |
| + String url = styleSheet->contents()->baseURL().string(); |
|
apavlov
2014/06/18 14:33:59
styleSheet->baseURL().string() for brevity
vsevik
2014/06/18 14:49:56
Done.
|
| + if (url.isEmpty() || urlsToFetch.contains(url)) |
| + continue; |
| + urlsToFetch.add(url); |
| + FetchRequest request(ResourceRequest(url), FetchInitiatorTypeNames::internal); |
| + ResourcePtr<Resource> resource = document->fetcher()->fetchCSSStyleSheet(request); |
| + // Prevent garbage collection by holding a reference to this resource. |
| + m_resources.append(resource.get()); |
|
apavlov
2014/06/18 14:33:59
This is not going to hold a reference to the resou
vsevik
2014/06/18 14:49:56
This will call an implicit ResourcePtr constructor
|
| + ResourceClient* resourceClient = new ResourceClient(this); |
| + m_pendingResourceClients.add(resourceClient); |
| + resourceClient->waitForResource(resource.get()); |
| + } |
| + } |
| + |
| + m_allRequestsStarted = true; |
| + checkDone(); |
| +} |
| + |
| +void InspectorResourceContentLoader::addListener(PassOwnPtr<VoidCallback> callback) |
| +{ |
| + m_callbacks.append(callback); |
| + checkDone(); |
| +} |
| + |
| +InspectorResourceContentLoader::~InspectorResourceContentLoader() |
| +{ |
| + stop(); |
| +} |
| + |
| +void InspectorResourceContentLoader::stop() |
| +{ |
| + HashSet<ResourceClient*> pendingResourceClients; |
| + m_pendingResourceClients.swap(pendingResourceClients); |
| + for (HashSet<ResourceClient*>::const_iterator it = pendingResourceClients.begin(); it != pendingResourceClients.end(); ++it) |
| + (*it)->m_loader = 0; |
| + m_resources.clear(); |
| + // Make sure all callbacks are called to prevent infinite waiting time. |
| + checkDone(); |
| +} |
| + |
| +bool InspectorResourceContentLoader::hasFinished() |
| +{ |
| + return m_allRequestsStarted && m_pendingResourceClients.size() == 0; |
| +} |
| + |
| +void InspectorResourceContentLoader::checkDone() |
| +{ |
| + if (!hasFinished()) |
| + return; |
| + Vector<OwnPtr<VoidCallback> > callbacks; |
| + callbacks.swap(m_callbacks); |
| + for (Vector<OwnPtr<VoidCallback> >::const_iterator it = callbacks.begin(); it != callbacks.end(); ++it) |
| + (*it)->handleEvent(); |
| +} |
| + |
| +void InspectorResourceContentLoader::resourceFinished(ResourceClient* client) |
| +{ |
| + m_pendingResourceClients.remove(client); |
| + checkDone(); |
| +} |
| + |
| +} // namespace WebCore |