+2004-08-30 Darin Adler <darin@apple.com>
+
+ Reviewed by Chris.
+
+ - did work to prepare for uploading files incrementally when submitting forms
+
+ * khtml/misc/formdata.h: Added. Class for holding form data inside WebCore.
+ * khtml/misc/formdata.cpp: Added.
+
+ * khtml/html/html_formimpl.h: Added the FormDataList type, changed the formData function parameters
+ and made it private, renamed the encoding method to appendFormData and changed the parameters around.
+ * khtml/html/html_formimpl.cpp:
+ (DOM::FormDataList): Added. Class that replaces the old use of QValueList<QCString> for form data.
+ Later we'll change it to accomodate filenames too.
+ (DOM::HTMLFormElementImpl::formData): Changed code to use FormDataList intsead of the old encodingList.
+ Also changed to return the "OK" result as the function result and put the form data into something
+ passed as an "out" parameter; the old way was the other way around.
+ (DOM::HTMLFormElementImpl::submit): Change to use FormData rather than a QByteArray when getting the
+ form data to submit.
+ (DOM::HTMLButtonElementImpl::appendFormData): Rename from encoding, and use the new appendData function
+ instead of the old way of doing += to put data on the list.
+ (DOM::HTMLInputElementImpl::appendFormData): Ditto.
+ (DOM::HTMLSelectElementImpl::appendFormData): Ditto.
+ (DOM::HTMLKeygenElementImpl::appendFormData): Ditto.
+ (DOM::HTMLTextAreaElementImpl::appendFormData): Ditto.
+ (DOM::FormDataList::FormDataList): Added.
+ (DOM::FormDataList::appendString): Added.
+ (DOM::FormDataList::begin): Added.
+ (DOM::FormDataList::end): Added.
+
+ * khtml/khtml_part.h: Changed the type of the submitForm parameter to FormData instead of QByteArray.
+ * khtml/khtmlpart_p.h: Changed the type of the submitFormData data member to FormData instead of QByteArray.
+ * khtml/khtml_part.cpp: (KHTMLPart::submitForm): Called the new flattenToString function in all the
+ code that handles mailto forms. Called the new flatten function in the non-Apple code path.
+
+ * kwq/KWQKHTMLPart.mm: (KWQKHTMLPart::submitForm): Pass NSArray for form data instead of NSData.
+
+ * kwq/KWQKJob.h: Use FormData instead of QByteArray. A couple other small cleanups.
+ * kwq/KWQKJobClasses.h: Ditto.
+ * kwq/KWQKJobClasses.mm:
+ (KIO::TransferJobPrivate::TransferJobPrivate): Ditto.
+ (KIO::TransferJob::TransferJob): Ditto.
+ (KIO::TransferJob::postData): Ditto.
+ * kwq/KWQKPartsBrowserExtension.h: Ditto.
+ * kwq/KWQLoader.mm:
+ (KWQServeRequest): Ditto.
+ (KWQServeSynchronousRequest): Ditto.
+
+ * kwq/KWQFormData.h: Added. A function to convert KHTML form data into an NSArray for communication
+ with the WebKit side.
+ * kwq/KWQFormData.mm: Added.
+
+ * kwq/WebCoreBridge.h: Pass NSArray instead of NSData for form data.
+
+ * kwq/KWQArrayImpl.h: Added a detach member function. The old version would do unnecessary work when
+ detach was called on an array that had exactly one reference.
+ * kwq/KWQArrayImpl.mm: (KWQArrayImpl::detach): Added.
+ * kwq/KWQMemArray.h: (QMemArray::detach): Call through to KWQArrayImpl.
+
+ * kwq/KWQValueList.h:
+ (QValueList::first): Added overload for non-const.
+ (QValueList::last): Ditto.
+
+ * ForwardingHeaders/misc/formdata.h: Added.
+ * WebCore.pbproj/project.pbxproj: Added formdata.h, formdata.cpp, KWQFormData.h, and KWQFormData.cpp.
+
+ * WebCore-tests.exp: Updated for changes to QValueList, and re-sorted.
+ * WebCore-combined.exp: Regenerated.
+
2004-08-30 Darin Adler <darin@apple.com>
Reviewed by Ken.
--- /dev/null
+#include <formdata.h>
__ZN16KWQValueListImpl5clearEv
__ZN16KWQValueListImpl6nodeAtEj
__ZN16KWQValueListImpl8fromLastEv
+__ZN16KWQValueListImpl8lastNodeEv
+__ZN16KWQValueListImpl9firstNodeEv
__ZN16KWQValueListImplC1EPFvP20KWQValueListNodeImplEPFS1_S1_E
__ZN16KWQValueListImplC1ERKS_
__ZN16KWQValueListImplD1Ev
__ZN24KWQValueListIteratorImplneERKS_
__ZN24KWQValueListIteratorImplppEi
__ZN24KWQValueListIteratorImplppEv
+__ZN3DOM13DOMStringImplD1Ev
__ZN4KURL11setProtocolERK7QString
__ZN4KURL13decode_stringERK7QStringPK10QTextCodec
__ZN4KURL6setRefERK7QString
__ZN5QRectC1Ev
__ZN5QSizeC1Eii
__ZN5QSizeC1Ev
-__ZNK5QTime7elapsedEv
__ZN5QTime7restartEv
__ZN5QTimeC1Eii
__ZN5QTimeC1Ev
__ZNK16KWQValueListImpl5countEv
__ZNK16KWQValueListImpl6nodeAtEj
__ZNK16KWQValueListImpl7isEmptyEv
-__ZNK16KWQValueListImpl8lastNodeEv
-__ZNK16KWQValueListImpl9firstNodeEv
__ZNK19KWQDictIteratorImpl16currentStringKeyEv
__ZNK19KWQListIteratorImpl5countEv
__ZNK19KWQListIteratorImpl7currentEv
__ZNK22KWQPtrDictIteratorImpl5countEv
__ZNK22KWQPtrDictIteratorImpl7currentEv
__ZNK24KWQValueListIteratorImpl4nodeEv
+__ZNK3DOM11ElementImpl17formatForDebuggerEPcj
+__ZNK3DOM23CSSStyleDeclarationImpl6lengthEv
+__ZNK3DOM8NodeImpl17formatForDebuggerEPcj
+__ZNK3DOM8Position17formatForDebuggerEPcj
+__ZNK3DOM8TextImpl17formatForDebuggerEPcj
+__ZNK3DOM9RangeImpl17formatForDebuggerEPcj
+__ZNK3DOM9Selection17formatForDebuggerEPcj
__ZNK4KURL3refEv
__ZNK4KURL3urlEv
__ZNK4KURL4hostEv
__ZNK5QSize10expandedToERKS_
__ZNK5QSize7isValidEv
__ZNK5QTime4msecEv
+__ZNK5QTime7elapsedEv
__ZNK7QRegExp5matchERK7QStringiPi
__ZNK7QRegExp7patternEv
__ZNK7QString10startsWithEPKc
__ZNK7QString10startsWithERKS_
__ZNK7QString15stripWhiteSpaceEv
__ZNK7QString18simplifyWhiteSpaceEv
+__ZNK7QString2atEj
__ZNK7QString3argERKS_i
__ZNK7QString3argEdi
__ZNK7QString3argEii
__ZplRK5QSizeS1_
__ZplRK6QPointS1_
__ZplcRK7QString
-__ZNK3DOM11ElementImpl17formatForDebuggerEPcj
-__ZNK3DOM8NodeImpl17formatForDebuggerEPcj
-__ZNK3DOM8Position17formatForDebuggerEPcj
-__ZNK3DOM8TextImpl17formatForDebuggerEPcj
-__ZNK3DOM9RangeImpl17formatForDebuggerEPcj
-__ZNK3DOM9Selection17formatForDebuggerEPcj
-__ZNK7QString2atEj
-__ZN3DOM13DOMStringImplD1Ev
-__ZNK3DOM23CSSStyleDeclarationImpl6lengthEv
-
__ZN16KWQValueListImpl5clearEv
__ZN16KWQValueListImpl6nodeAtEj
__ZN16KWQValueListImpl8fromLastEv
+__ZN16KWQValueListImpl8lastNodeEv
+__ZN16KWQValueListImpl9firstNodeEv
__ZN16KWQValueListImplC1EPFvP20KWQValueListNodeImplEPFS1_S1_E
__ZN16KWQValueListImplC1ERKS_
__ZN16KWQValueListImplD1Ev
__ZN24KWQValueListIteratorImplneERKS_
__ZN24KWQValueListIteratorImplppEi
__ZN24KWQValueListIteratorImplppEv
+__ZN3DOM13DOMStringImplD1Ev
__ZN4KURL11setProtocolERK7QString
__ZN4KURL13decode_stringERK7QStringPK10QTextCodec
__ZN4KURL6setRefERK7QString
__ZN5QRectC1Ev
__ZN5QSizeC1Eii
__ZN5QSizeC1Ev
-__ZNK5QTime7elapsedEv
__ZN5QTime7restartEv
__ZN5QTimeC1Eii
__ZN5QTimeC1Ev
__ZNK16KWQValueListImpl5countEv
__ZNK16KWQValueListImpl6nodeAtEj
__ZNK16KWQValueListImpl7isEmptyEv
-__ZNK16KWQValueListImpl8lastNodeEv
-__ZNK16KWQValueListImpl9firstNodeEv
__ZNK19KWQDictIteratorImpl16currentStringKeyEv
__ZNK19KWQListIteratorImpl5countEv
__ZNK19KWQListIteratorImpl7currentEv
__ZNK22KWQPtrDictIteratorImpl5countEv
__ZNK22KWQPtrDictIteratorImpl7currentEv
__ZNK24KWQValueListIteratorImpl4nodeEv
+__ZNK3DOM11ElementImpl17formatForDebuggerEPcj
+__ZNK3DOM23CSSStyleDeclarationImpl6lengthEv
+__ZNK3DOM8NodeImpl17formatForDebuggerEPcj
+__ZNK3DOM8Position17formatForDebuggerEPcj
+__ZNK3DOM8TextImpl17formatForDebuggerEPcj
+__ZNK3DOM9RangeImpl17formatForDebuggerEPcj
+__ZNK3DOM9Selection17formatForDebuggerEPcj
__ZNK4KURL3refEv
__ZNK4KURL3urlEv
__ZNK4KURL4hostEv
__ZNK5QSize10expandedToERKS_
__ZNK5QSize7isValidEv
__ZNK5QTime4msecEv
+__ZNK5QTime7elapsedEv
__ZNK7QRegExp5matchERK7QStringiPi
__ZNK7QRegExp7patternEv
__ZNK7QString10startsWithEPKc
__ZNK7QString10startsWithERKS_
__ZNK7QString15stripWhiteSpaceEv
__ZNK7QString18simplifyWhiteSpaceEv
+__ZNK7QString2atEj
__ZNK7QString3argERKS_i
__ZNK7QString3argEdi
__ZNK7QString3argEii
__ZplRK5QSizeS1_
__ZplRK6QPointS1_
__ZplcRK7QString
-__ZNK3DOM11ElementImpl17formatForDebuggerEPcj
-__ZNK3DOM8NodeImpl17formatForDebuggerEPcj
-__ZNK3DOM8Position17formatForDebuggerEPcj
-__ZNK3DOM8TextImpl17formatForDebuggerEPcj
-__ZNK3DOM9RangeImpl17formatForDebuggerEPcj
-__ZNK3DOM9Selection17formatForDebuggerEPcj
-__ZNK7QString2atEj
-__ZN3DOM13DOMStringImplD1Ev
-__ZNK3DOM23CSSStyleDeclarationImpl6lengthEv
-
9348900606C00363007E7ACE,
BC06F24E06D18A7E004A6FA3,
BC06F25006D18A7E004A6FA3,
+ 93ABCE6006E1A42E0085925B,
+ 93B641F406E28C5C0055F610,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
BE1A407206CA8A33005B28CF,
BC06F24D06D18A7E004A6FA3,
BC06F24F06D18A7E004A6FA3,
+ 93ABCE5F06E1A42E0085925B,
+ 93B641F306E28C5C0055F610,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
settings = {
};
};
+ 93ABCE5D06E1A42E0085925B = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.cpp.cpp;
+ path = formdata.cpp;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 93ABCE5E06E1A42E0085925B = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ path = formdata.h;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 93ABCE5F06E1A42E0085925B = {
+ fileRef = 93ABCE5D06E1A42E0085925B;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 93ABCE6006E1A42E0085925B = {
+ fileRef = 93ABCE5E06E1A42E0085925B;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 93B641F106E28C5C0055F610 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.cpp.objcpp;
+ path = KWQFormData.mm;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 93B641F206E28C5C0055F610 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ path = KWQFormData.h;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 93B641F306E28C5C0055F610 = {
+ fileRef = 93B641F106E28C5C0055F610;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 93B641F406E28C5C0055F610 = {
+ fileRef = 93B641F206E28C5C0055F610;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
93CCF7D4033BD43C008635CE = {
fileEncoding = 30;
isa = PBXFileReference;
93CCF7D5033BD43C008635CE,
9394E0A903AA60FB008635CE,
9394E0AA03AA60FB008635CE,
+ 93B641F206E28C5C0055F610,
+ 93B641F106E28C5C0055F610,
93D1FEF6067EBF89009CE68A,
F58784EE02DE375901EA4122,
F58784EF02DE375901EA4122,
};
F523D29C02DE43D9018635CA = {
children = (
+ BC7294F703804B3C00A80166,
+ BC7294F803804B3C00A80166,
F523D27802DE43D7018635CA,
F523D27902DE43D7018635CA,
+ 93ABCE5D06E1A42E0085925B,
+ 93ABCE5E06E1A42E0085925B,
F523D27A02DE43D7018635CA,
F523D27B02DE43D7018635CA,
F523D27D02DE43D7018635CA,
F523D28802DE43D7018635CA,
BC433ACF05D3046F003A5A14,
F523D28902DE43D7018635CA,
- BC7294F703804B3C00A80166,
- BC7294F803804B3C00A80166,
);
isa = PBXGroup;
path = misc;
#include "html_imageimpl.h"
#include "khtml_settings.h"
#include "misc/htmlhashes.h"
+#include "misc/formdata.h"
#include "css/cssstyleselector.h"
#include "css/cssproperties.h"
#include <assert.h>
-using namespace DOM;
using namespace khtml;
+namespace DOM {
+
+class FormDataList {
+public:
+ FormDataList(QTextCodec *);
+
+ void appendData(const DOMString &key, const DOMString &value)
+ { appendString(key.string()); appendString(value.string()); }
+ void appendData(const DOMString &key, const QString &value)
+ { appendString(key.string()); appendString(value); }
+ void appendData(const DOMString &key, const QCString &value)
+ { appendString(key.string()); appendString(value); }
+ void appendData(const DOMString &key, int value)
+ { appendString(key.string()); appendString(QString::number(value)); }
+ void appendFile(const DOMString &key, const DOMString &filename);
+
+ // Temporary API.
+ QValueListConstIterator<QCString> begin() const;
+ QValueListConstIterator<QCString> end() const;
+
+private:
+ void appendString(const QCString &s);
+ void appendString(const QString &s);
+
+ QTextCodec *m_codec;
+ QValueList<QCString> m_strings;
+};
+
HTMLFormElementImpl::HTMLFormElementImpl(DocumentPtr *doc)
: HTMLElementImpl(doc)
{
return result;
}
-inline static QCString fixUpfromUnicode(const QTextCodec* codec, const QString& s)
-{
- QCString str = fixLineBreaks(codec->fromUnicode(s));
- str.truncate(str.length());
- return str;
-}
-
#if !APPLE_CHANGES
void HTMLFormElementImpl::i18nData()
#endif
-QByteArray HTMLFormElementImpl::formData(bool& ok)
+bool HTMLFormElementImpl::formData(FormData &form_data) const
{
#ifdef FORMS_DEBUG
kdDebug( 6030 ) << "form: formData()" << endl;
#endif
- QByteArray form_data(0);
QCString enc_string = ""; // used for non-multipart data
// find out the QTextcodec to use
for (QPtrListIterator<HTMLGenericFormElementImpl> it(formElements); it.current(); ++it) {
HTMLGenericFormElementImpl* current = it.current();
- khtml::encodingList lst;
+ FormDataList lst(codec);
- if (!current->disabled() && current->encoding(codec, lst, m_multipart))
+ if (!current->disabled() && current->appendFormData(lst, m_multipart))
{
//kdDebug(6030) << "adding name " << current->name().string() << endl;
- khtml::encodingList::Iterator it;
- for( it = lst.begin(); it != lst.end(); ++it )
+ for(QValueListConstIterator<QCString> it = lst.begin(); it != lst.end(); ++it )
{
if (!m_multipart)
{
++it;
// append body
- unsigned int old_size = form_data.size();
- form_data.resize( old_size + hstr.length() + (*it).size() + 1);
- memcpy(form_data.data() + old_size, hstr.data(), hstr.length());
- memcpy(form_data.data() + old_size + hstr.length(), (*it), (*it).size());
- form_data[form_data.size()-2] = '\r';
- form_data[form_data.size()-1] = '\n';
+ form_data.appendData(hstr.data(), hstr.length());
+ form_data.appendData(*it, (*it).size() - 1);
+ form_data.appendData("\r\n", 2);
}
}
}
if (result == KMessageBox::Cancel) {
- ok = false;
- return QByteArray();
+ return false;
}
}
#endif
if (m_multipart)
enc_string = ("--" + m_boundary.string() + "--\r\n").ascii();
- int old_size = form_data.size();
- form_data.resize( form_data.size() + enc_string.length() );
- memcpy(form_data.data() + old_size, enc_string.data(), enc_string.length() );
-
- ok = true;
- return form_data;
+ form_data.appendData(enc_string.data(), enc_string.length());
+ return true;
}
void HTMLFormElementImpl::setEnctype( const DOMString& type )
firstSuccessfulSubmitButton->setActivatedSubmit(true);
}
- bool ok;
- QByteArray form_data = formData(ok);
- if (ok) {
+ FormData form_data;
+ if (formData(form_data)) {
if(m_post) {
part->submitForm( "post", m_url.string(), form_data,
m_target.string(),
m_activeSubmit = flag;
}
-bool HTMLButtonElementImpl::encoding(const QTextCodec* codec, khtml::encodingList& encoding, bool /*multipart*/)
+bool HTMLButtonElementImpl::appendFormData(FormDataList& encoding, bool /*multipart*/)
{
if (m_type != SUBMIT || name().isEmpty() || !m_activeSubmit)
return false;
-
- encoding += fixUpfromUnicode(codec, name().string());
- QString enc_str = m_currValue.isNull() ? QString("") : m_currValue;
- encoding += fixUpfromUnicode(codec, enc_str);
-
+ encoding.appendData(name(), m_currValue);
return true;
}
m_activeSubmit = flag;
}
-bool HTMLInputElementImpl::encoding(const QTextCodec* codec, khtml::encodingList& encoding, bool multipart)
+bool HTMLInputElementImpl::appendFormData(FormDataList &encoding, bool multipart)
{
- QString nme = name().string();
-
- // image generates its own name's
- if (nme.isEmpty() && m_type != IMAGE) return false;
-
- // IMAGE needs special handling later
- if(m_type != IMAGE) encoding += fixUpfromUnicode(codec, nme);
+ // image generates its own names
+ if (name().isEmpty() && m_type != IMAGE) return false;
switch (m_type) {
case HIDDEN:
#endif
case PASSWORD:
// always successful
- encoding += fixUpfromUnicode(codec, value().string());
+ encoding.appendData(name(), value());
return true;
- case CHECKBOX:
-
- if( checked() ) {
- encoding += fixUpfromUnicode(codec, value().string());
- return true;
- }
- break;
+ case CHECKBOX:
case RADIO:
-
- if( checked() ) {
- encoding += fixUpfromUnicode(codec, value().string());
+ if (checked()) {
+ encoding.appendData(name(), value());
return true;
}
break;
return false;
case IMAGE:
-
- if(m_activeSubmit)
+ if (m_activeSubmit)
{
- QString astr(nme.isEmpty() ? QString::fromLatin1("x") : nme + ".x");
-
- encoding += fixUpfromUnicode(codec, astr);
- astr.setNum(clickX());
- encoding += fixUpfromUnicode(codec, astr);
- astr = nme.isEmpty() ? QString::fromLatin1("y") : nme + ".y";
- encoding += fixUpfromUnicode(codec, astr);
- astr.setNum(clickY());
- encoding += fixUpfromUnicode(codec, astr);
-
+ encoding.appendData(name().isEmpty() ? QString::fromLatin1("x") : (name().string() + ".x"), clickX());
+ encoding.appendData(name().isEmpty() ? QString::fromLatin1("y") : (name().string() + ".y"), clickY());
return true;
}
break;
case SUBMIT:
-
if (m_activeSubmit)
{
QString enc_str = value().string();
if (enc_str.isEmpty())
enc_str = static_cast<RenderSubmitButton*>(m_render)->defaultLabel();
if (!enc_str.isEmpty()) {
- encoding += fixUpfromUnicode(codec, enc_str);
+ encoding.appendData(name(), enc_str);
return true;
}
}
if(!multipart || !renderer() || renderer()->style()->visibility() != khtml::VISIBLE)
return false;
- QString local;
- QCString dummy("");
-
// if no filename at all is entered, return successful, however empty
// null would be more logical but netscape posts an empty file. argh.
- if(value().isEmpty()) {
- encoding += dummy;
+ if (value().isEmpty()) {
+ encoding.appendData(name(), QString(""));
return true;
}
}
KFileItem fileitem(filestat, fileurl, true, false);
- if(fileitem.isDir()) {
- encoding += dummy;
+ if (fileitem.isDir()) {
return false;
}
+ QString local;
if ( KIO::NetAccess::download(fileurl, local) )
{
QFile file(local);
filearray[readbytes] = '\0';
file.close();
- encoding += filearray;
+ encoding.appendData(name(), filearray);
KIO::NetAccess::removeTempFile( local );
return true;
break;
}
case ISINDEX:
- encoding += fixUpfromUnicode(codec, value().string());
+ encoding.appendData(name(), value());
return true;
}
return false;
return new (arena) RenderSelect(this);
}
-bool HTMLSelectElementImpl::encoding(const QTextCodec* codec, khtml::encodingList& encoded_values, bool)
+bool HTMLSelectElementImpl::appendFormData(FormDataList& encoded_values, bool)
{
bool successful = false;
- QCString enc_name = fixUpfromUnicode(codec, name().string());
QMemArray<HTMLGenericFormElementImpl*> items = listItems();
uint i;
if (items[i]->id() == ID_OPTION) {
HTMLOptionElementImpl *option = static_cast<HTMLOptionElementImpl*>(items[i]);
if (option->selected()) {
- encoded_values += enc_name;
- encoded_values += fixUpfromUnicode(codec, option->value().string());
+ encoded_values.appendData(name(), option->value());
successful = true;
}
}
if (!successful && !m_multiple && m_size <= 1 && items.size() &&
(items[0]->id() == ID_OPTION) ) {
HTMLOptionElementImpl *option = static_cast<HTMLOptionElementImpl*>(items[0]);
- encoded_values += enc_name;
if (option->value().isNull())
- encoded_values += fixUpfromUnicode(codec, option->text().string().stripWhiteSpace());
+ encoded_values.appendData(name(), option->text().string().stripWhiteSpace());
else
- encoded_values += fixUpfromUnicode(codec, option->value().string());
+ encoded_values.appendData(name(), option->value());
successful = true;
}
}
}
-bool HTMLKeygenElementImpl::encoding(const QTextCodec* codec, khtml::encodingList& encoded_values, bool)
+bool HTMLKeygenElementImpl::appendFormData(FormDataList& encoded_values, bool)
{
- bool successful = false;
- QCString enc_name = fixUpfromUnicode(codec, name().string());
-
#if APPLE_CHANGES
// Only RSA is supported at this time.
if (!m_keyType.isNull() && strcasecmp(m_keyType, "rsa")) {
return false;
}
- QString value = KSSLKeyGen::signedPublicKeyAndChallengeString((unsigned)selectedIndex(), m_challenge.string(), getDocument()->part()->baseURL());
- if (!value.isNull()) {
- encoded_values += enc_name;
- encoded_values += value.utf8();
- successful = true;
+ QString value = KSSLKeyGen::signedPublicKeyAndChallengeString(selectedIndex(), m_challenge.string(), getDocument()->part()->baseURL());
+ if (value.isNull()) {
+ return false;
}
+ encoded_values.appendData(name(), value.utf8());
+ return true;
#else
- encoded_values += enc_name;
-
+ bool successful = false;
+
// pop up the fancy certificate creation dialog here
KSSLKeyGen *kg = new KSSLKeyGen(static_cast<RenderWidget *>(m_render)->widget(), "Key Generator", true);
delete kg;
- encoded_values += "deadbeef";
-#endif
+ encoded_values.appendData(name(), "deadbeef");
return successful;
+#endif
}
// -------------------------------------------------------------------------
return new (arena) RenderTextArea(this);
}
-bool HTMLTextAreaElementImpl::encoding(const QTextCodec* codec, encodingList& encoding, bool)
+bool HTMLTextAreaElementImpl::appendFormData(FormDataList& encoding, bool)
{
if (name().isEmpty()) return false;
-
- encoding += fixUpfromUnicode(codec, name().string());
- encoding += fixUpfromUnicode(codec, value().string());
-
+ encoding.appendData(name(), value());
return true;
}
// Not yet implemented.
return 0;
}
+
+// -------------------------------------------------------------------------
+
+FormDataList::FormDataList(QTextCodec *c)
+ : m_codec(c)
+{
+}
+
+void FormDataList::appendString(const QCString &s)
+{
+ m_strings.append(s);
+}
+
+void FormDataList::appendString(const QString &s)
+{
+ QCString cstr = fixLineBreaks(m_codec->fromUnicode(s));
+ cstr.truncate(cstr.length());
+ m_strings.append(cstr);
+}
+
+QValueListConstIterator<QCString> FormDataList::begin() const
+{
+ return m_strings.begin();
+}
+
+QValueListConstIterator<QCString> FormDataList::end() const
+{
+ return m_strings.end();
+}
+
+} // namespace
#include "html/html_elementimpl.h"
#include "dom/html_element.h"
-#include <qvaluelist.h>
#include <qptrlist.h>
-#include <qcstring.h>
#include <qmemarray.h>
class KHTMLView;
namespace khtml
{
+ class FormData;
class RenderFormElement;
class RenderTextArea;
class RenderSelect;
#if APPLE_CHANGES
class RenderSlider;
#endif
-
- typedef QValueList<QCString> encodingList;
}
namespace DOM {
-class HTMLFormElement;
class DOMString;
+class FormDataList;
+class HTMLFormElement;
class HTMLGenericFormElementImpl;
-class HTMLOptionElementImpl;
class HTMLImageLoader;
+class HTMLOptionElementImpl;
class HTMLOptionsCollectionImpl;
// -------------------------------------------------------------------------
long length() const;
- QByteArray formData(bool& ok);
-
DOMString enctype() const { return m_enctype; }
void setEnctype( const DOMString & );
bool m_doingsubmit : 1;
bool m_inreset : 1;
bool m_malformed : 1;
+
private:
+ bool formData(khtml::FormData &) const;
+
QString oldIdAttr;
QString oldNameAttr;
};
* for submitting
* return true for a successful control (see HTML4-17.13.2)
*/
- virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool) { return false; }
+ virtual bool appendFormData(FormDataList&, bool) { return false; }
virtual void defaultEventHandler(EventImpl *evt);
virtual bool isEditable();
virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
virtual void defaultEventHandler(EventImpl *evt);
- virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
+ virtual bool appendFormData(FormDataList&, bool);
virtual bool isSuccessfulSubmitButton() const;
virtual bool isActivatedSubmit() const;
virtual void attach();
virtual bool rendererIsNeeded(khtml::RenderStyle *);
virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
- virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
+ virtual bool appendFormData(FormDataList&, bool);
virtual bool isSuccessfulSubmitButton() const;
virtual bool isActivatedSubmit() const;
virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
- virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
+ virtual bool appendFormData(FormDataList&, bool);
// get the actual listbox index of the optionIndexth option
int optionToListIndex(int optionIndex) const;
virtual bool isEnumeratable() const { return false; }
virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
- virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
+ virtual bool appendFormData(FormDataList&, bool);
protected:
AtomicString m_challenge;
AtomicString m_keyType;
virtual void childrenChanged();
virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
- virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
+ virtual bool appendFormData(FormDataList&, bool);
virtual void reset();
DOMString value();
void setValue(DOMString _value);
using khtml::Decoder;
using khtml::DeleteSelectionCommand;
using khtml::EditCommand;
+using khtml::FormData;
using khtml::InlineTextBox;
using khtml::plainText;
using khtml::RenderObject;
disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
}
-void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
+void KHTMLPart::submitForm( const char *action, const QString &url, const FormData &formData, const QString &_target, const QString& contentType, const QString& boundary )
{
kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
KURL u = completeURL( url );
QString bodyEnc;
if (contentType.lower() == "multipart/form-data") {
// FIXME: is this correct? I suspect not
- bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
- formData.size()));
+ bodyEnc = KURL::encode_string(formData.flattenToString());
} else if (contentType.lower() == "text/plain") {
// Convention seems to be to decode, and s/&/\n/
- QString tmpbody = QString::fromLatin1(formData.data(),
- formData.size());
- tmpbody.replace(QRegExp("[&]"), "\n");
- tmpbody.replace(QRegExp("[+]"), " ");
+ QString tmpbody = formData.flattenToString();
+ tmpbody.replace('&', '\n');
+ tmpbody.replace('+', ' ');
tmpbody = KURL::decode_string(tmpbody); // Decode the rest of it
bodyEnc = KURL::encode_string(tmpbody); // Recode for the URL
} else {
- bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
- formData.size()));
+ bodyEnc = KURL::encode_string(formData.flattenToString());
}
nvps.append(QString("body=%1").arg(bodyEnc));
if ( strcmp( action, "get" ) == 0 ) {
if (u.protocol() != "mailto")
- u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
+ u.setQuery( formData.flattenToString() );
args.setDoPost( false );
}
else {
+#if APPLE_CHANGES
args.postData = formData;
+#else
+ args.postData = formData.flatten();
+#endif
args.setDoPost( true );
// construct some user headers if necessary
class DocLoader;
class DrawContentsEvent;
class EditCommand;
+ class FormData;
class HTMLTokenizer;
class MouseDoubleClickEvent;
class MouseEvent;
/**
* @internal
*/
- void submitForm( const char *action, const QString &url, const QByteArray &formData,
+ void submitForm( const char *action, const QString &url, const khtml::FormData &formData,
const QString &target, const QString& contentType = QString::null,
const QString& boundary = QString::null );
#include "khtml_iface.h"
#include "khtml_settings.h"
#include "misc/decoder.h"
+#include "misc/formdata.h"
#include "java/kjavaappletcontext.h"
#include "ecma/kjs_proxy.h"
#include "css/css_valueimpl.h"
{
const char *submitAction;
QString submitUrl;
- QByteArray submitFormData;
+ khtml::FormData submitFormData;
QString target;
QString submitContentType;
QString submitBoundary;
--- /dev/null
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2004 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "formdata.h"
+
+namespace khtml {
+
+FormData::FormData()
+{
+}
+
+FormData::FormData(const QCString &s)
+{
+ appendData(s.data(), s.length());
+}
+
+void FormData::appendData(const void *data, size_t size)
+{
+ if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::data) {
+ m_elements.append(FormDataElement());
+ }
+ FormDataElement &e = m_elements.last();
+ size_t oldSize = e.m_data.size();
+ e.m_data.resize(oldSize + size);
+ memcpy(e.m_data.data() + oldSize, data, size);
+}
+
+QByteArray FormData::flatten() const
+{
+ // Concatenate all the byte arrays, but omit any files.
+ QByteArray a;
+ for (QValueListConstIterator<FormDataElement> it = m_elements.begin(); it != m_elements.end(); ++it) {
+ const FormDataElement &e = *it;
+ if (e.m_type == FormDataElement::data) {
+ size_t oldSize = a.size();
+ if (oldSize == 0) {
+ a = e.m_data;
+ } else {
+ a.detach();
+ size_t delta = e.m_data.size();
+ a.resize(oldSize + delta);
+ memcpy(a.data() + oldSize, e.m_data.data(), delta);
+ }
+ }
+ }
+ return a;
+}
+
+QString FormData::flattenToString() const
+{
+ QByteArray bytes = flatten();
+ return QString::fromLatin1(bytes.data(), bytes.size());
+}
+
+} // namespace khtml
--- /dev/null
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2004 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef KHTML_FORM_DATA_H
+#define KHTML_FORM_DATA_H
+
+#include <qstring.h>
+#include <qvaluelist.h>
+
+class QCString;
+
+namespace khtml {
+
+class FormDataElement {
+public:
+ FormDataElement() : m_type(data) { }
+
+ enum { data, encodedFile } m_type;
+ QByteArray m_data;
+ QString m_filename;
+};
+
+class FormData {
+public:
+ FormData();
+ FormData(const QCString &);
+
+ void appendData(const void *data, size_t size);
+
+ QByteArray flatten() const; // omits files
+ QString flattenToString() const; // omits files
+
+ QValueList<FormDataElement> m_elements;
+};
+
+} // namespace khtml
+
+#endif
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
bool resize(size_t size);
void duplicate(const void *data, size_t size);
bool fill(const void *item, int size = -1);
+ void detach();
bool operator==(const KWQArrayImpl &) const;
+
private:
class KWQArrayPrivate
{
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
memcpy(d->data, data, newSize * d->itemSize);
}
+void KWQArrayImpl::detach()
+{
+ if (d->refCount > 1) {
+ duplicate(d->data, d->numItems);
+ }
+}
+
bool KWQArrayImpl::fill(const void *item, int numItems)
{
if (numItems == -1) {
--- /dev/null
+/*
+ * Copyright (C) 2004 Apple Computer, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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.
+ */
+
+#import <Foundation/Foundation.h>
+
+namespace khtml {
+ class FormData;
+}
+
+NSArray *arrayFromFormData(const khtml::FormData &);
--- /dev/null
+/*
+ * Copyright (C) 2004 Apple Computer, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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.
+ */
+
+#import "KWQFormData.h"
+
+#import "KWQAssertions.h"
+#import "formdata.h"
+
+using khtml::FormData;
+using khtml::FormDataElement;
+
+NSArray *arrayFromFormData(const FormData &d)
+{
+ NSMutableArray *a = [NSMutableArray arrayWithCapacity:d.m_elements.count()];
+ for (QValueListConstIterator<FormDataElement> it = d.m_elements.begin(); it != d.m_elements.end(); ++it) {
+ const FormDataElement &e = *it;
+ if (e.m_type == FormDataElement::data) {
+ [a addObject:[NSData dataWithBytes:e.m_data.data() length:e.m_data.size()]];
+ } else {
+ ASSERT(e.m_type == FormDataElement::encodedFile);
+ [a addObject:e.m_filename.getNSString()];
+ }
+ }
+ return a;
+}
#import "KWQDummyView.h"
#import "KWQEditCommand.h"
#import "KWQExceptions.h"
+#import "KWQFormData.h"
+#import "KWQFoundationExtras.h"
#import "KWQKJobClasses.h"
#import "KWQLogging.h"
#import "KWQPageState.h"
#import "KWQPrinter.h"
#import "KWQScrollBar.h"
#import "KWQWindowWidget.h"
-#import "KWQFoundationExtras.h"
#import "WebCoreBridge.h"
#import "WebCoreGraphicsBridge.h"
#import "WebCoreViewFactory.h"
[_bridge postWithURL:url.getNSURL()
referrer:[_bridge referrer]
target:args.frameName.getNSString()
- data:[NSData dataWithBytes:args.postData.data() length:args.postData.size()]
+ data:arrayFromFormData(args.postData)
contentType:args.contentType().mid(14).getNSString()
triggeringEvent:_currentEvent
form:_formAboutToBeSubmitted
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#ifndef JOB_H_
#define JOB_H_
-#include "KWQKURL.h"
#include "KWQKJobClasses.h"
// for time_t
void http_update_cache(const KURL &, bool, time_t);
-inline TransferJob *get(const KURL &url, bool reload = false, bool showProgressInfo = true)
- { return new TransferJob(url, reload, showProgressInfo); }
+inline TransferJob *get(const KURL &url, bool reload, bool)
+ { return new TransferJob(url, reload); }
-inline TransferJob *http_post(const KURL& url, const QByteArray &postData, bool showProgressInfo = true)
- { return new TransferJob(url, postData, showProgressInfo); }
+inline TransferJob *http_post(const KURL& url, const khtml::FormData &postData, bool)
+ { return new TransferJob(url, postData); }
} // namespace KIO
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "KWQMap.h"
#include "KWQObject.h"
#include "KWQString.h"
-
#include "KWQKURL.h"
#ifdef __OBJC__
class KWQResourceLoader;
#endif
+namespace khtml {
+ class FormData;
+}
+
namespace KIO {
class TransferJobPrivate;
class TransferJob : public Job {
public:
- TransferJob(const KURL &, bool reload = false, bool showProgressInfo = true);
- TransferJob(const KURL &, const QByteArray &postData, bool showProgressInfo = true);
+ TransferJob(const KURL &, bool reload);
+ TransferJob(const KURL &, const khtml::FormData &postData);
~TransferJob();
int error() const;
void emitResult();
void emitReceivedResponse(void *);
- QByteArray postData() const;
+ khtml::FormData postData() const;
QString method() const;
+
private:
void assembleResponseHeaders() const;
void retrieveCharset() const;
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#import "KWQString.h"
#import "KWQFoundationExtras.h"
+#import "formdata.h"
+
+using khtml::FormData;
+
namespace KIO {
// The allocations and releases in TransferJobPrivate are
{
}
- TransferJobPrivate(const KURL& kurl, const QByteArray &_postData)
+ TransferJobPrivate(const KURL& kurl, const FormData &_postData)
: status(0)
, metaData(KWQRetainNSRelease([[NSMutableDictionary alloc] initWithCapacity:17]))
, URL(kurl)
KURL URL;
KWQResourceLoader *loader;
QString method;
- QByteArray postData;
+ FormData postData;
void *response;
bool assembledResponseHeaders;
QString responseHeaders;
};
-TransferJob::TransferJob(const KURL &url, bool reload, bool showProgressInfo)
+TransferJob::TransferJob(const KURL &url, bool reload)
: d(new TransferJobPrivate(url)),
m_data(this, SIGNAL(data(KIO::Job*, const char*, int))),
m_redirection(this, SIGNAL(redirection(KIO::Job*, const KURL&))),
{
}
-TransferJob::TransferJob(const KURL &url, const QByteArray &postData, bool showProgressInfo)
+TransferJob::TransferJob(const KURL &url, const FormData &postData)
: d(new TransferJobPrivate(url, postData)),
m_data(this, SIGNAL(data(KIO::Job*, const char*, int))),
m_redirection(this, SIGNAL(redirection(KIO::Job*, const KURL&))),
return d->URL;
}
-QByteArray TransferJob::postData() const
+FormData TransferJob::postData() const
{
return d->postData;
}
#include "KWQKPartsPart.h"
#include "KWQKPartsBrowserInterface.h"
+#include "formdata.h"
+
class KXMLGUIClient { };
namespace KParts {
struct URLArgs {
QString frameName;
- QByteArray postData;
+ khtml::FormData postData;
bool reload;
QString serviceType;
int xOffset;
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#import "KWQLoader.h"
#import "KWQExceptions.h"
+#import "KWQFormData.h"
+#import "KWQFoundationExtras.h"
#import "KWQKJobClasses.h"
#import "KWQLogging.h"
#import "KWQResourceLoader.h"
-#import "KWQFoundationExtras.h"
#import "WebCoreBridge.h"
#import "khtml_part.h"
#import "loader.h"
}
if (job->method() == "POST") {
- NSData *postData = [NSData dataWithBytesNoCopy:job->postData().data() length:job->postData().size() freeWhenDone:NO];
- handle = [bridge startLoadingResource:resourceLoader withURL:job->url().getNSURL() customHeaders:headerDict postData:postData];
+ handle = [bridge startLoadingResource:resourceLoader withURL:job->url().getNSURL() customHeaders:headerDict
+ postData:arrayFromFormData(job->postData())];
} else {
handle = [bridge startLoadingResource:resourceLoader withURL:job->url().getNSURL() customHeaders:headerDict];
}
headerDict = [[NSDictionary alloc] _webcore_initWithHeaderString:headerString.getNSString()];
}
- NSData *postData = nil;
-
-
+ NSArray *postData = nil;
if (job->method() == "POST") {
- postData = [NSData dataWithBytesNoCopy:job->postData().data() length:job->postData().size() freeWhenDone:NO];
+ postData = arrayFromFormData(job->postData());
}
NSURL *finalNSURL = nil;
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
uint count() const { return impl.size(); }
bool resize(uint size) { return impl.resize(size); }
QMemArray<T>& duplicate(const T *data, int size) { impl.duplicate(data, size); return *this; }
- void detach() { duplicate(data(), size()); }
+ void detach() { impl.detach(); }
bool fill(const T &item, int size=-1) { return impl.fill(&item, size); }
QMemArray<T>& assign(const QMemArray<T> &a) { return *this = a; }
/*
- * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Iterator remove(Iterator iter) { return impl.removeIterator(iter.impl); }
Iterator fromLast() { return impl.fromLast(); }
- const T& first() const { return ((QValueListNode<T> *)impl.firstNode())->value; }
- const T& last() const { return ((QValueListNode<T> *)impl.lastNode())->value; }
+ T& first() { return static_cast<QValueListNode<T> *>(impl.firstNode())->value; }
+ const T& first() const { return static_cast<QValueListNode<T> *>(impl.firstNode())->value; }
+ T& last() { return static_cast<QValueListNode<T> *>(impl.lastNode())->value; }
+ const T& last() const { return static_cast<QValueListNode<T> *>(impl.lastNode())->value; }
Iterator begin() { return impl.begin(); }
Iterator end() { return impl.end(); }
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import <Foundation/Foundation.h>
-#import <AppKit/NSDragging.h> // for NSDragOperation typedef
-
-#import <WebCore/WebCoreKeyboardAccess.h>
+#import <Cocoa/Cocoa.h>
#import <JavaScriptCore/npruntime.h>
#import <JavaVM/jni.h>
+#import <WebCore/WebCoreKeyboardAccess.h>
#ifdef __cplusplus
// The WebCoreBridge protocol contains methods for use by the WebCore side of the bridge.
+// In NSArray objects for post data, NSData objects represent literal data, and NSString objects represent encoded files.
+// The encoding is the standard form encoding for uploading files.
+
@protocol WebCoreBridge
- (NSArray *)childFrames; // WebCoreBridge objects
- (NSView *)documentView;
- (void)loadURL:(NSURL *)URL referrer:(NSString *)referrer reload:(BOOL)reload userGesture:(BOOL)forUser target:(NSString *)target triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values;
-- (void)postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSData *)data contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values;
+- (void)postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSArray *)data contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values;
- (WebCoreBridge *)createWindowWithURL:(NSURL *)URL frameName:(NSString *)name;
- (void)showWindow;
- (void)addMessageToConsole:(NSDictionary *)message;
- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)loader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders;
-- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)loader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders postData:(NSData *)data;
+- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)loader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders postData:(NSArray *)data;
- (void)objectLoadedFromCacheWithURL:(NSURL *)URL response:(id)response size:(unsigned)bytes;
-- (NSData *)syncLoadResourceWithURL:(NSURL *)URL customHeaders:(NSDictionary *)requestHeaders postData:(NSData *)postData finalURL:(NSURL **)finalNSURL responseHeaders:(NSDictionary **)responseHeaderDict statusCode:(int *)statusCode;
+- (NSData *)syncLoadResourceWithURL:(NSURL *)URL customHeaders:(NSDictionary *)requestHeaders postData:(NSArray *)postData finalURL:(NSURL **)finalNSURL responseHeaders:(NSDictionary **)responseHeaderDict statusCode:(int *)statusCode;
- (BOOL)isReloading;
- (time_t)expiresTimeForResponse:(NSURLResponse *)response;
+2004-08-30 Darin Adler <darin@apple.com>
+
+ Reviewed by Chris.
+
+ - did work to prepare for uploading files incrementally when submitting forms
+
+ * History.subproj/WebHistoryItem.m:
+ (-[WebHistoryItem _setFormInfoFromRequest:]): Use NSArray instead of NSData for form data.
+ (-[WebHistoryItem formData]): Ditto.
+ * History.subproj/WebHistoryItemPrivate.h: Ditto.
+ * WebCoreSupport.subproj/WebBridge.m:
+ (-[WebBridge startLoadingResource:withURL:customHeaders:postData:]): Ditto.
+ (-[WebBridge syncLoadResourceWithURL:customHeaders:postData:finalURL:responseHeaders:statusCode:]): Ditto.
+ (-[WebBridge postWithURL:referrer:target:data:contentType:triggeringEvent:form:formValues:]): Ditto.
+ * WebCoreSupport.subproj/WebSubresourceClient.h: Ditto.
+ * WebCoreSupport.subproj/WebSubresourceClient.m:
+ (+[WebSubresourceClient startLoadingResource:withURL:customHeaders:postData:referrer:forDataSource:]): Ditto.
+ * WebView.subproj/WebFrame.m:
+ (-[WebFrame _loadItem:withLoadType:]): Ditto.
+ (-[WebFrame _postWithURL:referrer:target:data:contentType:triggeringEvent:form:formValues:]): Ditto.
+ * WebView.subproj/WebFramePrivate.h: Ditto.
+
+ * WebView.subproj/WebFormDataStream.h: Added.
+ * WebView.subproj/WebFormDataStream.m:
+ (-[WebFormDataStream initWithFormDataArray:]): Placeholder; not done yet.
+ (-[WebFormDataStream formDataArray]): Ditto.
+ * WebKit.pbproj/project.pbxproj: Added WebFormDataStream files.
+
2004-08-30 John Sullivan <sullivan@apple.com>
Reviewed by Ken.
BOOL notificationsSuppressed;
int visitCount;
// info used to repost form data
- NSData *formData;
+ NSArray *formData;
NSString *formContentType;
NSString *formReferrer;
// info used to support RSS feeds
- (void)_setFormInfoFromRequest:(NSURLRequest *)request
{
- NSData *newData = nil;
+ NSArray *newData = nil;
NSString *newContentType = nil;
NSString *newReferrer = nil;
if ([[request HTTPMethod] _web_isCaseInsensitiveEqualToString:@"POST"]) {
// save form state iff this is a POST
- newData = [[request HTTPBody] copy];
+
+ // FIXME: Eventually we have to make this smart enough to handle the case where
+ // we have a stream for the body to handle the "data interspersed with files" feature.
+ NSData *body = [request HTTPBody];
+ if (body) {
+ body = [body copy];
+ newData = [[NSArray alloc] initWithObjects:body, nil];
+ [body release];
+ }
+
newContentType = [[request HTTPContentType] copy];
newReferrer = [[request HTTPReferrer] copy];
}
_private->formReferrer = newReferrer;
}
-- (NSData *)formData
+- (NSArray *)formData
{
return _private->formData;
}
- (NSPoint)scrollPoint;
- (NSArray *)documentState;
- (BOOL)isTargetItem;
-- (NSData *)formData;
+- (NSArray *)formData;
- (NSString *)formContentType;
- (NSString *)formReferrer;
- (NSString *)RSSFeedReferrer;
forDataSource:[self dataSource]];
}
-- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)resourceLoader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders postData:(NSData *)data
+- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)resourceLoader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders postData:(NSArray *)postData
{
// If we are no longer attached to a WebView, this must be an attempted load from an
// onUnload handler, so let's just block it.
return [WebSubresourceClient startLoadingResource:resourceLoader
withURL:URL
customHeaders:customHeaders
- postData:data
+ postData:postData
referrer:[self referrer]
forDataSource:[self dataSource]];
}
[request release];
}
-- (NSData *)syncLoadResourceWithURL:(NSURL *)URL customHeaders:(NSDictionary *)requestHeaders postData:(NSData *)postData finalURL:(NSURL **)finalURL responseHeaders:(NSDictionary **)responseHeaderDict statusCode:(int *)statusCode
+- (NSData *)syncLoadResourceWithURL:(NSURL *)URL customHeaders:(NSDictionary *)requestHeaders postData:(NSArray *)postData finalURL:(NSURL **)finalURL responseHeaders:(NSDictionary **)responseHeaderDict statusCode:(int *)statusCode
{
NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] initWithURL:URL];
if (postData) {
[newRequest setHTTPMethod:@"POST"];
- [newRequest setHTTPBody:postData];
+
+ // FIXME: This will have to be expanded to handle filenames and arrays with more than one element to fix file uploading.
+ if ([postData count] == 1 && [[postData objectAtIndex:0] isKindOfClass:[NSData class]]) {
+ [newRequest setHTTPBody:(NSData *)[postData objectAtIndex:0]];
+ }
}
NSEnumerator *e = [requestHeaders keyEnumerator];
}
}
-- (void)postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSData *)data contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values
+- (void)postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSArray *)postData contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values
{
if ([target length] == 0) {
target = nil;
return;
}
- [_frame _postWithURL:URL referrer:(NSString *)referrer target:target data:data contentType:contentType triggeringEvent:event form:form formValues:values];
+ [_frame _postWithURL:URL referrer:referrer target:target data:postData contentType:contentType triggeringEvent:event form:form formValues:values];
if (targetFrame != nil && _frame != targetFrame) {
[[targetFrame _bridge] focusWindow];
WebSubresourceClient.h
Copyright (c) 2002, Apple Computer, Inc. All rights reserved.
*/
+
#import <Foundation/Foundation.h>
#import <WebKit/WebBaseResourceHandleDelegate.h>
@class WebDataSource;
-@class NSURLResponse;
@protocol WebCoreResourceHandle;
@protocol WebCoreResourceLoader;
+ (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
withURL:(NSURL *)URL
customHeaders:(NSDictionary *)customHeaders
- postData:(NSData *)data
+ postData:(NSArray *)postData
referrer:(NSString *)referrer
forDataSource:(WebDataSource *)source;
+ (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
withURL:(NSURL *)URL
customHeaders:(NSDictionary *)customHeaders
- postData:(NSData *)data
+ postData:(NSArray *)postData
referrer:(NSString *)referrer
forDataSource:(WebDataSource *)source
{
NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] initWithURL:URL];
+
[newRequest setHTTPMethod:@"POST"];
- [newRequest setHTTPBody:data];
+
+ // FIXME: This will have to be expanded to handle filenames and arrays with more than one element to fix file uploading.
+ if ([postData count] == 1 && [[postData objectAtIndex:0] isKindOfClass:[NSData class]]) {
+ [newRequest setHTTPBody:(NSData *)[postData objectAtIndex:0]];
+ }
+
WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest customHeaders:customHeaders referrer:referrer forDataSource:source];
[newRequest release];
WebSubresourceClient.h
Copyright (c) 2002, Apple Computer, Inc. All rights reserved.
*/
+
#import <Foundation/Foundation.h>
#import <WebKit/WebBaseResourceHandleDelegate.h>
@class WebDataSource;
-@class NSURLResponse;
@protocol WebCoreResourceHandle;
@protocol WebCoreResourceLoader;
+ (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
withURL:(NSURL *)URL
customHeaders:(NSDictionary *)customHeaders
- postData:(NSData *)data
+ postData:(NSArray *)postData
referrer:(NSString *)referrer
forDataSource:(WebDataSource *)source;
+ (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
withURL:(NSURL *)URL
customHeaders:(NSDictionary *)customHeaders
- postData:(NSData *)data
+ postData:(NSArray *)postData
referrer:(NSString *)referrer
forDataSource:(WebDataSource *)source
{
NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] initWithURL:URL];
+
[newRequest setHTTPMethod:@"POST"];
- [newRequest setHTTPBody:data];
+
+ // FIXME: This will have to be expanded to handle filenames and arrays with more than one element to fix file uploading.
+ if ([postData count] == 1 && [[postData objectAtIndex:0] isKindOfClass:[NSData class]]) {
+ [newRequest setHTTPBody:(NSData *)[postData objectAtIndex:0]];
+ }
+
WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest customHeaders:customHeaders referrer:referrer forDataSource:source];
[newRequest release];
51E94C3606C0321200A9B09E,
51E94C6A06C0347500A9B09E,
83634A7406DA5ECD0026E290,
+ 93B641FC06E292BC0055F610,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
51E94C3706C0321200A9B09E,
51E94C6B06C0347500A9B09E,
83634A7306DA5ECD0026E290,
+ 93B641FB06E292BC0055F610,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
settings = {
};
};
+ 93B641F906E292BC0055F610 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.objc;
+ path = WebFormDataStream.m;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 93B641FA06E292BC0055F610 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ path = WebFormDataStream.h;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 93B641FB06E292BC0055F610 = {
+ fileRef = 93B641F906E292BC0055F610;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 93B641FC06E292BC0055F610 = {
+ fileRef = 93B641FA06E292BC0055F610;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
93D1FE13067EB10B009CE68A = {
fileEncoding = 4;
isa = PBXFileReference;
2D81DAB203EB0B2D00A80166,
2D81DAB303EB0B2D00A80166,
5152FAE5033FC52200CA2ACD,
+ 93B641FA06E292BC0055F610,
+ 93B641F906E292BC0055F610,
2D36FD5E03F78F9E00A80166,
39446074020F50ED0ECA1767,
F5143A370221DCCE01A80181,
--- /dev/null
+/* Copyright 2004, Apple Computer, Inc. */
+
+#import <Foundation/Foundation.h>
+
+@interface WebFormDataStream : NSInputStream
+{
+ NSArray *_formDataArray;
+}
+
+- (id)initWithFormDataArray:(NSArray *)array;
+- (NSArray *)formDataArray;
+
+@end
--- /dev/null
+/* Copyright 2004, Apple Computer, Inc. */
+
+#import "WebFormDataStream.h"
+
+@implementation WebFormDataStream
+
+- (id)initWithFormDataArray:(NSArray *)array
+{
+ [super init];
+ _formDataArray = [array copy];
+ return self;
+}
+
+- (void)dealloc
+{
+ [_formDataArray release];
+ [super dealloc];
+}
+
+- (NSArray *)formDataArray
+{
+ return _formDataArray;
+}
+
+@end
return request;
}
-
- (BOOL)_shouldReloadToHandleUnreachableURLFromRequest:(NSURLRequest *)request
{
NSURL *unreachableURL = [request _webDataRequestUnreachableURL];
NSURL *itemURL = [item URL];
NSURL *itemOriginalURL = [NSURL _web_URLWithDataAsString:[item originalURLString]];
NSURL *currentURL = [[[self dataSource] request] URL];
- NSData *formData = [item formData];
+ NSArray *formData = [item formData];
// Are we navigating to an anchor within the page?
// Note if we have child frames we do a real reload, since the child frames might not
NSDictionary *action;
if (formData) {
[request setHTTPMethod:@"POST"];
- [request setHTTPBody:formData];
- [request setHTTPContentType:[item formContentType]];
[request setHTTPReferrer:[item formReferrer]];
+ // FIXME: This will have to be expanded to handle filenames and arrays with more than one element to fix file uploading.
+ if ([formData count] == 1 && [[formData objectAtIndex:0] isKindOfClass:[NSData class]]) {
+ [request setHTTPBody:(NSData *)[formData objectAtIndex:0]];
+ [request setHTTPContentType:[item formContentType]];
+ }
+
// Slight hack to test if the WF cache contains the page we're going to. We want
// to know this before talking to the policy delegate, since it affects whether we
// show the DoYouReallyWantToRepost nag.
}
}
-- (void)_postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSData *)data contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values
+- (void)_postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSArray *)postData contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values
{
// When posting, use the NSURLRequestReloadIgnoringCacheData load flag.
// This prevents a potential bug which may cause a page with a form that uses itself
// as an action to be returned from the cache without submitting.
+
+ // FIXME: Where's the code that implements what the comment above says?
+
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL];
- [self _addExtraFieldsToRequest:request alwaysFromRequest: YES];
- [request setHTTPMethod:@"POST"];
- [request setHTTPBody:data];
- [request setHTTPContentType:contentType];
+ [self _addExtraFieldsToRequest:request alwaysFromRequest:YES];
[request setHTTPReferrer:referrer];
+ [request setHTTPMethod:@"POST"];
+
+ // FIXME: This will have to be expanded to handle filenames and arrays with more than one element to fix file uploading.
+ if ([postData count] == 1 && [[postData objectAtIndex:0] isKindOfClass:[NSData class]]) {
+ [request setHTTPBody:(NSData *)[postData objectAtIndex:0]];
+ [request setHTTPContentType:contentType];
+ }
NSDictionary *action = [self _actionInformationForLoadType:WebFrameLoadTypeStandard isFormSubmission:YES event:event originalURL:URL];
WebFormState *formState = nil;
- (void)_goToItem:(WebHistoryItem *)item withLoadType:(WebFrameLoadType)type;
- (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer loadType:(WebFrameLoadType)loadType target:(NSString *)target triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values;
- (void)_loadURL:(NSURL *)URL intoChild:(WebFrame *)childFrame;
-- (void)_postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSData *)data contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values;
+- (void)_postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSArray *)postData contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values;
- (void)_loadRequest:(NSURLRequest *)request inFrameNamed:(NSString *)frameName;