[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

jianli at chromium.org jianli at chromium.org
Thu Apr 8 02:19:13 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit fd3fc61f89cdd3dc2abd64ffda6c53d9ca0a003d
Author: jianli at chromium.org <jianli at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Mar 11 01:19:41 2010 +0000

    Implementing DOMFormData class.
    https://bugs.webkit.org/show_bug.cgi?id=35707
    
    Reviewed by Dmitry Titov.
    
    This patch only addresses the implementation of DOMFormData class and
    moves the FormData construction logic from HTMLFormElement::createFormData
    to FormData::create() so that it can be used by both HTMLFormElement
    and XMLHttpRequest.
    
    The DOMFormData IDL interface will be exposed in another patch and the
    test will be added then.
    
    * Android.mk:
    * GNUmakefile.am:
    * WebCore.gypi:
    * WebCore.pro:
    * WebCore.vcproj/WebCore.vcproj:
    * WebCore.xcodeproj/project.pbxproj:
    * html/DOMFormData.cpp: Added.
    * html/DOMFormData.h: Added.
    * html/FormDataList.h:
    (WebCore::FormDataList::encoding):
    * html/HTMLFormElement.cpp:
    (WebCore::HTMLFormElement::createFormData):
    (WebCore::HTMLFormElement::submit):
    * html/HTMLFormElement.h:
    * platform/network/FormData.cpp:
    (WebCore::FormData::create):
    (WebCore::FormData::createMultiPart):
    (WebCore::FormData::appendDOMFormData):
    * platform/network/FormData.h:
    (WebCore::FormData::boundary):
    * xml/XMLHttpRequest.cpp:
    (WebCore::XMLHttpRequest::send):
    * xml/XMLHttpRequest.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55821 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index 917350f..84cba9c 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -239,6 +239,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
 	\
 	html/Blob.cpp \
 	html/CollectionCache.cpp \
+	html/DOMFormData.cpp \
 	html/File.cpp \
 	html/FileList.cpp \
 	html/FormDataList.cpp \
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 7d0eb87..0dcded6 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,42 @@
+2010-03-10  Jian Li  <jianli at chromium.org>
+
+        Reviewed by Dmitry Titov.
+
+        Implementing DOMFormData class.
+        https://bugs.webkit.org/show_bug.cgi?id=35707
+
+        This patch only addresses the implementation of DOMFormData class and
+        moves the FormData construction logic from HTMLFormElement::createFormData
+        to FormData::create() so that it can be used by both HTMLFormElement
+        and XMLHttpRequest.
+
+        The DOMFormData IDL interface will be exposed in another patch and the
+        test will be added then.
+
+        * Android.mk:
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * html/DOMFormData.cpp: Added.
+        * html/DOMFormData.h: Added.
+        * html/FormDataList.h:
+        (WebCore::FormDataList::encoding):
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::createFormData):
+        (WebCore::HTMLFormElement::submit):
+        * html/HTMLFormElement.h:
+        * platform/network/FormData.cpp:
+        (WebCore::FormData::create):
+        (WebCore::FormData::createMultiPart):
+        (WebCore::FormData::appendDOMFormData):
+        * platform/network/FormData.h:
+        (WebCore::FormData::boundary):
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::send):
+        * xml/XMLHttpRequest.h:
+
 2010-03-10  Chris Fleizach  <cfleizach at apple.com>
 
         Reviewed by Beth Dakin.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 7ac62e8..dbb0c28 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -1008,6 +1008,8 @@ webcore_sources += \
 	WebCore/html/DateComponents.h \
 	WebCore/html/DOMDataGridDataSource.cpp \
 	WebCore/html/DOMDataGridDataSource.h \
+	WebCore/html/DOMFormData.cpp \
+	WebCore/html/DOMFormData.h \
 	WebCore/html/File.cpp \
 	WebCore/html/File.h \
 	WebCore/html/FileList.cpp \
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index be547ec..e0ec09d 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -1412,6 +1412,8 @@
             'html/DataGridColumn.h',
             'html/DOMDataGridDataSource.cpp',
             'html/DOMDataGridDataSource.h',
+            'html/DOMFormData.cpp',
+            'html/DOMFormData.h',
             'html/DataGridColumnList.cpp',
             'html/DataGridColumnList.h',
             'html/DateComponents.cpp',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index de0bf01..57c6581 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -598,6 +598,7 @@ SOURCES += \
     html/DataGridColumnList.cpp \
     html/DateComponents.cpp \
     html/DOMDataGridDataSource.cpp \
+    html/DOMFormData.cpp \
     html/File.cpp \
     html/FileList.cpp \
     html/FormDataList.cpp \
@@ -1295,6 +1296,7 @@ HEADERS += \
     html/DataGridColumnList.h \
     html/DateComponents.h \
     html/DOMDataGridDataSource.h \
+    html/DOMFormData.h \
     html/File.h \
     html/FileList.h \
     html/FormDataList.h \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index d14a6a2..f624632 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -29973,6 +29973,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\html\DOMFormData.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\html\DOMFormData.h"
+				>
+			</File>
+			<File
 				RelativePath="..\html\File.cpp"
 				>
 			</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index af62274..a6127e4 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -625,6 +625,8 @@
 		2ECF7ADD10162B3800427DE7 /* JSErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ECF7ADB10162B3800427DE7 /* JSErrorEvent.h */; };
 		2ECF7AE110162B5800427DE7 /* ErrorEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ECF7ADE10162B5800427DE7 /* ErrorEvent.cpp */; };
 		2ECF7AE210162B5800427DE7 /* ErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ECF7ADF10162B5800427DE7 /* ErrorEvent.h */; };
+		2ED609BC1145B07100C8684E /* DOMFormData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ED609BA1145B07100C8684E /* DOMFormData.cpp */; };
+		2ED609BD1145B07100C8684E /* DOMFormData.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ED609BB1145B07100C8684E /* DOMFormData.h */; };
 		31288E720E3005D6003619AE /* WebKitCSSKeyframeRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31288E6E0E3005D6003619AE /* WebKitCSSKeyframeRule.cpp */; };
 		31288E730E3005D6003619AE /* WebKitCSSKeyframeRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 31288E6F0E3005D6003619AE /* WebKitCSSKeyframeRule.h */; };
 		31288E740E3005D6003619AE /* WebKitCSSKeyframesRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31288E700E3005D6003619AE /* WebKitCSSKeyframesRule.cpp */; };
@@ -5990,6 +5992,8 @@
 		2ECF7ADE10162B5800427DE7 /* ErrorEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorEvent.cpp; sourceTree = "<group>"; };
 		2ECF7ADF10162B5800427DE7 /* ErrorEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorEvent.h; sourceTree = "<group>"; };
 		2ECF7AE010162B5800427DE7 /* ErrorEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ErrorEvent.idl; sourceTree = "<group>"; };
+		2ED609BA1145B07100C8684E /* DOMFormData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMFormData.cpp; sourceTree = "<group>"; };
+		2ED609BB1145B07100C8684E /* DOMFormData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFormData.h; sourceTree = "<group>"; };
 		31288E6E0E3005D6003619AE /* WebKitCSSKeyframeRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSKeyframeRule.cpp; sourceTree = "<group>"; };
 		31288E6F0E3005D6003619AE /* WebKitCSSKeyframeRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitCSSKeyframeRule.h; sourceTree = "<group>"; };
 		31288E700E3005D6003619AE /* WebKitCSSKeyframesRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSKeyframesRule.cpp; sourceTree = "<group>"; };
@@ -12874,6 +12878,8 @@
 				F5D3A57B106B83B300545297 /* DateComponents.h */,
 				BC7DAAEC0FF9615D00CE0138 /* DOMDataGridDataSource.cpp */,
 				BC7DAAED0FF9615D00CE0138 /* DOMDataGridDataSource.h */,
+				2ED609BA1145B07100C8684E /* DOMFormData.cpp */,
+				2ED609BB1145B07100C8684E /* DOMFormData.h */,
 				BCDBB8CC0E08958400C60FF6 /* File.cpp */,
 				BCDBB8CB0E08958400C60FF6 /* File.h */,
 				BC1881D90E08C4ED00048C13 /* File.idl */,
@@ -18668,6 +18674,7 @@
 				BC53DA2E1143121E000D817E /* DOMWrapperWorld.h in Headers */,
 				BC53DA601143141A000D817E /* DOMObjectHashTableMap.h in Headers */,
 				BC53DAC211432EEE000D817E /* JSDebugWrapperSet.h in Headers */,
+				2ED609BD1145B07100C8684E /* DOMFormData.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -20867,6 +20874,7 @@
 				BC53DA62114314BD000D817E /* DOMObjectHashTableMap.cpp in Sources */,
 				BC53DAC511432FD9000D817E /* JSDebugWrapperSet.cpp in Sources */,
 				BC53DAC711433064000D817E /* JSDOMWrapper.cpp in Sources */,
+				2ED609BC1145B07100C8684E /* DOMFormData.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/WebCore/html/DOMFormData.cpp b/WebCore/html/DOMFormData.cpp
new file mode 100644
index 0000000..1441e8b
--- /dev/null
+++ b/WebCore/html/DOMFormData.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DOMFormData.h"
+
+#include "Blob.h"
+#include "PlatformString.h"
+#include "TextEncoding.h"
+
+namespace WebCore {
+
+DOMFormData::DOMFormData(const TextEncoding& encoding)
+    : FormDataList(encoding)
+{
+}
+
+void DOMFormData::append(const String& name, const String& value)
+{
+    if (!name.isEmpty())
+        appendData(name, value);
+}
+
+void DOMFormData::append(const String& name, Blob* blob)
+{
+    // FIXME: Need to support sliced file when Blob.slice support is landed.
+    if (!name.isEmpty() && !blob->path().isEmpty()) {
+        RefPtr<File> file = static_cast<File*>(blob);
+        appendFile(name, file.release());
+    }
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/DOMFormData.h b/WebCore/html/DOMFormData.h
new file mode 100644
index 0000000..f071d4a
--- /dev/null
+++ b/WebCore/html/DOMFormData.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOMFormData_h
+#define DOMFormData_h
+
+#include "FormDataList.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class Blob;
+class String;
+class TextEncoding;
+
+class DOMFormData : public FormDataList, public RefCounted<DOMFormData> {
+public:
+    static PassRefPtr<DOMFormData> create() { return adoptRef(new DOMFormData(UTF8Encoding())); }
+    static PassRefPtr<DOMFormData> create(const TextEncoding& encoding) { return adoptRef(new DOMFormData(encoding)); }
+
+    void append(const String& name, const String& value);
+    void append(const String& name, Blob*);
+
+private:
+    DOMFormData(const TextEncoding&);
+};
+
+} // namespace WebCore
+
+#endif // DOMFormData_h
diff --git a/WebCore/html/FormDataList.h b/WebCore/html/FormDataList.h
index aec1a52..8398dbc 100644
--- a/WebCore/html/FormDataList.h
+++ b/WebCore/html/FormDataList.h
@@ -55,6 +55,7 @@ public:
     };
 
     const Vector<Item>& list() const { return m_list; }
+    const TextEncoding& encoding() const { return m_encoding; }
 
 private:
     void appendString(const CString&);
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index 2f88894..bdac28a 100644
--- a/WebCore/html/HTMLFormElement.cpp
+++ b/WebCore/html/HTMLFormElement.cpp
@@ -26,8 +26,7 @@
 #include "HTMLFormElement.h"
 
 #include "CSSHelper.h"
-#include "Chrome.h"
-#include "ChromeClient.h"
+#include "DOMFormData.h"
 #include "Document.h"
 #include "Event.h"
 #include "EventNames.h"
@@ -46,7 +45,6 @@
 #include "ScriptEventListener.h"
 #include "MIMETypeRegistry.h"
 #include "MappedAttribute.h"
-#include "Page.h"
 #include "RenderTextControl.h"
 #include "ValidityState.h"
 #include <limits>
@@ -201,83 +199,16 @@ TextEncoding HTMLFormElement::dataEncoding() const
     return m_formDataBuilder.dataEncoding(document());
 }
 
-PassRefPtr<FormData> HTMLFormElement::createFormData(const CString& boundary)
+PassRefPtr<FormData> HTMLFormElement::createFormData()
 {
-    Vector<char> encodedData;
-    TextEncoding encoding = dataEncoding().encodingForFormSubmission();
-
-    RefPtr<FormData> result = FormData::create();
-
+    RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding().encodingForFormSubmission());
     for (unsigned i = 0; i < formElements.size(); ++i) {
         HTMLFormControlElement* control = formElements[i];
-        FormDataList list(encoding);
-
-        if (!control->disabled() && control->appendFormData(list, m_formDataBuilder.isMultiPartForm())) {
-            size_t formDataListSize = list.list().size();
-            ASSERT(formDataListSize % 2 == 0);
-            for (size_t j = 0; j < formDataListSize; j += 2) {
-                const FormDataList::Item& key = list.list()[j];
-                const FormDataList::Item& value = list.list()[j + 1];
-                if (!m_formDataBuilder.isMultiPartForm()) {
-                    // Omit the name "isindex" if it's the first form data element.
-                    // FIXME: Why is this a good rule? Is this obsolete now?
-                    if (encodedData.isEmpty() && key.data() == "isindex")
-                        FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
-                    else
-                        m_formDataBuilder.addKeyValuePairAsFormData(encodedData, key.data(), value.data());
-                } else {
-                    Vector<char> header;
-                    m_formDataBuilder.beginMultiPartHeader(header, boundary, key.data());
-
-                    bool shouldGenerateFile = false;
-                    // if the current type is FILE, then we also need to include the filename
-                    if (value.file()) {
-                        const String& path = value.file()->path();
-                        String fileName = value.file()->fileName();
-
-                        // Let the application specify a filename if it's going to generate a replacement file for the upload.
-                        if (!path.isEmpty()) {
-                            if (Page* page = document()->page()) {
-                                String generatedFileName;
-                                shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
-                                if (shouldGenerateFile)
-                                    fileName = generatedFileName;
-                            }
-                        }
-
-                        // We have to include the filename=".." part in the header, even if the filename is empty
-                        m_formDataBuilder.addFilenameToMultiPartHeader(header, encoding, fileName);
-
-                        if (!fileName.isEmpty()) {
-                            // FIXME: The MIMETypeRegistry function's name makes it sound like it takes a path,
-                            // not just a basename. But filename is not the path. But note that it's not safe to
-                            // just use path instead since in the generated-file case it will not reflect the
-                            // MIME type of the generated file.
-                            String mimeType = MIMETypeRegistry::getMIMETypeForPath(fileName);
-                            if (!mimeType.isEmpty())
-                                m_formDataBuilder.addContentTypeToMultiPartHeader(header, mimeType.latin1());
-                        }
-                    }
-
-                    m_formDataBuilder.finishMultiPartHeader(header);
-
-                    // Append body
-                    result->appendData(header.data(), header.size());
-                    if (size_t dataSize = value.data().length())
-                        result->appendData(value.data().data(), dataSize);
-                    else if (value.file() && !value.file()->path().isEmpty())
-                        result->appendFile(value.file()->path(), shouldGenerateFile);
-
-                    result->appendData("\r\n", 2);
-                }
-            }
-        }
+        if (!control->disabled())
+            control->appendFormData(*domFormData, m_formDataBuilder.isMultiPartForm());
     }
 
-    if (m_formDataBuilder.isMultiPartForm())
-        m_formDataBuilder.addBoundaryToMultiPartHeader(encodedData, boundary, true);
-
-    result->appendData(encodedData.data(), encodedData.size());
+    RefPtr<FormData> result = (m_formDataBuilder.isMultiPartForm()) ? FormData::createMultiPart(*domFormData, document()) : FormData::create(*domFormData);
 
     result->setIdentifier(generateFormDataIdentifier());
     return result;
@@ -389,8 +320,8 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockH
             ASSERT(!m_formDataBuilder.isMultiPartForm());
         }
 
+        RefPtr<FormData> data = createFormData();
         if (!m_formDataBuilder.isMultiPartForm()) {
-            RefPtr<FormData> data = createFormData(CString());
 
             if (isMailtoForm()) {
                 // Convert the form data into a string that we put into the URL.
@@ -400,13 +331,11 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockH
             }
 
             frame->loader()->submitForm("POST", m_url, data.release(), m_target, m_formDataBuilder.encodingType(), String(), lockHistory, event, formState.release());
-        } else {
-            Vector<char> boundary = m_formDataBuilder.generateUniqueBoundaryString();
-            frame->loader()->submitForm("POST", m_url, createFormData(boundary.data()), m_target, m_formDataBuilder.encodingType(), boundary.data(), lockHistory, event, formState.release());
-        }
+        } else
+            frame->loader()->submitForm("POST", m_url, data.get(), m_target, m_formDataBuilder.encodingType(), data->boundary().data(), lockHistory, event, formState.release());
     } else {
         m_formDataBuilder.setIsMultiPartForm(false);
-        frame->loader()->submitForm("GET", m_url, createFormData(CString()), m_target, String(), String(), lockHistory, event, formState.release());
+        frame->loader()->submitForm("GET", m_url, createFormData(), m_target, String(), String(), lockHistory, event, formState.release());
     }
 
     if (needButtonActivation && firstSuccessfulSubmitButton)
diff --git a/WebCore/html/HTMLFormElement.h b/WebCore/html/HTMLFormElement.h
index c0ce3e3..44bf628 100644
--- a/WebCore/html/HTMLFormElement.h
+++ b/WebCore/html/HTMLFormElement.h
@@ -135,7 +135,7 @@ private:
 
     bool isMailtoForm() const;
     TextEncoding dataEncoding() const;
-    PassRefPtr<FormData> createFormData(const CString& boundary);
+    PassRefPtr<FormData> createFormData();
     unsigned formElementIndex(HTMLFormControlElement*);
 
     friend class HTMLFormCollection;
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index a8456b2..597f859 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -23,8 +23,14 @@
 
 #include "Blob.h"
 #include "CString.h"
+#include "Chrome.h"
 #include "ChromeClient.h"
+#include "DOMFormData.h"
+#include "Document.h"
 #include "FileSystem.h"
+#include "FormDataBuilder.h"
+#include "MIMETypeRegistry.h"
+#include "Page.h"
 #include "TextEncoding.h"
 
 namespace WebCore {
@@ -89,6 +95,20 @@ PassRefPtr<FormData> FormData::create(const Vector<char>& vector)
     return result.release();
 }
 
+PassRefPtr<FormData> FormData::create(const DOMFormData& domFormData)
+{
+    RefPtr<FormData> result = create();
+    result->appendDOMFormData(domFormData, false, 0);
+    return result.release();
+}
+
+PassRefPtr<FormData> FormData::createMultiPart(const DOMFormData& domFormData, Document* document)
+{
+    RefPtr<FormData> result = create();
+    result->appendDOMFormData(domFormData, true, document);
+    return result.release();
+}
+
 PassRefPtr<FormData> FormData::copy() const
 {
     return adoptRef(new FormData(*this));
@@ -146,6 +166,81 @@ void FormData::appendFileRange(const String& filename, long long start, long lon
 }
 #endif
 
+void FormData::appendDOMFormData(const DOMFormData& domFormData, bool isMultiPartForm, Document* document)
+{
+    FormDataBuilder formDataBuilder;
+    if (isMultiPartForm)
+        m_boundary = formDataBuilder.generateUniqueBoundaryString();
+
+    Vector<char> encodedData;
+    TextEncoding encoding = domFormData.encoding();
+
+    const Vector<FormDataList::Item>& list = domFormData.list();
+    size_t formDataListSize = list.size();
+    ASSERT(!(formDataListSize % 2));
+    for (size_t i = 0; i < formDataListSize; i += 2) {
+        const FormDataList::Item& key = list[i];
+        const FormDataList::Item& value = list[i + 1];
+        if (isMultiPartForm) {
+            Vector<char> header;
+            formDataBuilder.beginMultiPartHeader(header, m_boundary.data(), key.data());
+
+            bool shouldGenerateFile = false;
+            // If the current type is FILE, then we also need to include the filename
+            if (value.file()) {
+                const String& path = value.file()->path();
+                String fileName = value.file()->fileName();
+
+                // Let the application specify a filename if it's going to generate a replacement file for the upload.
+                if (!path.isEmpty()) {
+                    if (Page* page = document->page()) {
+                        String generatedFileName;
+                        shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
+                        if (shouldGenerateFile)
+                            fileName = generatedFileName;
+                    }
+                }
+
+                // We have to include the filename=".." part in the header, even if the filename is empty
+                formDataBuilder.addFilenameToMultiPartHeader(header, encoding, fileName);
+
+                if (!fileName.isEmpty()) {
+                    // FIXME: The MIMETypeRegistry function's name makes it sound like it takes a path,
+                    // not just a basename. But filename is not the path. But note that it's not safe to
+                    // just use path instead since in the generated-file case it will not reflect the
+                    // MIME type of the generated file.
+                    String mimeType = MIMETypeRegistry::getMIMETypeForPath(fileName);
+                    if (!mimeType.isEmpty())
+                        formDataBuilder.addContentTypeToMultiPartHeader(header, mimeType.latin1());
+                }
+            }
+
+            formDataBuilder.finishMultiPartHeader(header);
+
+            // Append body
+            appendData(header.data(), header.size());
+            if (size_t dataSize = value.data().length())
+                appendData(value.data().data(), dataSize);
+            else if (value.file() && !value.file()->path().isEmpty())
+                appendFile(value.file()->path(), shouldGenerateFile);
+
+            appendData("\r\n", 2);
+        } else {
+            // Omit the name "isindex" if it's the first form data element.
+            // FIXME: Why is this a good rule? Is this obsolete now?
+            if (encodedData.isEmpty() && key.data() == "isindex")
+                FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
+            else
+                formDataBuilder.addKeyValuePairAsFormData(encodedData, key.data(), value.data());
+        }
+    } 
+
+    if (isMultiPartForm)
+        formDataBuilder.addBoundaryToMultiPartHeader(encodedData, m_boundary.data(), true);
+
+    appendData(encodedData.data(), encodedData.size());
+}
+
 void FormData::flatten(Vector<char>& data) const
 {
     // Concatenate all the byte arrays, but omit any files.
diff --git a/WebCore/platform/network/FormData.h b/WebCore/platform/network/FormData.h
index 48e5154..76b6be6 100644
--- a/WebCore/platform/network/FormData.h
+++ b/WebCore/platform/network/FormData.h
@@ -27,6 +27,8 @@
 namespace WebCore {
 
 class ChromeClient;
+class DOMFormData;
+class Document;
 
 class FormDataElement {
 public:
@@ -80,6 +82,8 @@ public:
     static PassRefPtr<FormData> create(const void*, size_t);
     static PassRefPtr<FormData> create(const CString&);
     static PassRefPtr<FormData> create(const Vector<char>&);
+    static PassRefPtr<FormData> create(const DOMFormData&);
+    static PassRefPtr<FormData> createMultiPart(const DOMFormData&, Document*);
     PassRefPtr<FormData> copy() const;
     PassRefPtr<FormData> deepCopy() const;
     ~FormData();
@@ -95,6 +99,7 @@ public:
 
     bool isEmpty() const { return m_elements.isEmpty(); }
     const Vector<FormDataElement>& elements() const { return m_elements; }
+    const Vector<char>& boundary() const { return m_boundary; }
 
     void generateFiles(ChromeClient*);
     void removeGeneratedFilesIfNeeded();
@@ -111,10 +116,13 @@ private:
     FormData();
     FormData(const FormData&);
 
+    void appendDOMFormData(const DOMFormData& domFormData, bool isMultiPartForm, Document* document);
+
     Vector<FormDataElement> m_elements;
     int64_t m_identifier;
     bool m_hasGeneratedFiles;
     bool m_alwaysStream;
+    Vector<char> m_boundary;
 };
 
 inline bool operator==(const FormData& a, const FormData& b)
diff --git a/WebCore/xml/XMLHttpRequest.cpp b/WebCore/xml/XMLHttpRequest.cpp
index abdb58a..96621b2 100644
--- a/WebCore/xml/XMLHttpRequest.cpp
+++ b/WebCore/xml/XMLHttpRequest.cpp
@@ -26,6 +26,7 @@
 #include "Cache.h"
 #include "CString.h"
 #include "CrossOriginAccessControl.h"
+#include "DOMFormData.h"
 #include "DOMImplementation.h"
 #include "Document.h"
 #include "Event.h"
@@ -459,6 +460,25 @@ void XMLHttpRequest::send(Blob* body, ExceptionCode& ec)
     createRequest(ec);
 }
 
+void XMLHttpRequest::send(DOMFormData* body, ExceptionCode& ec)
+{
+    if (!initSend(ec))
+        return;
+
+    if (m_method != "GET" && m_method != "HEAD" && m_url.protocolInHTTPFamily()) {
+        m_requestEntityBody = FormData::createMultiPart(*body, document());
+
+        String contentType = getRequestHeader("Content-Type");
+        if (contentType.isEmpty()) {
+            contentType = "multipart/form-data; boundary=";
+            contentType += m_requestEntityBody->boundary().data();
+            setRequestHeaderInternal("Content-Type", contentType);
+        }
+    }
+
+    createRequest(ec);
+}
+
 void XMLHttpRequest::createRequest(ExceptionCode& ec)
 {
     // The presence of upload event listeners forces us to use preflighting because POSTing to an URL that does not
diff --git a/WebCore/xml/XMLHttpRequest.h b/WebCore/xml/XMLHttpRequest.h
index 5e47d41..dce1a09 100644
--- a/WebCore/xml/XMLHttpRequest.h
+++ b/WebCore/xml/XMLHttpRequest.h
@@ -35,6 +35,7 @@ namespace WebCore {
 
 class Blob;
 class Document;
+class DOMFormData;
 class ResourceRequest;
 class TextResourceDecoder;
 class ThreadableLoader;
@@ -74,6 +75,7 @@ public:
     void send(Document*, ExceptionCode&);
     void send(const String&, ExceptionCode&);
     void send(Blob*, ExceptionCode&);
+    void send(DOMFormData*, ExceptionCode&);
     void abort();
     void setRequestHeader(const AtomicString& name, const String& value, ExceptionCode&);
     void overrideMimeType(const String& override);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list