2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "modules/filesystem/InspectorFileSystemAgent.h"
34 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
35 #include "bindings/core/v8/UnionTypesCore.h"
36 #include "core/dom/DOMArrayBuffer.h"
37 #include "core/dom/DOMImplementation.h"
38 #include "core/dom/Document.h"
39 #include "core/events/Event.h"
40 #include "core/fileapi/File.h"
41 #include "core/fileapi/FileCallback.h"
42 #include "core/fileapi/FileError.h"
43 #include "core/fileapi/FileReader.h"
44 #include "core/frame/LocalFrame.h"
45 #include "core/html/HTMLMediaElement.h"
46 #include "core/html/VoidCallback.h"
47 #include "core/html/parser/TextResourceDecoder.h"
48 #include "core/inspector/InspectorState.h"
49 #include "core/page/Page.h"
50 #include "modules/filesystem/DOMFileSystem.h"
51 #include "modules/filesystem/DirectoryEntry.h"
52 #include "modules/filesystem/DirectoryReader.h"
53 #include "modules/filesystem/EntriesCallback.h"
54 #include "modules/filesystem/Entry.h"
55 #include "modules/filesystem/EntryCallback.h"
56 #include "modules/filesystem/ErrorCallback.h"
57 #include "modules/filesystem/FileEntry.h"
58 #include "modules/filesystem/FileSystemCallbacks.h"
59 #include "modules/filesystem/LocalFileSystem.h"
60 #include "modules/filesystem/Metadata.h"
61 #include "modules/filesystem/MetadataCallback.h"
62 #include "platform/ContentType.h"
63 #include "platform/MIMETypeRegistry.h"
64 #include "platform/heap/Handle.h"
65 #include "platform/weborigin/KURL.h"
66 #include "platform/weborigin/SecurityOrigin.h"
67 #include "wtf/text/Base64.h"
68 #include "wtf/text/TextEncoding.h"
70 using blink::TypeBuilder::Array
;
72 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::RequestFileSystemRootCallback RequestFileSystemRootCallback
;
73 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::RequestDirectoryContentCallback RequestDirectoryContentCallback
;
74 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::RequestMetadataCallback RequestMetadataCallback
;
75 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::RequestFileContentCallback RequestFileContentCallback
;
76 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::DeleteEntryCallback DeleteEntryCallback
;
80 namespace FileSystemAgentState
{
81 static const char fileSystemAgentEnabled
[] = "fileSystemAgentEnabled";
86 template<typename BaseCallback
, typename Handler
, typename Argument
>
87 class GC_PLUGIN_IGNORE("crbug.com/513077") CallbackDispatcher final
: public BaseCallback
{
89 typedef bool (Handler::*HandlingMethod
)(Argument
);
91 static CallbackDispatcher
* create(PassRefPtrWillBeRawPtr
<Handler
> handler
, HandlingMethod handlingMethod
)
93 return new CallbackDispatcher(handler
, handlingMethod
);
96 void handleEvent(Argument argument
) override
98 (m_handler
.get()->*m_handlingMethod
)(argument
);
101 DEFINE_INLINE_TRACE()
103 visitor
->trace(m_handler
);
104 BaseCallback::trace(visitor
);
108 CallbackDispatcher(PassRefPtrWillBeRawPtr
<Handler
> handler
, HandlingMethod handlingMethod
)
110 , m_handlingMethod(handlingMethod
) { }
112 RefPtrWillBeMember
<Handler
> m_handler
;
113 HandlingMethod m_handlingMethod
;
116 template<typename BaseCallback
>
117 class CallbackDispatcherFactory
{
119 template<typename Handler
, typename Argument
>
120 static CallbackDispatcher
<BaseCallback
, Handler
, Argument
>* create(Handler
* handler
, bool (Handler::*handlingMethod
)(Argument
))
122 return CallbackDispatcher
<BaseCallback
, Handler
, Argument
>::create(PassRefPtrWillBeRawPtr
<Handler
>(handler
), handlingMethod
);
126 class FileSystemRootRequest final
: public RefCountedWillBeGarbageCollectedFinalized
<FileSystemRootRequest
> {
127 WTF_MAKE_NONCOPYABLE(FileSystemRootRequest
);
129 static PassRefPtrWillBeRawPtr
<FileSystemRootRequest
> create(PassRefPtrWillBeRawPtr
<RequestFileSystemRootCallback
> requestCallback
, const String
& type
)
131 return adoptRefWillBeNoop(new FileSystemRootRequest(requestCallback
, type
));
134 void start(ExecutionContext
*);
136 DEFINE_INLINE_TRACE()
138 visitor
->trace(m_requestCallback
);
142 bool didHitError(FileError
* error
)
144 reportResult(error
->code());
148 bool didGetEntry(Entry
*);
150 void reportResult(FileError::ErrorCode errorCode
, PassRefPtr
<TypeBuilder::FileSystem::Entry
> entry
= nullptr)
152 m_requestCallback
->sendSuccess(static_cast<int>(errorCode
), entry
);
155 FileSystemRootRequest(PassRefPtrWillBeRawPtr
<RequestFileSystemRootCallback
> requestCallback
, const String
& type
)
156 : m_requestCallback(requestCallback
)
159 RefPtrWillBeMember
<RequestFileSystemRootCallback
> m_requestCallback
;
163 void FileSystemRootRequest::start(ExecutionContext
* executionContext
)
165 ASSERT(executionContext
);
167 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &FileSystemRootRequest::didHitError
);
170 if (!DOMFileSystemBase::pathPrefixToFileSystemType(m_type
, type
)) {
171 errorCallback
->handleEvent(FileError::create(FileError::SYNTAX_ERR
));
175 KURL rootURL
= DOMFileSystemBase::createFileSystemRootURL(executionContext
->securityOrigin()->toString(), type
);
176 if (!rootURL
.isValid()) {
177 errorCallback
->handleEvent(FileError::create(FileError::SYNTAX_ERR
));
181 EntryCallback
* successCallback
= CallbackDispatcherFactory
<EntryCallback
>::create(this, &FileSystemRootRequest::didGetEntry
);
182 OwnPtr
<AsyncFileSystemCallbacks
> fileSystemCallbacks
= ResolveURICallbacks::create(successCallback
, errorCallback
, executionContext
);
183 LocalFileSystem::from(*executionContext
)->resolveURL(executionContext
, rootURL
, fileSystemCallbacks
.release());
186 bool FileSystemRootRequest::didGetEntry(Entry
* entry
)
188 RefPtr
<TypeBuilder::FileSystem::Entry
> result
= TypeBuilder::FileSystem::Entry::create()
189 .setUrl(entry
->toURL())
191 .setIsDirectory(true);
192 reportResult(static_cast<FileError::ErrorCode
>(0), result
);
196 class DirectoryContentRequest final
: public RefCountedWillBeGarbageCollectedFinalized
<DirectoryContentRequest
> {
197 WTF_MAKE_NONCOPYABLE(DirectoryContentRequest
);
199 static PassRefPtrWillBeRawPtr
<DirectoryContentRequest
> create(PassRefPtrWillBeRawPtr
<RequestDirectoryContentCallback
> requestCallback
, const String
& url
)
201 return adoptRefWillBeNoop(new DirectoryContentRequest(requestCallback
, url
));
204 ~DirectoryContentRequest()
208 void start(ExecutionContext
*);
210 DEFINE_INLINE_VIRTUAL_TRACE()
212 visitor
->trace(m_requestCallback
);
213 visitor
->trace(m_directoryReader
);
217 bool didHitError(FileError
* error
)
219 reportResult(error
->code());
223 bool didGetEntry(Entry
*);
224 bool didReadDirectoryEntries(const EntryHeapVector
&);
226 void reportResult(FileError::ErrorCode errorCode
, PassRefPtr
<Array
<TypeBuilder::FileSystem::Entry
>> entries
= nullptr)
228 m_requestCallback
->sendSuccess(static_cast<int>(errorCode
), entries
);
231 DirectoryContentRequest(PassRefPtrWillBeRawPtr
<RequestDirectoryContentCallback
> requestCallback
, const String
& url
)
232 : m_requestCallback(requestCallback
)
233 , m_url(ParsedURLString
, url
) { }
235 void readDirectoryEntries();
237 RefPtrWillBeMember
<RequestDirectoryContentCallback
> m_requestCallback
;
239 RefPtr
<Array
<TypeBuilder::FileSystem::Entry
>> m_entries
;
240 PersistentWillBeMember
<DirectoryReader
> m_directoryReader
;
243 void DirectoryContentRequest::start(ExecutionContext
* executionContext
)
245 ASSERT(executionContext
);
247 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &DirectoryContentRequest::didHitError
);
248 EntryCallback
* successCallback
= CallbackDispatcherFactory
<EntryCallback
>::create(this, &DirectoryContentRequest::didGetEntry
);
250 OwnPtr
<AsyncFileSystemCallbacks
> fileSystemCallbacks
= ResolveURICallbacks::create(successCallback
, errorCallback
, executionContext
);
252 LocalFileSystem::from(*executionContext
)->resolveURL(executionContext
, m_url
, fileSystemCallbacks
.release());
255 bool DirectoryContentRequest::didGetEntry(Entry
* entry
)
257 if (!entry
->isDirectory()) {
258 reportResult(FileError::TYPE_MISMATCH_ERR
);
262 m_directoryReader
= toDirectoryEntry(entry
)->createReader();
263 m_entries
= Array
<TypeBuilder::FileSystem::Entry
>::create();
264 readDirectoryEntries();
268 void DirectoryContentRequest::readDirectoryEntries()
270 if (!m_directoryReader
->filesystem()->executionContext()) {
271 reportResult(FileError::ABORT_ERR
);
275 EntriesCallback
* successCallback
= CallbackDispatcherFactory
<EntriesCallback
>::create(this, &DirectoryContentRequest::didReadDirectoryEntries
);
276 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &DirectoryContentRequest::didHitError
);
277 m_directoryReader
->readEntries(successCallback
, errorCallback
);
280 bool DirectoryContentRequest::didReadDirectoryEntries(const EntryHeapVector
& entries
)
282 if (entries
.isEmpty()) {
283 reportResult(static_cast<FileError::ErrorCode
>(0), m_entries
);
287 for (size_t i
= 0; i
< entries
.size(); ++i
) {
288 Entry
* entry
= entries
[i
];
289 RefPtr
<TypeBuilder::FileSystem::Entry
> entryForFrontend
= TypeBuilder::FileSystem::Entry::create()
290 .setUrl(entry
->toURL())
291 .setName(entry
->name())
292 .setIsDirectory(entry
->isDirectory());
294 using TypeBuilder::Page::ResourceType
;
295 if (!entry
->isDirectory()) {
296 String mimeType
= MIMETypeRegistry::getMIMETypeForPath(entry
->name());
297 ResourceType::Enum resourceType
;
298 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType
)) {
299 resourceType
= ResourceType::Image
;
300 entryForFrontend
->setIsTextFile(false);
301 } else if (HTMLMediaElement::supportsType(ContentType(mimeType
)) != WebMimeRegistry::IsNotSupported
) {
302 resourceType
= ResourceType::Media
;
303 entryForFrontend
->setIsTextFile(false);
304 } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType
)) {
305 resourceType
= ResourceType::Script
;
306 entryForFrontend
->setIsTextFile(true);
307 } else if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType
)) {
308 resourceType
= ResourceType::Document
;
309 entryForFrontend
->setIsTextFile(true);
311 resourceType
= ResourceType::Other
;
312 entryForFrontend
->setIsTextFile(DOMImplementation::isXMLMIMEType(mimeType
) || DOMImplementation::isTextMIMEType(mimeType
));
315 entryForFrontend
->setMimeType(mimeType
);
316 entryForFrontend
->setResourceType(resourceType
);
319 m_entries
->addItem(entryForFrontend
);
321 readDirectoryEntries();
325 class MetadataRequest final
: public RefCountedWillBeGarbageCollectedFinalized
<MetadataRequest
> {
326 WTF_MAKE_NONCOPYABLE(MetadataRequest
);
328 static PassRefPtrWillBeRawPtr
<MetadataRequest
> create(PassRefPtrWillBeRawPtr
<RequestMetadataCallback
> requestCallback
, const String
& url
)
330 return adoptRefWillBeNoop(new MetadataRequest(requestCallback
, url
));
337 void start(ExecutionContext
*);
339 DEFINE_INLINE_VIRTUAL_TRACE()
341 visitor
->trace(m_requestCallback
);
345 bool didHitError(FileError
* error
)
347 reportResult(error
->code());
351 bool didGetEntry(Entry
*);
352 bool didGetMetadata(Metadata
*);
354 void reportResult(FileError::ErrorCode errorCode
, PassRefPtr
<TypeBuilder::FileSystem::Metadata
> metadata
= nullptr)
356 m_requestCallback
->sendSuccess(static_cast<int>(errorCode
), metadata
);
359 MetadataRequest(PassRefPtrWillBeRawPtr
<RequestMetadataCallback
> requestCallback
, const String
& url
)
360 : m_requestCallback(requestCallback
)
361 , m_url(ParsedURLString
, url
) { }
363 RefPtrWillBeMember
<RequestMetadataCallback
> m_requestCallback
;
368 void MetadataRequest::start(ExecutionContext
* executionContext
)
370 ASSERT(executionContext
);
372 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &MetadataRequest::didHitError
);
373 EntryCallback
* successCallback
= CallbackDispatcherFactory
<EntryCallback
>::create(this, &MetadataRequest::didGetEntry
);
374 OwnPtr
<AsyncFileSystemCallbacks
> fileSystemCallbacks
= ResolveURICallbacks::create(successCallback
, errorCallback
, executionContext
);
375 LocalFileSystem::from(*executionContext
)->resolveURL(executionContext
, m_url
, fileSystemCallbacks
.release());
378 bool MetadataRequest::didGetEntry(Entry
* entry
)
380 if (!entry
->filesystem()->executionContext()) {
381 reportResult(FileError::ABORT_ERR
);
385 MetadataCallback
* successCallback
= CallbackDispatcherFactory
<MetadataCallback
>::create(this, &MetadataRequest::didGetMetadata
);
386 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &MetadataRequest::didHitError
);
387 entry
->getMetadata(successCallback
, errorCallback
);
388 m_isDirectory
= entry
->isDirectory();
392 bool MetadataRequest::didGetMetadata(Metadata
* metadata
)
394 using TypeBuilder::FileSystem::Metadata
;
395 RefPtr
<Metadata
> result
= Metadata::create()
396 .setModificationTime(metadata
->modificationTime())
397 .setSize(metadata
->size());
398 reportResult(static_cast<FileError::ErrorCode
>(0), result
);
402 class FileContentRequest final
: public EventListener
{
403 WTF_MAKE_NONCOPYABLE(FileContentRequest
);
405 static PassRefPtrWillBeRawPtr
<FileContentRequest
> create(PassRefPtrWillBeRawPtr
<RequestFileContentCallback
> requestCallback
, const String
& url
, bool readAsText
, long long start
, long long end
, const String
& charset
)
407 return adoptRefWillBeNoop(new FileContentRequest(requestCallback
, url
, readAsText
, start
, end
, charset
));
410 ~FileContentRequest() override
414 void start(ExecutionContext
*);
416 bool operator==(const EventListener
& other
) override
418 return this == &other
;
421 void handleEvent(ExecutionContext
*, Event
* event
) override
423 if (event
->type() == EventTypeNames::load
)
425 else if (event
->type() == EventTypeNames::error
)
426 didHitError(m_reader
->error());
429 DEFINE_INLINE_VIRTUAL_TRACE()
431 visitor
->trace(m_requestCallback
);
432 visitor
->trace(m_reader
);
433 EventListener::trace(visitor
);
437 bool didHitError(FileError
* error
)
439 reportResult(error
->code());
443 bool didGetEntry(Entry
*);
444 bool didGetFile(File
*);
447 void reportResult(FileError::ErrorCode errorCode
, const String
* result
= 0, const String
* charset
= 0)
449 m_requestCallback
->sendSuccess(static_cast<int>(errorCode
), result
, charset
);
452 FileContentRequest(PassRefPtrWillBeRawPtr
<RequestFileContentCallback
> requestCallback
, const String
& url
, bool readAsText
, long long start
, long long end
, const String
& charset
)
453 : EventListener(EventListener::CPPEventListenerType
)
454 , m_requestCallback(requestCallback
)
455 , m_url(ParsedURLString
, url
)
456 , m_readAsText(readAsText
)
459 , m_charset(charset
) { }
461 RefPtrWillBeMember
<RequestFileContentCallback
> m_requestCallback
;
469 PersistentWillBeMember
<FileReader
> m_reader
;
472 void FileContentRequest::start(ExecutionContext
* executionContext
)
474 ASSERT(executionContext
);
476 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &FileContentRequest::didHitError
);
477 EntryCallback
* successCallback
= CallbackDispatcherFactory
<EntryCallback
>::create(this, &FileContentRequest::didGetEntry
);
479 OwnPtr
<AsyncFileSystemCallbacks
> fileSystemCallbacks
= ResolveURICallbacks::create(successCallback
, errorCallback
, executionContext
);
480 LocalFileSystem::from(*executionContext
)->resolveURL(executionContext
, m_url
, fileSystemCallbacks
.release());
483 bool FileContentRequest::didGetEntry(Entry
* entry
)
485 if (entry
->isDirectory()) {
486 reportResult(FileError::TYPE_MISMATCH_ERR
);
490 if (!entry
->filesystem()->executionContext()) {
491 reportResult(FileError::ABORT_ERR
);
495 FileCallback
* successCallback
= CallbackDispatcherFactory
<FileCallback
>::create(this, &FileContentRequest::didGetFile
);
496 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &FileContentRequest::didHitError
);
497 toFileEntry(entry
)->file(successCallback
, errorCallback
);
499 m_reader
= FileReader::create(entry
->filesystem()->executionContext());
500 m_mimeType
= MIMETypeRegistry::getMIMETypeForPath(entry
->name());
505 bool FileContentRequest::didGetFile(File
* file
)
507 Blob
* blob
= file
->Blob::slice(m_start
, m_end
, IGNORE_EXCEPTION
);
508 m_reader
->setOnload(this);
509 m_reader
->setOnerror(this);
511 m_reader
->readAsArrayBuffer(blob
, IGNORE_EXCEPTION
);
515 void FileContentRequest::didRead()
517 StringOrArrayBuffer resultAttribute
;
518 m_reader
->result(resultAttribute
);
519 RefPtr
<DOMArrayBuffer
> buffer
= resultAttribute
.getAsArrayBuffer();
522 String result
= base64Encode(static_cast<char*>(buffer
->data()), buffer
->byteLength());
523 reportResult(static_cast<FileError::ErrorCode
>(0), &result
, 0);
527 OwnPtr
<TextResourceDecoder
> decoder
= TextResourceDecoder::create(m_mimeType
, m_charset
, true);
528 String result
= decoder
->decode(static_cast<char*>(buffer
->data()), buffer
->byteLength());
529 result
= result
+ decoder
->flush();
530 m_charset
= decoder
->encoding().name();
531 reportResult(static_cast<FileError::ErrorCode
>(0), &result
, &m_charset
);
534 class DeleteEntryRequest final
: public RefCountedWillBeGarbageCollectedFinalized
<DeleteEntryRequest
> {
536 static PassRefPtrWillBeRawPtr
<DeleteEntryRequest
> create(PassRefPtrWillBeRawPtr
<DeleteEntryCallback
> requestCallback
, const KURL
& url
)
538 return adoptRefWillBeNoop(new DeleteEntryRequest(requestCallback
, url
));
541 ~DeleteEntryRequest()
545 void start(ExecutionContext
*);
547 DEFINE_INLINE_TRACE()
549 visitor
->trace(m_requestCallback
);
553 // CallbackDispatcherFactory doesn't handle 0-arg handleEvent methods
554 class VoidCallbackImpl final
: public VoidCallback
{
556 explicit VoidCallbackImpl(PassRefPtrWillBeRawPtr
<DeleteEntryRequest
> handler
)
561 void handleEvent() override
563 m_handler
->didDeleteEntry();
566 DEFINE_INLINE_VIRTUAL_TRACE()
568 visitor
->trace(m_handler
);
569 VoidCallback::trace(visitor
);
573 RefPtrWillBeMember
<DeleteEntryRequest
> m_handler
;
576 bool didHitError(FileError
* error
)
578 reportResult(error
->code());
582 bool didGetEntry(Entry
*);
583 bool didDeleteEntry();
585 void reportResult(FileError::ErrorCode errorCode
)
587 m_requestCallback
->sendSuccess(static_cast<int>(errorCode
));
590 DeleteEntryRequest(PassRefPtrWillBeRawPtr
<DeleteEntryCallback
> requestCallback
, const KURL
& url
)
591 : m_requestCallback(requestCallback
)
594 RefPtrWillBeMember
<DeleteEntryCallback
> m_requestCallback
;
598 void DeleteEntryRequest::start(ExecutionContext
* executionContext
)
600 ASSERT(executionContext
);
602 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &DeleteEntryRequest::didHitError
);
606 if (!DOMFileSystemBase::crackFileSystemURL(m_url
, type
, path
)) {
607 errorCallback
->handleEvent(FileError::create(FileError::SYNTAX_ERR
));
612 VoidCallback
* successCallback
= new VoidCallbackImpl(this);
613 OwnPtr
<AsyncFileSystemCallbacks
> fileSystemCallbacks
= VoidCallbacks::create(successCallback
, errorCallback
, executionContext
, nullptr);
614 LocalFileSystem::from(*executionContext
)->deleteFileSystem(executionContext
, type
, fileSystemCallbacks
.release());
616 EntryCallback
* successCallback
= CallbackDispatcherFactory
<EntryCallback
>::create(this, &DeleteEntryRequest::didGetEntry
);
617 OwnPtr
<AsyncFileSystemCallbacks
> fileSystemCallbacks
= ResolveURICallbacks::create(successCallback
, errorCallback
, executionContext
);
618 LocalFileSystem::from(*executionContext
)->resolveURL(executionContext
, m_url
, fileSystemCallbacks
.release());
622 bool DeleteEntryRequest::didGetEntry(Entry
* entry
)
624 VoidCallback
* successCallback
= new VoidCallbackImpl(this);
625 ErrorCallback
* errorCallback
= CallbackDispatcherFactory
<ErrorCallback
>::create(this, &DeleteEntryRequest::didHitError
);
626 if (entry
->isDirectory()) {
627 DirectoryEntry
* directoryEntry
= toDirectoryEntry(entry
);
628 directoryEntry
->removeRecursively(successCallback
, errorCallback
);
630 entry
->remove(successCallback
, errorCallback
);
635 bool DeleteEntryRequest::didDeleteEntry()
637 reportResult(static_cast<FileError::ErrorCode
>(0));
641 } // anonymous namespace
644 PassOwnPtrWillBeRawPtr
<InspectorFileSystemAgent
> InspectorFileSystemAgent::create(Page
* page
)
646 return adoptPtrWillBeNoop(new InspectorFileSystemAgent(page
));
649 InspectorFileSystemAgent::~InspectorFileSystemAgent()
653 void InspectorFileSystemAgent::enable(ErrorString
*)
658 m_state
->setBoolean(FileSystemAgentState::fileSystemAgentEnabled
, m_enabled
);
661 void InspectorFileSystemAgent::disable(ErrorString
*)
666 m_state
->setBoolean(FileSystemAgentState::fileSystemAgentEnabled
, m_enabled
);
669 void InspectorFileSystemAgent::requestFileSystemRoot(ErrorString
* error
, const String
& origin
, const String
& type
, PassRefPtrWillBeRawPtr
<RequestFileSystemRootCallback
> requestCallback
)
671 if (!assertEnabled(error
))
674 ExecutionContext
* executionContext
= assertExecutionContextForOrigin(error
, SecurityOrigin::createFromString(origin
).get());
675 if (!executionContext
)
678 FileSystemRootRequest::create(requestCallback
, type
)->start(executionContext
);
681 void InspectorFileSystemAgent::requestDirectoryContent(ErrorString
* error
, const String
& url
, PassRefPtrWillBeRawPtr
<RequestDirectoryContentCallback
> requestCallback
)
683 if (!assertEnabled(error
))
686 ExecutionContext
* executionContext
= assertExecutionContextForOrigin(error
, SecurityOrigin::createFromString(url
).get());
687 if (!executionContext
)
690 DirectoryContentRequest::create(requestCallback
, url
)->start(executionContext
);
693 void InspectorFileSystemAgent::requestMetadata(ErrorString
* error
, const String
& url
, PassRefPtrWillBeRawPtr
<RequestMetadataCallback
> requestCallback
)
695 if (!assertEnabled(error
))
698 ExecutionContext
* executionContext
= assertExecutionContextForOrigin(error
, SecurityOrigin::createFromString(url
).get());
699 if (!executionContext
)
702 MetadataRequest::create(requestCallback
, url
)->start(executionContext
);
705 void InspectorFileSystemAgent::requestFileContent(ErrorString
* error
, const String
& url
, bool readAsText
, const int* start
, const int* end
, const String
* charset
, PassRefPtrWillBeRawPtr
<RequestFileContentCallback
> requestCallback
)
707 if (!assertEnabled(error
))
710 ExecutionContext
* executionContext
= assertExecutionContextForOrigin(error
, SecurityOrigin::createFromString(url
).get());
711 if (!executionContext
)
714 long long startPosition
= start
? *start
: 0;
715 long long endPosition
= end
? *end
: std::numeric_limits
<long long>::max();
716 FileContentRequest::create(requestCallback
, url
, readAsText
, startPosition
, endPosition
, charset
? *charset
: "")->start(executionContext
);
719 void InspectorFileSystemAgent::deleteEntry(ErrorString
* error
, const String
& urlString
, PassRefPtrWillBeRawPtr
<DeleteEntryCallback
> requestCallback
)
721 if (!assertEnabled(error
))
724 KURL
url(ParsedURLString
, urlString
);
726 ExecutionContext
* executionContext
= assertExecutionContextForOrigin(error
, SecurityOrigin::create(url
).get());
727 if (!executionContext
)
730 DeleteEntryRequest::create(requestCallback
, url
)->start(executionContext
);
733 void InspectorFileSystemAgent::restore()
735 m_enabled
= m_state
->getBoolean(FileSystemAgentState::fileSystemAgentEnabled
);
738 InspectorFileSystemAgent::InspectorFileSystemAgent(Page
* page
)
739 : InspectorBaseAgent
<InspectorFileSystemAgent
, InspectorFrontend::FileSystem
>("FileSystem")
746 bool InspectorFileSystemAgent::assertEnabled(ErrorString
* error
)
749 *error
= "FileSystem agent is not enabled.";
755 ExecutionContext
* InspectorFileSystemAgent::assertExecutionContextForOrigin(ErrorString
* error
, SecurityOrigin
* origin
)
757 for (Frame
* frame
= m_page
->mainFrame(); frame
; frame
= frame
->tree().traverseNext()) {
758 if (!frame
->isLocalFrame())
760 LocalFrame
* localFrame
= toLocalFrame(frame
);
761 if (localFrame
->document() && localFrame
->document()->securityOrigin()->isSameSchemeHostPort(origin
))
762 return localFrame
->document();
765 *error
= "No frame is available for the request";
769 DEFINE_TRACE(InspectorFileSystemAgent
)
771 visitor
->trace(m_page
);
772 InspectorBaseAgent::trace(visitor
);