From 75b020d2c331e7f9adcef288c7fc5c8ef9aa0498 Mon Sep 17 00:00:00 2001 From: "commit-queue@webkit.org" Date: Mon, 2 Jul 2012 14:12:04 +0000 Subject: [PATCH] Web Inspector: Add requestFileContent command and fileContentReceived event https://bugs.webkit.org/show_bug.cgi?id=89642 Patch by Taiju Tsuiki on 2012-07-02 Reviewed by Vsevolod Vlasov. Source/WebCore: Test: http/tests/inspector/filesystem/read-file.html * inspector/Inspector.json: * inspector/InspectorFileSystemAgent.cpp: (WebCore): (WebCore::InspectorFileSystemAgent::requestFileContent): * inspector/InspectorFileSystemAgent.h: (InspectorFileSystemAgent): * inspector/front-end/FileSystemModel.js: (WebInspector.FileSystemModel.prototype.requestMetadata): (WebInspector.FileSystemModel.prototype.requestFileContent): (WebInspector.FileSystemModel.File.prototype.get resourceType): (WebInspector.FileSystemModel.File.prototype.requestFileContent): (WebInspector.FileSystemRequestManager): (WebInspector.FileSystemRequestManager.prototype._metadataReceived): (WebInspector.FileSystemRequestManager.prototype.requestFileContent.requestAccepted): (WebInspector.FileSystemRequestManager.prototype.requestFileContent): (WebInspector.FileSystemRequestManager.prototype._fileContentReceived): (WebInspector.FileSystemDispatcher.prototype.metadataReceived): (WebInspector.FileSystemDispatcher.prototype.fileContentReceived): LayoutTests: * http/tests/inspector/filesystem/read-file-expected.txt: Added. * http/tests/inspector/filesystem/read-file.html: Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121676 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 10 ++ .../inspector/filesystem/read-file-expected.txt | 5 + .../http/tests/inspector/filesystem/read-file.html | 50 +++++++ Source/WebCore/ChangeLog | 28 ++++ Source/WebCore/inspector/Inspector.json | 25 +++- .../WebCore/inspector/InspectorFileSystemAgent.cpp | 145 +++++++++++++++++++++ .../WebCore/inspector/InspectorFileSystemAgent.h | 1 + .../WebCore/inspector/front-end/FileSystemModel.js | 68 ++++++++++ 8 files changed, 330 insertions(+), 2 deletions(-) create mode 100644 LayoutTests/http/tests/inspector/filesystem/read-file-expected.txt create mode 100644 LayoutTests/http/tests/inspector/filesystem/read-file.html diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index c5c73a8..58f5920 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,5 +1,15 @@ 2012-07-02 Taiju Tsuiki + Web Inspector: Add requestFileContent command and fileContentReceived event + https://bugs.webkit.org/show_bug.cgi?id=89642 + + Reviewed by Vsevolod Vlasov. + + * http/tests/inspector/filesystem/read-file-expected.txt: Added. + * http/tests/inspector/filesystem/read-file.html: Added. + +2012-07-02 Taiju Tsuiki + Web Inspector: Add refresh button to FileSystemView status bar https://bugs.webkit.org/show_bug.cgi?id=90244 diff --git a/LayoutTests/http/tests/inspector/filesystem/read-file-expected.txt b/LayoutTests/http/tests/inspector/filesystem/read-file-expected.txt new file mode 100644 index 0000000..0389774 --- /dev/null +++ b/LayoutTests/http/tests/inspector/filesystem/read-file-expected.txt @@ -0,0 +1,5 @@ +Tests readFile. + +errorCode = 0 +content = "UEFTUw==" [PASS] + diff --git a/LayoutTests/http/tests/inspector/filesystem/read-file.html b/LayoutTests/http/tests/inspector/filesystem/read-file.html new file mode 100644 index 0000000..34341d8 --- /dev/null +++ b/LayoutTests/http/tests/inspector/filesystem/read-file.html @@ -0,0 +1,50 @@ + + + + + + + + + +

Tests readFile.

+ + diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 5232c11..850c7c0 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,5 +1,33 @@ 2012-07-02 Taiju Tsuiki + Web Inspector: Add requestFileContent command and fileContentReceived event + https://bugs.webkit.org/show_bug.cgi?id=89642 + + Reviewed by Vsevolod Vlasov. + + Test: http/tests/inspector/filesystem/read-file.html + + * inspector/Inspector.json: + * inspector/InspectorFileSystemAgent.cpp: + (WebCore): + (WebCore::InspectorFileSystemAgent::requestFileContent): + * inspector/InspectorFileSystemAgent.h: + (InspectorFileSystemAgent): + * inspector/front-end/FileSystemModel.js: + (WebInspector.FileSystemModel.prototype.requestMetadata): + (WebInspector.FileSystemModel.prototype.requestFileContent): + (WebInspector.FileSystemModel.File.prototype.get resourceType): + (WebInspector.FileSystemModel.File.prototype.requestFileContent): + (WebInspector.FileSystemRequestManager): + (WebInspector.FileSystemRequestManager.prototype._metadataReceived): + (WebInspector.FileSystemRequestManager.prototype.requestFileContent.requestAccepted): + (WebInspector.FileSystemRequestManager.prototype.requestFileContent): + (WebInspector.FileSystemRequestManager.prototype._fileContentReceived): + (WebInspector.FileSystemDispatcher.prototype.metadataReceived): + (WebInspector.FileSystemDispatcher.prototype.fileContentReceived): + +2012-07-02 Taiju Tsuiki + Web Inspector: Add refresh button to FileSystemView status bar https://bugs.webkit.org/show_bug.cgi?id=90244 diff --git a/Source/WebCore/inspector/Inspector.json b/Source/WebCore/inspector/Inspector.json index 851606e..3711cf3 100644 --- a/Source/WebCore/inspector/Inspector.json +++ b/Source/WebCore/inspector/Inspector.json @@ -1471,6 +1471,18 @@ { "name": "requestId", "$ref": "RequestId", "description": "Request identifier. Corresponding metadataReceived event should have same requestId with this." } ], "description": "Returns metadata of the entry as metadataReceived event." + }, + { + "name": "requestFileContent", + "parameters": [ + { "name": "url", "type": "string", "description": "URL of the file that the frontend is requesting to read from." }, + { "name": "start", "type": "integer", "optional": true, "description": "Specifies the start of range to read." }, + { "name": "end", "type": "integer", "optional": true, "description": "Specifies the end of range to read exclusively." } + ], + "returns": [ + { "name": "requestId", "$ref": "RequestId", "description": "Request identifier. Corresponding fileContentReceived event should have same requestId with this." } + ], + "description": "Returns content of the file as fileContentReceived event. Result should be sliced into [start, end)." } ], "events": [ @@ -1495,11 +1507,20 @@ { "name": "metadataReceived", "parameters": [ - { "name": "requestId", "type": "integer", "description": "Request Identifier that was returned in response to the corresponding getMetadata request." }, + { "name": "requestId", "type": "integer", "description": "Request Identifier that was returned in response to the corresponding requestMetadata command." }, { "name": "errorCode", "type": "integer", "description": "0, if no error. Otherwise, errorCode is set to FileError::ErrorCode value." }, { "name": "metadata", "$ref": "FileSystem.Metadata", "optional": true, "description": "Contains metadata of the entry if the command completed successfully." } ], - "description": "Completion event of getMetadata command." + "description": "Completion event of requestMetadata command." + }, + { + "name": "fileContentReceived", + "parameters": [ + { "name": "requestId", "type": "integer", "description": "Request Identifier that was returned in response to the corresponding requestFileContent command." }, + { "name": "errorCode", "type": "integer", "description": "0, if no error. Otherwise, errorCode is set to FileError::ErrorCode value." }, + { "name": "content", "type": "string", "optional": true, "description": "Contains content of the file as base64 encoded string." } + ], + "description": "Completion event of requestFileContent command." } ] }, diff --git a/Source/WebCore/inspector/InspectorFileSystemAgent.cpp b/Source/WebCore/inspector/InspectorFileSystemAgent.cpp index 06206de..adafeea 100644 --- a/Source/WebCore/inspector/InspectorFileSystemAgent.cpp +++ b/Source/WebCore/inspector/InspectorFileSystemAgent.cpp @@ -34,15 +34,20 @@ #include "InspectorFileSystemAgent.h" +#include "Base64.h" #include "DOMFileSystem.h" #include "DirectoryEntry.h" #include "DirectoryReader.h" #include "Document.h" #include "EntriesCallback.h" +#include "Entry.h" #include "EntryArray.h" #include "EntryCallback.h" #include "ErrorCallback.h" +#include "FileCallback.h" +#include "FileEntry.h" #include "FileError.h" +#include "FileReader.h" #include "FileSystemCallback.h" #include "FileSystemCallbacks.h" #include "Frame.h" @@ -54,6 +59,7 @@ #include "MIMETypeRegistry.h" #include "Metadata.h" #include "MetadataCallback.h" +#include "ScriptExecutionContext.h" #include "SecurityOrigin.h" using WebCore::TypeBuilder::Array; @@ -400,6 +406,129 @@ bool GetMetadataTask::didGetMetadata(Metadata* metadata) return true; } +class ReadFileTask : public EventListener { + WTF_MAKE_NONCOPYABLE(ReadFileTask); +public: + static PassRefPtr create(PassRefPtr frontendProvider, int requestId, const String& url, long long start, long long end) + { + return adoptRef(new ReadFileTask(frontendProvider, requestId, url, start, end)); + } + + virtual ~ReadFileTask() + { + reportResult(FileError::ABORT_ERR, 0); + } + + void start(ScriptExecutionContext*); + + + virtual bool operator==(const EventListener& other) OVERRIDE + { + return this == &other; + } + + virtual void handleEvent(ScriptExecutionContext*, Event* event) OVERRIDE + { + if (event->type() == eventNames().loadEvent) + didRead(); + else if (event->type() == eventNames().errorEvent) + didHitError(m_reader->error().get()); + } + +private: + bool didHitError(FileError* error) + { + reportResult(error->code(), 0); + return true; + } + + bool didGetEntry(Entry*); + bool didGetFile(File*); + void didRead(); + + void reportResult(FileError::ErrorCode errorCode, const String* result) + { + if (!m_frontendProvider || !m_frontendProvider->frontend()) + return; + m_frontendProvider->frontend()->fileContentReceived(m_requestId, static_cast(errorCode), result); + m_frontendProvider = 0; + } + + ReadFileTask(PassRefPtr frontendProvider, int requestId, const String& url, long long start, long long end) + : EventListener(EventListener::CPPEventListenerType) + , m_frontendProvider(frontendProvider) + , m_requestId(requestId) + , m_url(ParsedURLString, url) + , m_start(start) + , m_end(end) + , m_current(start) { } + + RefPtr m_frontendProvider; + int m_requestId; + KURL m_url; + int m_start; + long long m_end; + long long m_current; + + RefPtr m_reader; +}; + +void ReadFileTask::start(ScriptExecutionContext* scriptExecutionContext) +{ + ASSERT(scriptExecutionContext); + + FileSystemType type; + String path; + if (!DOMFileSystemBase::crackFileSystemURL(m_url, type, path)) { + reportResult(FileError::SYNTAX_ERR, 0); + return; + } + + RefPtr successCallback = CallbackDispatcherFactory::create(this, &ReadFileTask::didGetEntry); + RefPtr errorCallback = CallbackDispatcherFactory::create(this, &ReadFileTask::didHitError); + OwnPtr fileSystemCallbacks = ResolveURICallbacks::create(successCallback, errorCallback, scriptExecutionContext, type, path); + + LocalFileSystem::localFileSystem().readFileSystem(scriptExecutionContext, type, fileSystemCallbacks.release()); +} + +bool ReadFileTask::didGetEntry(Entry* entry) +{ + if (entry->isDirectory()) { + reportResult(FileError::TYPE_MISMATCH_ERR, 0); + return true; + } + + if (!entry->filesystem()->scriptExecutionContext()) { + reportResult(FileError::ABORT_ERR, 0); + return true; + } + + RefPtr successCallback = CallbackDispatcherFactory::create(this, &ReadFileTask::didGetFile); + RefPtr errorCallback = CallbackDispatcherFactory::create(this, &ReadFileTask::didHitError); + static_cast(entry)->file(successCallback, errorCallback); + + m_reader = FileReader::create(entry->filesystem()->scriptExecutionContext()); + return true; +} + +bool ReadFileTask::didGetFile(File* file) +{ + RefPtr blob = file->slice(m_start, m_end); + m_reader->setOnload(this); + m_reader->setOnerror(this); + + ExceptionCode ec = 0; + m_reader->readAsArrayBuffer(blob.get(), ec); + return true; +} + +void ReadFileTask::didRead() +{ + RefPtr result = m_reader->arrayBufferResult(); + String encodedResult = base64Encode(static_cast(result->data()), result->byteLength()); + reportResult(static_cast(0), &encodedResult); +} + } // static @@ -478,6 +607,22 @@ void InspectorFileSystemAgent::requestMetadata(ErrorString* error, const String& m_frontendProvider->frontend()->metadataReceived(*requestId, static_cast(FileError::ABORT_ERR), 0); } +void InspectorFileSystemAgent::requestFileContent(ErrorString* error, const String& url, const int* start, const int* end, int* requestId) +{ + if (!m_enabled || !m_frontendProvider) { + *error = "FileSystem agent is not enabled"; + return; + } + ASSERT(m_frontendProvider->frontend()); + + *requestId = m_nextRequestId++; + + if (ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextForOrigin(SecurityOrigin::createFromString(url).get())) + ReadFileTask::create(m_frontendProvider, *requestId, url, start ? *start : 0, end ? *end : std::numeric_limits::max())->start(scriptExecutionContext); + else + m_frontendProvider->frontend()->fileContentReceived(*requestId, static_cast(FileError::ABORT_ERR), 0); +} + void InspectorFileSystemAgent::setFrontend(InspectorFrontend* frontend) { ASSERT(frontend); diff --git a/Source/WebCore/inspector/InspectorFileSystemAgent.h b/Source/WebCore/inspector/InspectorFileSystemAgent.h index 82f95c4..0e56b38 100644 --- a/Source/WebCore/inspector/InspectorFileSystemAgent.h +++ b/Source/WebCore/inspector/InspectorFileSystemAgent.h @@ -62,6 +62,7 @@ public: virtual void requestFileSystemRoot(ErrorString*, const String& origin, const String& type, int* requestId) OVERRIDE; virtual void requestDirectoryContent(ErrorString*, const String& url, int* requestId) OVERRIDE; virtual void requestMetadata(ErrorString*, const String& url, int* requestId) OVERRIDE; + virtual void requestFileContent(ErrorString*, const String& url, const int* start, const int* end, int* requestId) OVERRIDE; virtual void setFrontend(InspectorFrontend*) OVERRIDE; virtual void clearFrontend() OVERRIDE; diff --git a/Source/WebCore/inspector/front-end/FileSystemModel.js b/Source/WebCore/inspector/front-end/FileSystemModel.js index 8ba591f..41939ee 100644 --- a/Source/WebCore/inspector/front-end/FileSystemModel.js +++ b/Source/WebCore/inspector/front-end/FileSystemModel.js @@ -237,9 +237,24 @@ WebInspector.FileSystemModel.prototype = { callback(errorCode, entries); }, + /** + * @param {WebInspector.FileSystemModel.Entry} entry + * @param {function(number, FileSystemAgent.Metadata=)} callback + */ requestMetadata: function(entry, callback) { this._agentWrapper.requestMetadata(entry.url, callback); + }, + + /** + * @param {WebInspector.FileSystemModel.File} file + * @param {number} start + * @param {number} end + * @param {function(number, string=)} callback + */ + requestFileContent: function(file, start, end, callback) + { + this._agentWrapper.requestFileContent(file.url, start, end, callback); } } @@ -407,6 +422,16 @@ WebInspector.FileSystemModel.File.prototype = { get resourceType() { return this._resourceType; + }, + + /** + * @param {number} start + * @param {number} end + * @param {function(number, string=)} callback + */ + requestFileContent: function(start, end, callback) + { + this.fileSystemModel.requestFileContent(this, start, end, callback); } } @@ -420,6 +445,7 @@ WebInspector.FileSystemRequestManager = function() this._pendingFileSystemRootRequests = {}; this._pendingDirectoryContentRequests = {}; this._pendingMetadataRequests = {}; + this._pendingFileContentRequests = {}; InspectorBackend.registerFileSystemDispatcher(new WebInspector.FileSystemDispatcher(this)); FileSystemAgent.enable(); @@ -510,6 +536,38 @@ WebInspector.FileSystemRequestManager.prototype = { return; delete this._pendingMetadataRequests[requestId]; callback(errorCode, metadata); + }, + + /** + * @param {string} url + * @param {number} start + * @param {number} end + * @param {function(number, string)} callback + */ + requestFileContent: function(url, start, end, callback) + { + var store = this._pendingFileContentRequests; + FileSystemAgent.requestFileContent(url, start, end, requestAccepted); + + function requestAccepted(error, requestId) + { + if (!error) + store[requestId] = callback; + } + }, + + /** + * @param {number} requestId + * @param {number} errorCode + * @param {string=} content + */ + _fileContentReceived: function(requestId, errorCode, content) + { + var callback = /** @type {function(number, string=)} */ this._pendingFileContentRequests[requestId]; + if (!callback) + return; + delete this._pendingFileContentRequests[requestId]; + callback(errorCode, content); } } @@ -552,5 +610,15 @@ WebInspector.FileSystemDispatcher.prototype = { metadataReceived: function(requestId, errorCode, metadata) { this._agentWrapper._metadataReceived(requestId, errorCode, metadata); + }, + + /** + * @param {number} requestId + * @param {number} errorCode + * @param {string=} content + */ + fileContentReceived: function(requestId, errorCode, content) + { + this._agentWrapper._fileContentReceived(requestId, errorCode, content); } } -- 2.7.4