2011-04-19 John Gregg <johnnyg@google.com>
authorjohnnyg@google.com <johnnyg@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Apr 2011 10:07:51 +0000 (10:07 +0000)
committerjohnnyg@google.com <johnnyg@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Apr 2011 10:07:51 +0000 (10:07 +0000)
        Reviewed by Darin Fisher.

        Enable folder drag-n-drop when using a "webkitdirectory" file input
        https://bugs.webkit.org/show_bug.cgi?id=58401

        This uses a new ChromeClient API to enumerate the directory and
        return all the files, as if the user had selected that directory
        by clicking the control in the normal way.

        * loader/EmptyClients.h:
        (WebCore::EmptyChromeClient::enumerateChosenDirectory):
        * page/Chrome.cpp:
        (WebCore::Chrome::enumerateChosenDirectory):
        * page/Chrome.h:
        * page/ChromeClient.h:
        * platform/network/FormData.cpp:
        (WebCore::FormData::appendKeyValuePairItems):
        * rendering/RenderFileUploadControl.cpp:
        (WebCore::RenderFileUploadControl::receiveDropForDirectoryUpload):
        (WebCore::RenderFileUploadControl::receiveDroppedFiles):
        * rendering/RenderFileUploadControl.h:
2011-04-19  John Gregg  <johnnyg@google.com>

        Reviewed by Darin Fisher.

        Enable folder drag-n-drop when using a "webkitdirectory" file input
        https://bugs.webkit.org/show_bug.cgi?id=58401

        This uses a new ChromeClient API to enumerate the directory and
        return all the files, as if the user had selected that directory
        by clicking the control in the normal way.

        * public/WebViewClient.h:
        (WebKit::WebViewClient::enumerateChosenDirectory):
        * src/ChromeClientImpl.cpp:
        (WebKit::ChromeClientImpl::enumerateChosenDirectory):
        * src/ChromeClientImpl.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@84238 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/loader/EmptyClients.h
Source/WebCore/page/Chrome.cpp
Source/WebCore/page/Chrome.h
Source/WebCore/page/ChromeClient.h
Source/WebCore/rendering/RenderFileUploadControl.cpp
Source/WebCore/rendering/RenderFileUploadControl.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebViewClient.h
Source/WebKit/chromium/src/ChromeClientImpl.cpp
Source/WebKit/chromium/src/ChromeClientImpl.h

index ce38117..1ef0158 100644 (file)
@@ -1,3 +1,27 @@
+2011-04-19  John Gregg  <johnnyg@google.com>
+
+        Reviewed by Darin Fisher.
+
+        Enable folder drag-n-drop when using a "webkitdirectory" file input
+        https://bugs.webkit.org/show_bug.cgi?id=58401
+
+        This uses a new ChromeClient API to enumerate the directory and 
+        return all the files, as if the user had selected that directory
+        by clicking the control in the normal way.
+
+        * loader/EmptyClients.h:
+        (WebCore::EmptyChromeClient::enumerateChosenDirectory):
+        * page/Chrome.cpp:
+        (WebCore::Chrome::enumerateChosenDirectory):
+        * page/Chrome.h:
+        * page/ChromeClient.h:
+        * platform/network/FormData.cpp:
+        (WebCore::FormData::appendKeyValuePairItems):
+        * rendering/RenderFileUploadControl.cpp:
+        (WebCore::RenderFileUploadControl::receiveDropForDirectoryUpload):
+        (WebCore::RenderFileUploadControl::receiveDroppedFiles):
+        * rendering/RenderFileUploadControl.h:
+
 2011-04-19  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r84150.
index e1a9ffe..e9971a4 100644 (file)
@@ -192,6 +192,10 @@ public:
     virtual NotificationPresenter* notificationPresenter() const { return 0; }
 #endif
 
+#if ENABLE(DIRECTORY_UPLOAD)
+    virtual void enumerateChosenDirectory(const String&, FileChooser*) { }
+#endif
+
     virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) { }
     virtual void chooseIconForFiles(const Vector<String>&, FileChooser*) { }
 
index fa64677..dce7d33 100644 (file)
@@ -444,6 +444,13 @@ void Chrome::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocatio
     m_client->cancelGeolocationPermissionRequestForFrame(frame, geolocation);
 }
 
+#if ENABLE(DIRECTORY_UPLOAD)
+void Chrome::enumerateChosenDirectory(const String& path, FileChooser* fileChooser)
+{
+    m_client->enumerateChosenDirectory(path, fileChooser);
+}
+#endif
+
 void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
 {
     m_client->runOpenPanel(frame, fileChooser);
index 9e4f9dc..9adfec8 100644 (file)
@@ -153,6 +153,9 @@ namespace WebCore {
 
         void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
         void chooseIconForFiles(const Vector<String>&, FileChooser*);
+#if ENABLE(DIRECTORY_UPLOAD)
+        void enumerateChosenDirectory(const String&, FileChooser*);
+#endif
 
         void dispatchViewportDataDidChange(const ViewportArguments&) const;
 
index e2e7c9d..5d5b229 100644 (file)
@@ -224,6 +224,11 @@ namespace WebCore {
         // Asynchronous request to load an icon for specified filenames.
         virtual void chooseIconForFiles(const Vector<String>&, FileChooser*) = 0;
 
+#if ENABLE(DIRECTORY_UPLOAD)
+        // Asychronous request to enumerate all files in a directory chosen by the user.
+        virtual void enumerateChosenDirectory(const String&, FileChooser*) = 0;
+#endif
+
         // Notification that the given form element has changed. This function
         // will be called frequently, so handling should be very fast.
         virtual void formStateDidChange(const Node*) = 0;
index b50b2ad..8056662 100644 (file)
@@ -109,6 +109,12 @@ bool RenderFileUploadControl::allowsDirectoryUpload()
     HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
     return input->fastHasAttribute(webkitdirectoryAttr);
 }
+
+void RenderFileUploadControl::receiveDropForDirectoryUpload(const Vector<String>& paths)
+{
+    if (Chrome* chromePointer = chrome())
+        chromePointer->enumerateChosenDirectory(paths[0], m_fileChooser.get());
+}
 #endif
 
 String RenderFileUploadControl::acceptTypes()
@@ -304,6 +310,13 @@ VisiblePosition RenderFileUploadControl::positionForPoint(const IntPoint&)
 
 void RenderFileUploadControl::receiveDroppedFiles(const Vector<String>& paths)
 {
+#if ENABLE(DIRECTORY_UPLOAD)
+    if (allowsDirectoryUpload()) {
+        receiveDropForDirectoryUpload(paths);
+        return;
+    }
+#endif
+
     if (allowsMultipleFiles())
         m_fileChooser->chooseFiles(paths);
     else
index 22974fe..e9fb7f0 100644 (file)
@@ -64,6 +64,7 @@ private:
     bool allowsMultipleFiles();
 #if ENABLE(DIRECTORY_UPLOAD)
     bool allowsDirectoryUpload();
+    void receiveDropForDirectoryUpload(const Vector<String>&);
 #endif
     String acceptTypes();
     void chooseIconForFiles(FileChooser*, const Vector<String>&);
index d28d8be..1c5fb09 100644 (file)
@@ -1,3 +1,20 @@
+2011-04-19  John Gregg  <johnnyg@google.com>
+
+        Reviewed by Darin Fisher.
+
+        Enable folder drag-n-drop when using a "webkitdirectory" file input
+        https://bugs.webkit.org/show_bug.cgi?id=58401
+
+        This uses a new ChromeClient API to enumerate the directory and 
+        return all the files, as if the user had selected that directory
+        by clicking the control in the normal way.
+
+        * public/WebViewClient.h:
+        (WebKit::WebViewClient::enumerateChosenDirectory):
+        * src/ChromeClientImpl.cpp:
+        (WebKit::ChromeClientImpl::enumerateChosenDirectory):
+        * src/ChromeClientImpl.h:
+
 2011-04-18  Evan Martin  <evan@chromium.org>
 
         Reviewed by Eric Seidel.
index c168ef2..5174351 100644 (file)
@@ -122,6 +122,12 @@ public:
     // The icon is shown in a file upload control.
     virtual bool queryIconForFiles(const WebVector<WebString>& filenames, WebIconLoadingCompletion*) { return false; }
 
+    // This method enumerates all the files in the path. It returns immediately
+    // and asynchronously invokes the WebFileChooserCompletion with all the
+    // files in the directory. Returns false if the WebFileChooserCompletion
+    // will never be called.
+    virtual bool enumerateChosenDirectory(const WebString& path, WebFileChooserCompletion*) { return false; }
+
 
     // Navigational --------------------------------------------------------
 
index 8b853c8..f12bf03 100644 (file)
@@ -683,6 +683,22 @@ void ChromeClientImpl::chooseIconForFiles(const Vector<String>& filenames, FileC
         iconCompletion->didLoadIcon(WebData());
 }
 
+#if ENABLE(DIRECTORY_UPLOAD)
+void ChromeClientImpl::enumerateChosenDirectory(const String& path, FileChooser* fileChooser)
+{
+    WebViewClient* client = m_webView->client();
+    if (!client)
+        return;
+
+    WebFileChooserCompletionImpl* chooserCompletion =
+        new WebFileChooserCompletionImpl(fileChooser);
+
+    // If the enumeration can't happen, call the callback with an empty list.
+    if (!client->enumerateChosenDirectory(path, chooserCompletion))
+        chooserCompletion->didChooseFile(WebVector<WebString>());
+}
+#endif
+
 void ChromeClientImpl::popupOpened(PopupContainer* popupContainer,
                                    const IntRect& bounds,
                                    bool handleExternally)
index afc3432..6a65522 100644 (file)
@@ -139,6 +139,9 @@ public:
     virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*);
     virtual void runOpenPanel(WebCore::Frame*, PassRefPtr<WebCore::FileChooser>);
     virtual void chooseIconForFiles(const Vector<WTF::String>&, WebCore::FileChooser*);
+#if ENABLE(DIRECTORY_UPLOAD)
+    virtual void enumerateChosenDirectory(const WTF::String&, WebCore::FileChooser*);
+#endif
     virtual void setCursor(const WebCore::Cursor&);
     virtual void formStateDidChange(const WebCore::Node*);
 #if ENABLE(TOUCH_EVENTS)