Allow WebFileChooser to return extra file info (like displayName) in addition to...
authorkinuko@chromium.org <kinuko@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Mar 2012 14:06:48 +0000 (14:06 +0000)
committerkinuko@chromium.org <kinuko@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Mar 2012 14:06:48 +0000 (14:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=80719

Reviewed by Kent Tamura.

Source/WebCore:

No new tests: this change itself shouldn't change existing behavior.

* fileapi/File.cpp:
(WebCore::createBlobDataForFileWithName): Renamed from createBlobDataForFileSystemFile.
* fileapi/File.h:
* html/FileInputType.cpp:
(WebCore::FileInputType::saveFormControlState): Updated to handle File.name.
(WebCore::FileInputType::restoreFormControlState): Ditto.
(WebCore::FileInputType::setFileList): Changed the signature to take
FileChooserFileInfo.
(WebCore::FileInputType::filesChosen): Ditto.
(WebCore::FileInputType::receiveDroppedFiles):
* html/FileInputType.h:
(FileInputType):
* platform/FileChooser.cpp:
(WebCore::FileChooser::chooseFiles): Added an overloaded method that
takes FileChooserFileInfo.
(WebCore):
* platform/FileChooser.h:
(WebCore::FileChooserFileInfo::FileChooserFileInfo): Added.
* platform/MIMETypeRegistry.cpp:
(WebCore::MIMETypeRegistry::getWellKnownMIMETypeForExtension): Removed surrouonding ifdefs as this function is now used even if FILE_SYSTEM is not enabled.
* platform/MIMETypeRegistry.h:
(MIMETypeRegistry):

Source/WebKit/chromium:

* public/WebFileChooserCompletion.h:
(SelectedFileInfo): Added.
(WebFileChooserCompletion):
(WebKit::WebFileChooserCompletion::didChooseFile): Added an overloaded
method that takes SelectedFileInfo.
* src/WebFileChooserCompletionImpl.cpp:
(WebKit::WebFileChooserCompletionImpl::didChooseFile): Ditto.
(WebKit):
* src/WebFileChooserCompletionImpl.h:
(WebFileChooserCompletionImpl):

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

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/fileapi/File.cpp
Source/WebCore/fileapi/File.h
Source/WebCore/html/FileInputType.cpp
Source/WebCore/html/FileInputType.h
Source/WebCore/platform/FileChooser.cpp
Source/WebCore/platform/FileChooser.h
Source/WebCore/platform/MIMETypeRegistry.cpp
Source/WebCore/platform/MIMETypeRegistry.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebFileChooserCompletion.h
Source/WebKit/chromium/src/WebFileChooserCompletionImpl.cpp
Source/WebKit/chromium/src/WebFileChooserCompletionImpl.h

index e8450e4..b7623c0 100644 (file)
@@ -1,3 +1,35 @@
+2012-03-13  Kinuko Yasuda  <kinuko@chromium.org>
+
+        Allow WebFileChooser to return extra file info (like displayName) in addition to mere file paths
+        https://bugs.webkit.org/show_bug.cgi?id=80719
+
+        Reviewed by Kent Tamura.
+
+        No new tests: this change itself shouldn't change existing behavior.
+
+        * fileapi/File.cpp:
+        (WebCore::createBlobDataForFileWithName): Renamed from createBlobDataForFileSystemFile.
+        * fileapi/File.h:
+        * html/FileInputType.cpp:
+        (WebCore::FileInputType::saveFormControlState): Updated to handle File.name.
+        (WebCore::FileInputType::restoreFormControlState): Ditto.
+        (WebCore::FileInputType::setFileList): Changed the signature to take
+        FileChooserFileInfo.
+        (WebCore::FileInputType::filesChosen): Ditto.
+        (WebCore::FileInputType::receiveDroppedFiles):
+        * html/FileInputType.h:
+        (FileInputType):
+        * platform/FileChooser.cpp:
+        (WebCore::FileChooser::chooseFiles): Added an overloaded method that
+        takes FileChooserFileInfo.
+        (WebCore):
+        * platform/FileChooser.h:
+        (WebCore::FileChooserFileInfo::FileChooserFileInfo): Added.
+        * platform/MIMETypeRegistry.cpp:
+        (WebCore::MIMETypeRegistry::getWellKnownMIMETypeForExtension): Removed surrouonding ifdefs as this function is now used even if FILE_SYSTEM is not enabled.
+        * platform/MIMETypeRegistry.h:
+        (MIMETypeRegistry):
+
 2012-03-13  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Unreviewed inspector compilation module name fix after r110550.
index d409b97..905291b 100644 (file)
@@ -50,8 +50,7 @@ static PassOwnPtr<BlobData> createBlobDataForFile(const String& path)
     return createBlobDataForFileWithType(path, type);
 }
 
-#if ENABLE(FILE_SYSTEM)
-static PassOwnPtr<BlobData> createBlobDataForFileSystemFile(const String& path, const String& fileSystemName)
+static PassOwnPtr<BlobData> createBlobDataForFileWithName(const String& path, const String& fileSystemName)
 {
     String type;
     int index = fileSystemName.reverseFind('.');
@@ -59,7 +58,6 @@ static PassOwnPtr<BlobData> createBlobDataForFileSystemFile(const String& path,
         type = MIMETypeRegistry::getWellKnownMIMETypeForExtension(fileSystemName.substring(index + 1));
     return createBlobDataForFileWithType(path, type);
 }
-#endif
 
 #if ENABLE(DIRECTORY_UPLOAD)
 PassRefPtr<File> File::createWithRelativePath(const String& path, const String& relativePath)
@@ -87,14 +85,12 @@ File::File(const String& path, const KURL& url, const String& type)
     // See SerializedScriptValue.cpp for js and v8.
 }
 
-#if ENABLE(FILE_SYSTEM)
 File::File(const String& path, const String& name)
-    : Blob(createBlobDataForFileSystemFile(path, name), -1)
+    : Blob(createBlobDataForFileWithName(path, name), -1)
     , m_path(path)
     , m_name(name)
 {
 }
-#endif
 
 double File::lastModifiedDate() const
 {
index 13a91fe..e6ad2a9 100644 (file)
@@ -52,13 +52,13 @@ public:
     static PassRefPtr<File> createWithRelativePath(const String& path, const String& relativePath);
 #endif
 
-#if ENABLE(FILE_SYSTEM)
     // Create a file with a name exposed to the author (via File.name and associated DOM properties) that differs from the one provided in the path.
     static PassRefPtr<File> createWithName(const String& path, const String& name)
     {
+        if (name.isEmpty())
+            return adoptRef(new File(path));
         return adoptRef(new File(path, name));
     }
-#endif
 
     virtual unsigned long long size() const;
     virtual bool isFile() const { return true; }
@@ -83,10 +83,7 @@ private:
 
     // For deserialization.
     File(const String& path, const KURL& srcURL, const String& type);
-
-#if ENABLE(FILE_SYSTEM)
     File(const String& path, const String& name);
-#endif
 
     String m_path;
     String m_name;
index 9cb39b6..60606e2 100644 (file)
@@ -107,6 +107,8 @@ bool FileInputType::saveFormControlState(String& result) const
     unsigned numFiles = m_fileList->length();
     for (unsigned i = 0; i < numFiles; ++i) {
         result.append(m_fileList->item(i)->path());
+        result.append('\1');
+        result.append(m_fileList->item(i)->name());
         result.append('\0');
     }
     return true;
@@ -114,8 +116,17 @@ bool FileInputType::saveFormControlState(String& result) const
 
 void FileInputType::restoreFormControlState(const String& state)
 {
-    Vector<String> files;
-    state.split('\0', files);
+    Vector<FileChooserFileInfo> files;
+    Vector<String> paths;
+    state.split('\0', paths);
+    for (unsigned i = 0; i < paths.size(); ++i) {
+        Vector<String> pathAndName;
+        paths[i].split('\1', pathAndName);
+        if (pathAndName.size() > 1)
+            files.append(FileChooserFileInfo(pathAndName[0], pathAndName[1]));
+        else
+            files.append(FileChooserFileInfo(paths[i]));
+    }
     filesChosen(files);
 }
 
@@ -240,10 +251,10 @@ void FileInputType::setValue(const String&, bool, TextFieldEventBehavior)
     element()->setNeedsStyleRecalc();
 }
 
-void FileInputType::setFileList(const Vector<String>& paths)
+void FileInputType::setFileList(const Vector<FileChooserFileInfo>& files)
 {
     m_fileList->clear();
-    size_t size = paths.size();
+    size_t size = files.size();
 
 #if ENABLE(DIRECTORY_UPLOAD)
     // If a directory is being selected, the UI allows a directory to be chosen
@@ -251,9 +262,9 @@ void FileInputType::setFileList(const Vector<String>& paths)
     // we want to store only the relative paths from that point.
     if (size && element()->fastHasAttribute(webkitdirectoryAttr)) {
         // Find the common root path.
-        String rootPath = directoryName(paths[0]);
+        String rootPath = directoryName(files[0].path);
         for (size_t i = 1; i < size; i++) {
-            while (!paths[i].startsWith(rootPath))
+            while (!files[i].path.startsWith(rootPath))
                 rootPath = directoryName(rootPath);
         }
         rootPath = directoryName(rootPath);
@@ -263,15 +274,15 @@ void FileInputType::setFileList(const Vector<String>& paths)
             rootLength += 1;
         for (size_t i = 0; i < size; i++) {
             // Normalize backslashes to slashes before exposing the relative path to script.
-            String relativePath = paths[i].substring(rootLength).replace('\\', '/');
-            m_fileList->append(File::createWithRelativePath(paths[i], relativePath));
+            String relativePath = files[i].path.substring(rootLength).replace('\\', '/');
+            m_fileList->append(File::createWithRelativePath(files[i].path, relativePath));
         }
         return;
     }
 #endif
 
     for (size_t i = 0; i < size; i++)
-        m_fileList->append(File::create(paths[i]));
+        m_fileList->append(File::createWithName(files[i].path, files[i].displayName));
 }
 
 bool FileInputType::isFileUpload() const
@@ -303,28 +314,31 @@ void FileInputType::requestIcon(const Vector<String>& paths)
         chrome->loadIconForFiles(paths, newFileIconLoader());
 }
 
-void FileInputType::filesChosen(const Vector<String>& paths)
+void FileInputType::filesChosen(const Vector<FileChooserFileInfo>& files)
 {
     RefPtr<HTMLInputElement> input = element();
 
     bool pathsChanged = false;
-    if (paths.size() != m_fileList->length())
+    if (files.size() != m_fileList->length())
         pathsChanged = true;
     else {
-        for (unsigned i = 0; i < paths.size(); ++i) {
-            if (paths[i] != m_fileList->item(i)->path()) {
+        for (unsigned i = 0; i < files.size(); ++i) {
+            if (files[i].path != m_fileList->item(i)->path()) {
                 pathsChanged = true;
                 break;
             }
         }
     }
 
-    setFileList(paths);
+    setFileList(files);
 
     input->setFormControlValueMatchesRenderer(true);
     input->notifyFormStateChanged();
     input->setNeedsValidityCheck();
 
+    Vector<String> paths;
+    for (unsigned i = 0; i < files.size(); ++i)
+        paths.append(files[i].path);
     requestIcon(paths);
 
     if (input->renderer())
@@ -373,12 +387,16 @@ void FileInputType::receiveDroppedFiles(const Vector<String>& paths)
     }
 #endif
 
+    Vector<FileChooserFileInfo> files;
+    for (unsigned i = 0; i < paths.size(); ++i)
+        files.append(FileChooserFileInfo(paths[i]));
+
     if (input->fastHasAttribute(multipleAttr))
-        filesChosen(paths);
+        filesChosen(files);
     else {
-        Vector<String> firstPathOnly;
-        firstPathOnly.append(paths[0]);
-        filesChosen(firstPathOnly);
+        Vector<FileChooserFileInfo> firstFileOnly;
+        firstFileOnly.append(files[0]);
+        filesChosen(firstFileOnly);
     }
 }
 
index 00d362b..bd6a00a 100644 (file)
@@ -69,12 +69,12 @@ private:
     virtual String defaultToolTip() const OVERRIDE;
 
     // FileChooserClient implementation.
-    virtual void filesChosen(const Vector<String>&) OVERRIDE;
+    virtual void filesChosen(const Vector<FileChooserFileInfo>&) OVERRIDE;
 
     // FileIconLoaderClient implementation.
     virtual void updateRendering(PassRefPtr<Icon>) OVERRIDE;
 
-    void setFileList(const Vector<String>& paths);
+    void setFileList(const Vector<FileChooserFileInfo>&);
 #if ENABLE(DIRECTORY_UPLOAD)
     void receiveDropForDirectoryUpload(const Vector<String>&);
 #endif
index a9792aa..50e4c60 100644 (file)
@@ -78,8 +78,25 @@ void FileChooser::chooseFiles(const Vector<String>& filenames)
     if (m_settings.selectedFiles == filenames)
         return;
 
+    if (m_client) {
+        Vector<FileChooserFileInfo> files;
+        for (unsigned i = 0; i < filenames.size(); ++i)
+            files.append(FileChooserFileInfo(filenames[i]));
+        m_client->filesChosen(files);
+    }
+}
+
+void FileChooser::chooseFiles(const Vector<FileChooserFileInfo>& files)
+{
+    // FIXME: This is inelegant. We should not be looking at settings here.
+    Vector<String> paths;
+    for (unsigned i = 0; i < files.size(); ++i)
+        paths.append(files[i].path);
+    if (m_settings.selectedFiles == paths)
+        return;
+
     if (m_client)
-        m_client->filesChosen(filenames);
+        m_client->filesChosen(files);
 }
 
 }
index cc20be2..98dc99c 100644 (file)
@@ -38,6 +38,17 @@ namespace WebCore {
 
 class FileChooser;
 
+struct FileChooserFileInfo {
+    FileChooserFileInfo(const String& path, const String& displayName = String())
+        : path(path)
+        , displayName(displayName)
+    {
+    }
+
+    const String path;
+    const String displayName;
+};
+
 struct FileChooserSettings {
     bool allowsMultipleFiles;
 #if ENABLE(DIRECTORY_UPLOAD)
@@ -49,7 +60,7 @@ struct FileChooserSettings {
 
 class FileChooserClient {
 public:
-    virtual void filesChosen(const Vector<String>&) = 0;
+    virtual void filesChosen(const Vector<FileChooserFileInfo>&) = 0;
     virtual ~FileChooserClient();
 
 protected:
@@ -71,6 +82,9 @@ public:
     void chooseFile(const String& path);
     void chooseFiles(const Vector<String>& paths);
 
+    // FIXME: We should probably just pass file paths that could be virtual paths with proper display names rather than passing structs.
+    void chooseFiles(const Vector<FileChooserFileInfo>& files);
+
     const FileChooserSettings& settings() const { return m_settings; }
 
 private:
index 8e1e8e8..4864453 100644 (file)
@@ -139,7 +139,6 @@ static const TypeExtensionPair commonMediaTypes[] = {
     { "audio/x-wav", "wav" }
 };
 
-#if ENABLE(FILE_SYSTEM)
 static const char textPlain[] = "text/plain";
 static const char textHtml[] = "text/html";
 static const char imageJpeg[] = "image/jpeg";
@@ -181,7 +180,6 @@ static const TypeExtensionPair wellKnownMimeTypes[] = {
     { "application/rdf+xml", "rdf" },
     { "application/x-shockwave-flash", "swf" },
 };
-#endif
 
 static HashSet<String>* supportedImageResourceMIMETypes;
 static HashSet<String>* supportedImageMIMETypes;
@@ -474,7 +472,6 @@ static void initializeMIMETypeRegistry()
     initializeUnsupportedTextMIMETypes();
 }
 
-#if ENABLE(FILE_SYSTEM)
 static String findMimeType(const TypeExtensionPair* pairs, unsigned numPairs, const String& extension)
 {
     if (!extension.isEmpty()) {
@@ -494,7 +491,6 @@ String MIMETypeRegistry::getWellKnownMIMETypeForExtension(const String& extensio
         return found;
     return findMimeType(commonMediaTypes, sizeof(commonMediaTypes) / sizeof(commonMediaTypes[0]), extension);
 }
-#endif
 
 String MIMETypeRegistry::getMIMETypeForPath(const String& path)
 {
index d2c3752..7fa6db6 100644 (file)
@@ -36,9 +36,7 @@ namespace WebCore {
 class MIMETypeRegistry {
 public:
     static String getMIMETypeForExtension(const String& extension);
-#if ENABLE(FILE_SYSTEM)
     static String getWellKnownMIMETypeForExtension(const String& extension);
-#endif
 
     static Vector<String> getExtensionsForMIMEType(const String& type);
     static String getPreferredExtensionForMIMEType(const String& type);
index 2282f08..ceeb7db 100644 (file)
@@ -1,3 +1,21 @@
+2012-03-13  Kinuko Yasuda  <kinuko@chromium.org>
+
+        Allow WebFileChooser to return extra file info (like displayName) in addition to mere file paths
+        https://bugs.webkit.org/show_bug.cgi?id=80719
+
+        Reviewed by Kent Tamura.
+
+        * public/WebFileChooserCompletion.h:
+        (SelectedFileInfo): Added.
+        (WebFileChooserCompletion):
+        (WebKit::WebFileChooserCompletion::didChooseFile): Added an overloaded
+        method that takes SelectedFileInfo.
+        * src/WebFileChooserCompletionImpl.cpp:
+        (WebKit::WebFileChooserCompletionImpl::didChooseFile): Ditto.
+        (WebKit):
+        * src/WebFileChooserCompletionImpl.h:
+        (WebFileChooserCompletionImpl):
+
 2012-03-12  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r110529.
index 14bace4..9b01d0e 100644 (file)
 #ifndef WebFileChooserCompletion_h
 #define WebFileChooserCompletion_h
 
+#include "platform/WebString.h"
+
 namespace WebKit {
 
-class WebString;
 template <typename T> class WebVector;
 
 // Gets called back when WebViewClient finished choosing a file.
 class WebFileChooserCompletion {
 public:
+    struct SelectedFileInfo {
+        // The actual path of the selected file.
+        WebString path;
+
+        // The display name of the file that is to be exposed as File.name in
+        // the DOM layer. If it is empty the base part of the |path| is used.
+        WebString displayName;
+    };
+
     // Called with zero or more file names. Zero-lengthed vector means that
     // the user cancelled or that file choosing failed. The callback instance
     // is destroyed when this method is called.
     virtual void didChooseFile(const WebVector<WebString>& fileNames) = 0;
+
+    // Called with zero or more files, given as a vector of SelectedFileInfo.
+    // Zero-lengthed vector means that the user cancelled or that file
+    // choosing failed. The callback instance is destroyed when this method
+    // is called.
+    // FIXME: Deprecate either one of the didChooseFile (and rename it to
+    // didChooseFile*s*).
+    virtual void didChooseFile(const WebVector<SelectedFileInfo>&) { }
 protected:
     virtual ~WebFileChooserCompletion() {}
 };
index d7583c5..73452d0 100644 (file)
@@ -44,14 +44,20 @@ WebFileChooserCompletionImpl::~WebFileChooserCompletionImpl()
 
 void WebFileChooserCompletionImpl::didChooseFile(const WebVector<WebString>& fileNames)
 {
-    if (fileNames.size() == 1)
-        m_fileChooser->chooseFile(fileNames[0]);
-    else if (fileNames.size() > 0) {
-        Vector<WTF::String> paths;
-        for (size_t i = 0; i < fileNames.size(); ++i)
-            paths.append(fileNames[i]);
-        m_fileChooser->chooseFiles(paths);
-    }
+    Vector<WebCore::FileChooserFileInfo> fileInfo;
+    for (size_t i = 0; i < fileNames.size(); ++i)
+        fileInfo.append(WebCore::FileChooserFileInfo(fileNames[i]));
+    m_fileChooser->chooseFiles(fileInfo);
+    // This object is no longer needed.
+    delete this;
+}
+
+void WebFileChooserCompletionImpl::didChooseFile(const WebVector<SelectedFileInfo>& files)
+{
+    Vector<WebCore::FileChooserFileInfo> fileInfo;
+    for (size_t i = 0; i < files.size(); ++i)
+        fileInfo.append(WebCore::FileChooserFileInfo(files[i].path, files[i].displayName));
+    m_fileChooser->chooseFiles(fileInfo);
     // This object is no longer needed.
     delete this;
 }
index 06a0577..3ac63a5 100644 (file)
@@ -49,6 +49,7 @@ public:
     WebFileChooserCompletionImpl(PassRefPtr<WebCore::FileChooser> chooser);
     ~WebFileChooserCompletionImpl();
     virtual void didChooseFile(const WebVector<WebString>& fileNames);
+    virtual void didChooseFile(const WebVector<SelectedFileInfo>& files);
 private:
     RefPtr<WebCore::FileChooser> m_fileChooser;
 };