[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.22-985-g3c00f00
jianli at chromium.org
jianli at chromium.org
Wed Mar 17 18:32:25 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit 044ed51ff54e134c103c4990886d4cf260897e1c
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