[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

kinuko at chromium.org kinuko at chromium.org
Wed Dec 22 13:56:18 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 727bb25be768605bc2e6c2fecdf9d89709073e12
Author: kinuko at chromium.org <kinuko at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Sep 30 01:16:43 2010 +0000

    2010-09-29  Kinuko Yasuda  <kinuko at chromium.org>
    
            Reviewed by David Levin.
    
            Fix DirectoryReader's behavior to trigger only one EntriesCallback per readEntries
            https://bugs.webkit.org/show_bug.cgi?id=46563
    
            * src/WebFileSystemCallbacksImpl.cpp:
            (WebKit::WebFileSystemCallbacksImpl::didReadDirectory):
    2010-09-29  Kinuko Yasuda  <kinuko at chromium.org>
    
            Reviewed by David Levin.
    
            Fix DirectoryReader's behavior to trigger only one EntriesCallback per readEntries
            https://bugs.webkit.org/show_bug.cgi?id=46563
    
            Test: fast/filesystem/read-directory.html
    
            * fileapi/DOMFileSystem.cpp:
            (WebCore::DOMFileSystem::readDirectory): Changed to take DirectoryReader
            as a parameter.
            * fileapi/DOMFileSystem.h:
            (WebCore::DOMFileSystem::scheduleCallback): Added.
            * fileapi/DirectoryReader.cpp:
            (WebCore::DirectoryReader::DirectoryReader): Added initializer for
            m_hasMore flag.
            (WebCore::DirectoryReader::readEntries): Changed to schedule
            EntriesCallback with an empty array if m_hasMore flag is set false.
            * fileapi/DirectoryReader.h:
            (WebCore::DirectoryReader::filesystem): Added.
            (WebCore::DirectoryReader::setHasMore): Added.
            * fileapi/FileSystemCallbacks.cpp:
            (WebCore::EntriesCallbacks::create):
            (WebCore::EntriesCallbacks::EntriesCallbacks): Changed to take
            DirectoryReader as a parameter.
            (WebCore::EntriesCallbacks::didReadDirectoryEntry):
            (WebCore::EntriesCallbacks::didReadDirectoryEntries): Changed 1) not to
            trigger the second callback when hasMore is false, and 2) to update
            the DirectoryReader's m_hasMore flag.
            * fileapi/FileSystemCallbacks.h:
    2010-09-29  Kinuko Yasuda  <kinuko at chromium.org>
    
            Reviewed by David Levin.
    
            Fix DirectoryReader's behavior to trigger only one EntriesCallback per readEntries
            https://bugs.webkit.org/show_bug.cgi?id=46563
    
            * fast/filesystem/flags-passing.html: Updated to make it match
            with the updated TEMPLATE.html.
            * fast/filesystem/flags-passing-expected.txt: Updated.
            * fast/filesystem/read-directory.html: Added.
            * fast/filesystem/read-directory-expected.txt: Added.
            * fast/filesystem/resources/fs-test-util.js: Added for common test
            utilities.
            * fast/filesystem/script-tests/TEMPLATE.html: Updated to include
            fs-test-util.js.
            * fast/filesystem/script-tests/flags-passing.js: Updated to use
            jsTestIsAsync and finishJSTest (so that all the tests look alike).
            * fast/filesystem/script-tests/read-directory.js: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@68735 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 1de34da..789131c 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,23 @@
+2010-09-29  Kinuko Yasuda  <kinuko at chromium.org>
+
+        Reviewed by David Levin.
+
+        Fix DirectoryReader's behavior to trigger only one EntriesCallback per readEntries
+        https://bugs.webkit.org/show_bug.cgi?id=46563
+
+        * fast/filesystem/flags-passing.html: Updated to make it match
+        with the updated TEMPLATE.html.
+        * fast/filesystem/flags-passing-expected.txt: Updated.
+        * fast/filesystem/read-directory.html: Added.
+        * fast/filesystem/read-directory-expected.txt: Added.
+        * fast/filesystem/resources/fs-test-util.js: Added for common test
+        utilities.
+        * fast/filesystem/script-tests/TEMPLATE.html: Updated to include
+        fs-test-util.js.
+        * fast/filesystem/script-tests/flags-passing.js: Updated to use
+        jsTestIsAsync and finishJSTest (so that all the tests look alike).
+        * fast/filesystem/script-tests/read-directory.js: Added.
+
 2010-09-29  MORITA Hajime  <morrita at google.com>
 
         Unreviewed, updated expectations.
diff --git a/LayoutTests/fast/filesystem/flags-passing-expected.txt b/LayoutTests/fast/filesystem/flags-passing-expected.txt
index 330c83f..575a7f6 100644
--- a/LayoutTests/fast/filesystem/flags-passing-expected.txt
+++ b/LayoutTests/fast/filesystem/flags-passing-expected.txt
@@ -3,9 +3,6 @@ Passing Flags parameter tests. This test checks if passing Flags parameters (in
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS successfullyParsed is true
-
-TEST COMPLETE
 * Passing a Flags object.
 * Recycling the same Flags object.
 * Passing a Flags object (with exclusive=true).
@@ -14,4 +11,7 @@ TEST COMPLETE
 Finished running tests.
 PASS expectedCallbacksCount is 3
 PASS unexpectedCallbacksCount is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
 
diff --git a/LayoutTests/fast/filesystem/flags-passing.html b/LayoutTests/fast/filesystem/flags-passing.html
index 70add66..f347446 100644
--- a/LayoutTests/fast/filesystem/flags-passing.html
+++ b/LayoutTests/fast/filesystem/flags-passing.html
@@ -2,6 +2,7 @@
 <head>
 <link rel="stylesheet" href="../js/resources/js-test-style.css">
 <script src="../js/resources/js-test-pre.js"></script>
+<script src="resources/fs-test-util.js"></script>
 </head>
 <body>
 <p id="description"></p>
diff --git a/LayoutTests/fast/filesystem/read-directory-expected.txt b/LayoutTests/fast/filesystem/read-directory-expected.txt
new file mode 100644
index 0000000..c2600e1
--- /dev/null
+++ b/LayoutTests/fast/filesystem/read-directory-expected.txt
@@ -0,0 +1,24 @@
+DirectoryReader.readEntries() test.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Successfully obtained Persistent FileSystem:TestShellFileSystem
+PASS readEntriesCount is entriesCallbackCount
+PASS resultEntries.length is testEntriesCount
+Entry:/a isDirectory:true
+PASS testEntries[entry.fullPath] is entry.isDirectory
+Entry:/b isDirectory:false
+PASS testEntries[entry.fullPath] is entry.isDirectory
+Entry:/c isDirectory:true
+PASS testEntries[entry.fullPath] is entry.isDirectory
+Entry:/d isDirectory:false
+PASS testEntries[entry.fullPath] is entry.isDirectory
+Entry:/e isDirectory:false
+PASS testEntries[entry.fullPath] is entry.isDirectory
+Entry:/f isDirectory:true
+PASS testEntries[entry.fullPath] is entry.isDirectory
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/filesystem/read-directory.html b/LayoutTests/fast/filesystem/read-directory.html
new file mode 100644
index 0000000..f83a966
--- /dev/null
+++ b/LayoutTests/fast/filesystem/read-directory.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script src="resources/fs-test-util.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/read-directory.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/filesystem/resources/fs-test-util.js b/LayoutTests/fast/filesystem/resources/fs-test-util.js
new file mode 100644
index 0000000..9eddcb5
--- /dev/null
+++ b/LayoutTests/fast/filesystem/resources/fs-test-util.js
@@ -0,0 +1,128 @@
+// Usage:
+//   var helper = new JoinHelper;
+//
+//   helper.run(function() { /* do something that eventually calls helper.done(); */ });
+//   helper.run(function() { /* do something that eventually calls helper.done(); */ });
+//   ...
+//   helper.join(joinCallback);
+//
+var JoinHelper = function()
+{
+    this.pendingOperations = [];
+    this.pendingOperationCount = 0;
+    this.joinCallback = null;
+
+    this.run = function(operation)
+    {
+        this.pendingOperationCount++;
+        operation();
+    };
+
+    // Call this when an operation is done.
+    this.done = function()
+    {
+        this.pendingOperationCount--;
+        if (this.pendingOperationCount == 0 && this.joinCallback)
+            this.joinCallback();
+    };
+
+    // This eventually calls the joinCallback when helper.done() is called as many times as helper.run() is called.
+    this.join = function(joinCallback)
+    {
+        if (this.pendingOperationCount == 0)
+            joinCallback();
+        else
+            this.joinCallback = joinCallback;
+    };
+};
+
+// FIXME: replace this code with the equivalent File API method once it fully supports removeRecursively.
+function removeRecursively(directory, successCallback, errorCallback) {
+    var RemoveRecursiveHelper = function(successCallback, errorCallback) {
+        this.removeDirMap = {};
+        this.successCallback = successCallback;
+        this.errorCallback = errorCallback;
+
+        this.removeRecursively = function(directory)
+        {
+            this.removeRecursivelyInternal(directory);
+        };
+
+        this.hasMoreEntries = function(hash)
+        {
+            for (k in hash)
+                return true;
+            return false;
+        };
+
+        this.bind = function(callback, arg1, arg2, arg3)
+        {
+            var obj = this;
+            return function(arg) {
+                if (arg == undefined)
+                    callback.apply(obj, [arg1, arg2, arg3]);
+                else
+                    callback.apply(obj, [arg, arg1, arg2, arg3]);
+            };
+        };
+
+        this.removeDirectory = function(directory, parentDirectory)
+        {
+            if (directory.fullPath != '/') {
+                // Ok to remove the parent directory.
+                directory.remove(this.bind(this.entryRemovedCallback, parentDirectory, directory), this.bind(this.ErrorCallback));
+            } else
+                delete this.removeDirMap[directory.fullPath];
+            if (!this.hasMoreEntries(this.removeDirMap) && this.successCallback)
+                this.successCallback();
+        };
+
+        this.entryRemovedCallback = function(directory, entry)
+        {
+            if (entry.isDirectory)
+                delete this.removeDirMap[entry.fullPath];
+
+            if (directory) {
+                var dirInfo = this.removeDirMap[directory.fullPath];
+                if (--dirInfo.entries == 0 && dirInfo.hasMore == false)
+                    this.removeDirectory(directory, dirInfo.parentDirectory);
+            }
+        };
+
+        this.removeRecursivelyCallback = function(entries, directory)
+        {
+            for (var i = 0; i < entries.length; ++i) {
+                this.removeDirMap[directory.fullPath].entries++;
+                if (entries[i].isDirectory)
+                    this.removeRecursivelyInternal(entries[i], directory);
+                else {
+                    var entry = entries[i];
+                    entry.remove(this.bind(this.entryRemovedCallback, directory, entry), this.bind(this.errorCallback));
+                }
+            }
+            if (entries.length) {
+                this.removeDirMap[directory.fullPath].reader.readEntries(this.bind(this.removeRecursivelyCallback, directory), this.bind(this.errorCallback));
+            } else {
+                var dirInfo = this.removeDirMap[directory.fullPath];
+                dirInfo.hasMore = false;
+                if (dirInfo.entries == 0)
+                    this.removeDirectory(directory, dirInfo.parentDirectory);
+            }
+        };
+
+        this.removeRecursivelyInternal = function(directory, parentDirectory)
+        {
+            directoryReader = directory.createReader();
+            this.removeDirMap[directory.fullPath] = {
+                hasMore: true,
+                parentDirectory: parentDirectory,
+                entries: 0,
+                reader: directoryReader,
+            };
+            directoryReader.readEntries(this.bind(this.removeRecursivelyCallback, directory), this.bind(this.errorCallback));
+        };
+    };
+
+    var helper = new RemoveRecursiveHelper(successCallback, errorCallback);
+    helper.removeRecursively(directory);
+}
diff --git a/LayoutTests/fast/filesystem/script-tests/TEMPLATE.html b/LayoutTests/fast/filesystem/script-tests/TEMPLATE.html
index 8a1a15e..f207f1f 100644
--- a/LayoutTests/fast/filesystem/script-tests/TEMPLATE.html
+++ b/LayoutTests/fast/filesystem/script-tests/TEMPLATE.html
@@ -2,6 +2,7 @@
 <head>
 <link rel="stylesheet" href="../js/resources/js-test-style.css">
 <script src="../js/resources/js-test-pre.js"></script>
+<script src="resources/fs-test-util.js"></script>
 </head>
 <body>
 <p id="description"></p>
diff --git a/LayoutTests/fast/filesystem/script-tests/flags-passing.js b/LayoutTests/fast/filesystem/script-tests/flags-passing.js
index 4b27229..0789a99 100644
--- a/LayoutTests/fast/filesystem/script-tests/flags-passing.js
+++ b/LayoutTests/fast/filesystem/script-tests/flags-passing.js
@@ -16,26 +16,19 @@ var testsList = [
 ];
 var testCounter = 0;
 
-function endTest() {
-    debug("Finished running tests.");
-    shouldBe('expectedCallbacksCount', '3');
-    shouldBe('unexpectedCallbacksCount', '0');
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
 function runNextTest(v) {
-    if (testCounter == testsList.length)
-        endTest();
-    else
+    if (testCounter == testsList.length) {
+        debug("Finished running tests.");
+        shouldBe('expectedCallbacksCount', '3');
+        shouldBe('unexpectedCallbacksCount', '0');
+        finishJSTest();
+    } else
         this[testsList[testCounter++]]();
 }
 
 function errorCallback(error) {
     debug("Error occured during requesting Temporary FileSystem:" + error.code);
-
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
+    finishJSTest();
 }
 
 // Test body functions ----------------------------------------------------
@@ -93,11 +86,9 @@ function fileSystemCallback(fs) {
 }
 
 if (window.requestFileSystem) {
-    if (window.layoutTestController)
-        layoutTestController.waitUntilDone();
-
     requestFileSystem(window.TEMPORARY, 100, fileSystemCallback, errorCallback);
+    window.jsTestIsAsync = true;
 } else
     debug("This test requires FileSystem API support.");
 
-var successfullyParsed = true;
+window.successfullyParsed = true;
diff --git a/LayoutTests/fast/filesystem/script-tests/read-directory.js b/LayoutTests/fast/filesystem/script-tests/read-directory.js
new file mode 100644
index 0000000..3b4857f
--- /dev/null
+++ b/LayoutTests/fast/filesystem/script-tests/read-directory.js
@@ -0,0 +1,97 @@
+description("DirectoryReader.readEntries() test.");
+var fileSystem = null;
+var reader = null;
+var resultEntries = [];
+
+var readEntriesCount = 0;
+var entriesCallbackCount = 0;
+
+// path: isDirectory map.
+var testEntries = {
+    '/a': true,
+    '/b': false,
+    '/c': true,
+    '/d': false,
+    '/e': false,
+    '/f': true,
+};
+var testEntriesCount = 0;
+
+function endTest()
+{
+    removeRecursively(fileSystem.root);
+    finishJSTest();
+}
+
+function errorCallback(error)
+{
+    debug("Error occured:" + error.code);
+    endTest();
+}
+
+var entry = null;
+function verifyTestResult()
+{
+    shouldBe('readEntriesCount', 'entriesCallbackCount');
+    shouldBe('resultEntries.length', 'testEntriesCount');
+    resultEntries.sort(function(a, b) { return (a.fullPath > b.fullPath) ? 1 : (a.fullPath < b.fullPath) ? -1 : 0; });
+    for (i = 0; i < resultEntries.length; ++i) {
+        entry = resultEntries[i];
+        debug('Entry:' + entry.fullPath + ' isDirectory:' + entry.isDirectory);
+        shouldBe('testEntries[entry.fullPath]', 'entry.isDirectory');
+    }
+}
+
+function entriesCallback(entries)
+{
+    entriesCallbackCount++;
+
+    for (var i = 0; i < entries.length; ++i)
+        resultEntries.push(entries[i]);
+
+    if (entries.length) {
+        readEntriesCount++;
+        reader.readEntries(entriesCallback, errorCallback);
+    } else {
+        // Must have read all the entries.
+        verifyTestResult();
+        endTest();
+    }
+}
+
+function runReadDirectoryTest()
+{
+    readEntriesCount++;
+    reader = fileSystem.root.createReader();
+    reader.readEntries(entriesCallback, errorCallback);
+}
+
+function prepareForTest()
+{
+    var helper = new JoinHelper();
+    var done = function() { helper.done(); };
+
+    for (var path in testEntries) {
+        testEntriesCount++;
+        if (testEntries[path])
+            helper.run(function() { fileSystem.root.getDirectory(path, {create:true}, done, errorCallback); });
+        else
+            helper.run(function() { fileSystem.root.getFile(path, {create:true}, done, errorCallback); });
+    }
+    helper.join(runReadDirectoryTest);
+}
+
+function successCallback(fs)
+{
+    fileSystem = fs;
+    debug("Successfully obtained Persistent FileSystem:" + fileSystem.name);
+    removeRecursively(fileSystem.root, prepareForTest, errorCallback);
+}
+
+if (window.requestFileSystem) {
+    requestFileSystem(window.TEMPORARY, 100, successCallback, errorCallback);
+    window.jsTestIsAsync = true;
+} else
+    debug("This test requires FileSystem API support.");
+
+window.successfullyParsed = true;
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index f20398a..660ed2a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,35 @@
+2010-09-29  Kinuko Yasuda  <kinuko at chromium.org>
+
+        Reviewed by David Levin.
+
+        Fix DirectoryReader's behavior to trigger only one EntriesCallback per readEntries
+        https://bugs.webkit.org/show_bug.cgi?id=46563
+
+        Test: fast/filesystem/read-directory.html
+
+        * fileapi/DOMFileSystem.cpp:
+        (WebCore::DOMFileSystem::readDirectory): Changed to take DirectoryReader
+        as a parameter.
+        * fileapi/DOMFileSystem.h:
+        (WebCore::DOMFileSystem::scheduleCallback): Added.
+        * fileapi/DirectoryReader.cpp:
+        (WebCore::DirectoryReader::DirectoryReader): Added initializer for
+        m_hasMore flag.
+        (WebCore::DirectoryReader::readEntries): Changed to schedule
+        EntriesCallback with an empty array if m_hasMore flag is set false.
+        * fileapi/DirectoryReader.h:
+        (WebCore::DirectoryReader::filesystem): Added.
+        (WebCore::DirectoryReader::setHasMore): Added.
+        * fileapi/FileSystemCallbacks.cpp:
+        (WebCore::EntriesCallbacks::create):
+        (WebCore::EntriesCallbacks::EntriesCallbacks): Changed to take
+        DirectoryReader as a parameter.
+        (WebCore::EntriesCallbacks::didReadDirectoryEntry):
+        (WebCore::EntriesCallbacks::didReadDirectoryEntries): Changed 1) not to
+        trigger the second callback when hasMore is false, and 2) to update
+        the DirectoryReader's m_hasMore flag.
+        * fileapi/FileSystemCallbacks.h:
+
 2010-09-29  Chris Rogers  <crogers at google.com>
 
         Reviewed by Kenneth Russell.
diff --git a/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp b/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp
index fc8cf98..a44131a 100644
--- a/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp
@@ -70,8 +70,8 @@ v8::Handle<v8::Value> V8DirectoryEntry::getDirectoryCallback(const v8::Arguments
             flags->setExclusive(isExclusive);
         }
     } else {
-       EXCEPTION_BLOCK(Flags*, tmp_flags, V8Flags::HasInstance(args[1]) ? V8Flags::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0);
-       flags = tmp_flags;
+        EXCEPTION_BLOCK(Flags*, tmp_flags, V8Flags::HasInstance(args[1]) ? V8Flags::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0);
+        flags = tmp_flags;
     }
     RefPtr<EntryCallback> successCallback;
     if (args.Length() > 2 && !args[2]->IsNull() && !args[2]->IsUndefined()) {
diff --git a/WebCore/fileapi/DOMFileSystem.cpp b/WebCore/fileapi/DOMFileSystem.cpp
index 2bd09c2..b1b1cdc 100644
--- a/WebCore/fileapi/DOMFileSystem.cpp
+++ b/WebCore/fileapi/DOMFileSystem.cpp
@@ -214,11 +214,11 @@ void DOMFileSystem::createWriter(const FileEntry* file, PassRefPtr<FileWriterCal
     m_asyncFileSystem->createWriter(fileWriter.get(), platformPath, callbacks.release());
 }
 
-void DOMFileSystem::readDirectory(const String& path, PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
+void DOMFileSystem::readDirectory(DirectoryReader* reader, const String& path, PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
 {
     ASSERT(DOMFilePath::isAbsolute(path));
     String platformPath = m_asyncFileSystem->virtualToPlatformPath(path);
-    m_asyncFileSystem->readDirectory(platformPath, EntriesCallbacks::create(successCallback, errorCallback, this, path));
+    m_asyncFileSystem->readDirectory(platformPath, EntriesCallbacks::create(successCallback, errorCallback, reader, path));
 }
 
 } // namespace
diff --git a/WebCore/fileapi/DOMFileSystem.h b/WebCore/fileapi/DOMFileSystem.h
index 881ffc5..8498e75 100644
--- a/WebCore/fileapi/DOMFileSystem.h
+++ b/WebCore/fileapi/DOMFileSystem.h
@@ -44,6 +44,7 @@
 namespace WebCore {
 
 class DirectoryEntry;
+class DirectoryReader;
 class Entry;
 class EntryCallback;
 class EntriesCallback;
@@ -78,13 +79,20 @@ public:
     void getParent(const Entry* entry, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
     void getFile(const Entry* base, const String& path, PassRefPtr<Flags>, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
     void getDirectory(const Entry* base, const String& path, PassRefPtr<Flags>, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>);
-    void readDirectory(const String& path, PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>);
+    void readDirectory(DirectoryReader* reader, const String& path, PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>);
     void createWriter(const FileEntry* file, PassRefPtr<FileWriterCallback>, PassRefPtr<ErrorCallback>);
 
     // Schedule a callback. This should not cross threads (should be called on the same context thread).
+    // FIXME: move this to a more generic place.
     template <typename CB, typename CBArg>
     static void scheduleCallback(ScriptExecutionContext*, PassRefPtr<CB>, PassRefPtr<CBArg>);
 
+    template <typename CB, typename CBArg>
+    void scheduleCallback(PassRefPtr<CB> callback, PassRefPtr<CBArg> callbackArg)
+    {
+        scheduleCallback(scriptExecutionContext(), callback, callbackArg);
+    }
+
 private:
     DOMFileSystem(ScriptExecutionContext*, const String& name, PassOwnPtr<AsyncFileSystem>);
 
diff --git a/WebCore/fileapi/DirectoryReader.cpp b/WebCore/fileapi/DirectoryReader.cpp
index b0eef1c..092f976 100644
--- a/WebCore/fileapi/DirectoryReader.cpp
+++ b/WebCore/fileapi/DirectoryReader.cpp
@@ -35,6 +35,7 @@
 
 #include "DOMFileSystem.h"
 #include "EntriesCallback.h"
+#include "EntryArray.h"
 #include "ErrorCallback.h"
 
 namespace WebCore {
@@ -42,12 +43,17 @@ namespace WebCore {
 DirectoryReader::DirectoryReader(PassRefPtr<DOMFileSystem> fileSystem, const String& fullPath)
     : m_fileSystem(fileSystem)
     , m_fullPath(fullPath)
+    , m_hasMore(true)
 {
 }
 
 void DirectoryReader::readEntries(PassRefPtr<EntriesCallback> entriesCallback, PassRefPtr<ErrorCallback> errorCallback)
 {
-    m_fileSystem->readDirectory(m_fullPath, entriesCallback, errorCallback);
+    if (!m_hasMore) {
+        m_fileSystem->scheduleCallback(entriesCallback, EntryArray::create());
+        return;
+    }
+    m_fileSystem->readDirectory(this, m_fullPath, entriesCallback, errorCallback);
 }
 
 } // namespace
diff --git a/WebCore/fileapi/DirectoryReader.h b/WebCore/fileapi/DirectoryReader.h
index 0e2ef0f..3358853 100644
--- a/WebCore/fileapi/DirectoryReader.h
+++ b/WebCore/fileapi/DirectoryReader.h
@@ -41,6 +41,7 @@
 namespace WebCore {
 
 class EntriesCallback;
+class EntriesCallbacks;
 class ErrorCallback;
 
 class DirectoryReader : public RefCounted<DirectoryReader> {
@@ -50,13 +51,16 @@ public:
         return adoptRef(new DirectoryReader(fileSystem, path));
     }
 
-    void readEntries(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback = 0);
+    DOMFileSystem* filesystem() const { return m_fileSystem.get(); }
+    void readEntries(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback> = 0);
+    void setHasMore(bool hasMore) { m_hasMore = hasMore; }
 
 private:
     DirectoryReader(PassRefPtr<DOMFileSystem> fileSystem, const String& path);
 
     RefPtr<DOMFileSystem> m_fileSystem;
     String m_fullPath;
+    bool m_hasMore;
 };
 
 } // namespace
diff --git a/WebCore/fileapi/FileSystemCallbacks.cpp b/WebCore/fileapi/FileSystemCallbacks.cpp
index 550b509..516f627 100644
--- a/WebCore/fileapi/FileSystemCallbacks.cpp
+++ b/WebCore/fileapi/FileSystemCallbacks.cpp
@@ -38,6 +38,7 @@
 #include "DOMFilePath.h"
 #include "DOMFileSystem.h"
 #include "DirectoryEntry.h"
+#include "DirectoryReader.h"
 #include "EntriesCallback.h"
 #include "EntryArray.h"
 #include "EntryCallback.h"
@@ -137,39 +138,34 @@ void EntryCallbacks::didSucceed()
 
 // EntriesCallbacks -----------------------------------------------------------
 
-PassOwnPtr<EntriesCallbacks> EntriesCallbacks::create(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DOMFileSystem* fileSystem, const String& basePath)
+PassOwnPtr<EntriesCallbacks> EntriesCallbacks::create(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DirectoryReader* directoryReader, const String& basePath)
 {
-    return adoptPtr(new EntriesCallbacks(successCallback, errorCallback, fileSystem, basePath));
+    return adoptPtr(new EntriesCallbacks(successCallback, errorCallback, directoryReader, basePath));
 }
 
-EntriesCallbacks::EntriesCallbacks(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DOMFileSystem* fileSystem, const String& basePath)
+EntriesCallbacks::EntriesCallbacks(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, DirectoryReader* directoryReader, const String& basePath)
     : FileSystemCallbacksBase(errorCallback)
     , m_successCallback(successCallback)
-    , m_fileSystem(fileSystem)
+    , m_directoryReader(directoryReader)
     , m_basePath(basePath)
     , m_entries(EntryArray::create())
 {
+    ASSERT(m_directoryReader);
 }
 
 void EntriesCallbacks::didReadDirectoryEntry(const String& name, bool isDirectory)
 {
     if (isDirectory)
-        m_entries->append(DirectoryEntry::create(m_fileSystem, DOMFilePath::append(m_basePath, name)));
+        m_entries->append(DirectoryEntry::create(m_directoryReader->filesystem(), DOMFilePath::append(m_basePath, name)));
     else
-        m_entries->append(FileEntry::create(m_fileSystem, DOMFilePath::append(m_basePath, name)));
+        m_entries->append(FileEntry::create(m_directoryReader->filesystem(), DOMFilePath::append(m_basePath, name)));
 }
 
 void EntriesCallbacks::didReadDirectoryEntries(bool hasMore)
 {
-    if (m_successCallback) {
+    m_directoryReader->setHasMore(hasMore);
+    if (m_successCallback)
         m_successCallback->handleEvent(m_entries.get());
-        if (!m_entries->isEmpty() && !hasMore) {
-            // If we have returned some entries and there're no more coming entries (hasMore==false), call back once more with an empty array.
-            m_successCallback->handleEvent(EntryArray::create().get());
-            m_successCallback.clear();
-        }
-        m_entries->clear();
-    }
 }
 
 // FileSystemCallbacks --------------------------------------------------------
diff --git a/WebCore/fileapi/FileSystemCallbacks.h b/WebCore/fileapi/FileSystemCallbacks.h
index 3647ad3..7f186ef 100644
--- a/WebCore/fileapi/FileSystemCallbacks.h
+++ b/WebCore/fileapi/FileSystemCallbacks.h
@@ -42,6 +42,7 @@ namespace WebCore {
 
 class AsyncFileWriter;
 class DOMFileSystem;
+class DirectoryReader;
 class ErrorCallback;
 class EntriesCallback;
 class EntryArray;
@@ -98,14 +99,14 @@ private:
 
 class EntriesCallbacks : public FileSystemCallbacksBase {
 public:
-    static PassOwnPtr<EntriesCallbacks> create(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DOMFileSystem*, const String& basePath);
+    static PassOwnPtr<EntriesCallbacks> create(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DirectoryReader*, const String& basePath);
     virtual void didReadDirectoryEntry(const String& name, bool isDirectory);
     virtual void didReadDirectoryEntries(bool hasMore);
 
 private:
-    EntriesCallbacks(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DOMFileSystem*, const String& basePath);
+    EntriesCallbacks(PassRefPtr<EntriesCallback>, PassRefPtr<ErrorCallback>, DirectoryReader*, const String& basePath);
     RefPtr<EntriesCallback> m_successCallback;
-    DOMFileSystem* m_fileSystem;
+    DirectoryReader* m_directoryReader;
     String m_basePath;
     RefPtr<EntryArray> m_entries;
 };
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 2d67832..bd0459e 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,13 @@
+2010-09-29  Kinuko Yasuda  <kinuko at chromium.org>
+
+        Reviewed by David Levin.
+
+        Fix DirectoryReader's behavior to trigger only one EntriesCallback per readEntries
+        https://bugs.webkit.org/show_bug.cgi?id=46563
+
+        * src/WebFileSystemCallbacksImpl.cpp:
+        (WebKit::WebFileSystemCallbacksImpl::didReadDirectory):
+
 2010-09-29  Tony Chang  <tony at chromium.org>
 
         Reviewed by James Robinson.
diff --git a/WebKit/chromium/src/WebFileSystemCallbacksImpl.cpp b/WebKit/chromium/src/WebFileSystemCallbacksImpl.cpp
index faffed0..6b8c80f 100644
--- a/WebKit/chromium/src/WebFileSystemCallbacksImpl.cpp
+++ b/WebKit/chromium/src/WebFileSystemCallbacksImpl.cpp
@@ -73,8 +73,7 @@ void WebFileSystemCallbacksImpl::didReadDirectory(const WebVector<WebFileSystemE
     for (size_t i = 0; i < entries.size(); ++i)
         m_callbacks->didReadDirectoryEntry(entries[i].name, entries[i].isDirectory);
     m_callbacks->didReadDirectoryEntries(hasMore);
-    if (!hasMore)
-        delete this;
+    delete this;
 }
 
 void WebFileSystemCallbacksImpl::didOpenFileSystem(const WebString& name, const WebString& path)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list