| Index: Source/core/inspector/InspectorPageAgent.cpp
|
| diff --git a/Source/core/inspector/InspectorPageAgent.cpp b/Source/core/inspector/InspectorPageAgent.cpp
|
| index 51f34a4baad00791969311c8a6eacd217e689107..37ae986d8c7552339654f789149983a697905eee 100644
|
| --- a/Source/core/inspector/InspectorPageAgent.cpp
|
| +++ b/Source/core/inspector/InspectorPageAgent.cpp
|
| @@ -47,6 +47,9 @@
|
| #include "core/fetch/ResourceFetcher.h"
|
| #include "core/fetch/ScriptResource.h"
|
| #include "core/fetch/TextResourceDecoder.h"
|
| +#include "core/fileapi/Blob.h"
|
| +#include "core/fileapi/FileReaderLoader.h"
|
| +#include "core/fileapi/FileReaderLoaderClient.h"
|
| #include "core/html/HTMLFrameOwnerElement.h"
|
| #include "core/inspector/ContentSearchUtils.h"
|
| #include "core/inspector/DOMPatchSupport.h"
|
| @@ -77,6 +80,8 @@
|
| #include "wtf/text/Base64.h"
|
| #include "wtf/text/TextEncoding.h"
|
|
|
| +typedef WebCore::InspectorBackendDispatcher::PageCommandHandler::GetResourceContentCallback GetResourceContentCallback;
|
| +
|
| namespace WebCore {
|
|
|
| namespace PageAgentState {
|
| @@ -101,6 +106,66 @@ static const char forceCompositingMode[] = "forceCompositingMode";
|
|
|
| namespace {
|
|
|
| +class InspectorPageFileReaderLoaderClient : public FileReaderLoaderClient {
|
| + WTF_MAKE_NONCOPYABLE(InspectorPageFileReaderLoaderClient);
|
| +public:
|
| + InspectorPageFileReaderLoaderClient(PassRefPtr<GetResourceContentCallback> callback)
|
| + : m_callback(callback) { }
|
| +
|
| + void didStartLoading()
|
| + {
|
| + ASSERT(m_loader);
|
| + }
|
| +
|
| + void didReceiveData()
|
| + {
|
| + ASSERT(m_loader);
|
| + }
|
| +
|
| + void didFinishLoading()
|
| + {
|
| + ASSERT(m_loader);
|
| + if (!m_decoder) {
|
| + m_callback->sendSuccess(String(""), false);
|
| + } else {
|
| + RefPtr<ArrayBuffer> buffer = m_loader->arrayBufferResult();
|
| + String content = m_decoder->decode(static_cast<const char*>(buffer->data()), buffer->byteLength());
|
| + m_callback->sendSuccess(content + m_decoder->flush(), false);
|
| + }
|
| + dispose();
|
| + }
|
| +
|
| + void didFail(FileError::ErrorCode errorCode)
|
| + {
|
| + m_callback->sendFailure("Failed to load Blob: error code = " + String::number(errorCode)); // FIXME: Generate human-friendly reason message.
|
| + dispose();
|
| + }
|
| +
|
| + void setLoader(PassOwnPtr<FileReaderLoader> loader)
|
| + {
|
| + m_loader = loader;
|
| + }
|
| +
|
| + void start(Document* document, PassRefPtr<Blob> prpBlob, const String& textEncodingName)
|
| + {
|
| + ASSERT(m_loader);
|
| + RefPtr<Blob> blob = prpBlob;
|
| + m_decoder = InspectorPageAgent::createXHRTextDecoder(blob->type(), textEncodingName);
|
| + m_loader->start(document, *blob);
|
| + }
|
| +
|
| +private:
|
| + void dispose()
|
| + {
|
| + m_loader.clear();
|
| + delete this;
|
| + }
|
| +
|
| + OwnPtr<FileReaderLoader> m_loader;
|
| + RefPtr<GetResourceContentCallback> m_callback;
|
| + RefPtr<TextResourceDecoder> m_decoder;
|
| +};
|
| +
|
| KURL urlWithoutFragment(const KURL& url)
|
| {
|
| KURL result = url;
|
| @@ -122,12 +187,18 @@ static bool decodeBuffer(const char* buffer, unsigned size, const String& textEn
|
| return false;
|
| }
|
|
|
| -static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize)
|
| +static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize, bool* hasBlob)
|
| {
|
| *hasZeroSize = false;
|
| + *hasBlob = false;
|
| if (!cachedResource)
|
| return false;
|
|
|
| + if (!cachedResource->response().downloadedFilePath().isEmpty()) {
|
| + *hasBlob = true;
|
| + return true;
|
| + }
|
| +
|
| // Zero-sized resources don't have data at all -- so fake the empty buffer, instead of indicating error by returning 0.
|
| if (!cachedResource->encodedSize()) {
|
| *hasZeroSize = true;
|
| @@ -154,7 +225,7 @@ static bool hasTextContent(Resource* cachedResource)
|
| return type == InspectorPageAgent::DocumentResource || type == InspectorPageAgent::StylesheetResource || type == InspectorPageAgent::ScriptResource || type == InspectorPageAgent::XHRResource;
|
| }
|
|
|
| -static PassRefPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeType, const String& textEncodingName)
|
| +PassRefPtr<TextResourceDecoder> InspectorPageAgent::createXHRTextDecoder(const String& mimeType, const String& textEncodingName)
|
| {
|
| RefPtr<TextResourceDecoder> decoder;
|
| if (!textEncodingName.isEmpty())
|
| @@ -169,13 +240,24 @@ static PassRefPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeTy
|
| return decoder;
|
| }
|
|
|
| -bool InspectorPageAgent::cachedResourceContent(Resource* cachedResource, String* result, bool* base64Encoded)
|
| +bool InspectorPageAgent::cachedResourceContentOrBlob(Resource* cachedResource, String* result, bool* base64Encoded, RefPtr<Blob>* blob, String* textEncodingName)
|
| {
|
| bool hasZeroSize;
|
| - bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize);
|
| + bool hasBlob;
|
| + bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize, &hasBlob);
|
| if (!prepared)
|
| return false;
|
|
|
| + if (hasBlob) {
|
| + const String& filePath = cachedResource->response().downloadedFilePath();
|
| + OwnPtr<BlobData> blobData = BlobData::create();
|
| + blobData->appendFile(filePath);
|
| + blobData->setContentType(cachedResource->response().mimeType());
|
| + *blob = Blob::create(blobData.release(), cachedResource->encodedSize());
|
| + *textEncodingName = cachedResource->response().textEncodingName();
|
| + return true;
|
| + }
|
| +
|
| *base64Encoded = !hasTextContent(cachedResource);
|
| if (*base64Encoded) {
|
| RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer();
|
| @@ -244,12 +326,12 @@ PassOwnPtr<InspectorPageAgent> InspectorPageAgent::create(InstrumentingAgents* i
|
| }
|
|
|
| // static
|
| -void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame, const KURL& url, String* result, bool* base64Encoded)
|
| +void InspectorPageAgent::resourceContentOrBlob(ErrorString* errorString, Frame* frame, const KURL& url, String* result, bool* base64Encoded, RefPtr<Blob>* blob, String* textEncodingName)
|
| {
|
| DocumentLoader* loader = assertDocumentLoader(errorString, frame);
|
| if (!loader)
|
| return;
|
| - if (!cachedResourceContent(cachedResource(frame, url), result, base64Encoded))
|
| + if (!cachedResourceContentOrBlob(cachedResource(frame, url), result, base64Encoded, blob, textEncodingName))
|
| *errorString = "No resource with given URL found";
|
| }
|
|
|
| @@ -569,12 +651,38 @@ void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page:
|
| object = buildObjectForFrameTree(m_page->mainFrame());
|
| }
|
|
|
| -void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, String* content, bool* base64Encoded)
|
| +void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, PassRefPtr<GetResourceContentCallback> prpCallback)
|
| {
|
| + RefPtr<GetResourceContentCallback> callback = prpCallback;
|
| + if (!callback->isActive())
|
| + return;
|
| +
|
| Frame* frame = assertFrame(errorString, frameId);
|
| if (!frame)
|
| return;
|
| - resourceContent(errorString, frame, KURL(ParsedURLString, url), content, base64Encoded);
|
| +
|
| + Document* document = frame->document();
|
| + if (!document) {
|
| + *errorString = "No Document instance for the specified frame";
|
| + return;
|
| + }
|
| +
|
| + String content;
|
| + bool base64Encoded;
|
| + RefPtr<Blob> blob;
|
| + String textEncodingName;
|
| + resourceContentOrBlob(errorString, frame, KURL(ParsedURLString, url), &content, &base64Encoded, &blob, &textEncodingName);
|
| + if (!errorString->isEmpty())
|
| + return;
|
| +
|
| + if (blob) {
|
| + InspectorPageFileReaderLoaderClient* client = new InspectorPageFileReaderLoaderClient(callback);
|
| + OwnPtr<FileReaderLoader> loader = adoptPtr(new FileReaderLoader(FileReaderLoader::ReadAsArrayBuffer, client));
|
| + client->setLoader(loader.release());
|
| + client->start(document, blob.release(), textEncodingName);
|
| + } else {
|
| + callback->sendSuccess(content, base64Encoded);
|
| + }
|
| }
|
|
|
| static bool textContentForResource(Resource* cachedResource, String* result)
|
| @@ -582,9 +690,12 @@ static bool textContentForResource(Resource* cachedResource, String* result)
|
| if (hasTextContent(cachedResource)) {
|
| String content;
|
| bool base64Encoded;
|
| - if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) {
|
| + RefPtr<Blob> blob;
|
| + String textEncodingName;
|
| + if (InspectorPageAgent::cachedResourceContentOrBlob(cachedResource, result, &base64Encoded, &blob, &textEncodingName)) {
|
| ASSERT(!base64Encoded);
|
| - return true;
|
| + if (!blob)
|
| + return true;
|
| }
|
| }
|
| return false;
|
|
|