diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h
index fff910f6412..10485655c5d 100644
--- a/mozilla/content/base/public/nsIDocument.h
+++ b/mozilla/content/base/public/nsIDocument.h
@@ -39,6 +39,13 @@ class nsString;
{ 0x94c6ceb0, 0x9447, 0x11d1, \
{0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
+// specification for data to be sent via form "post"
+class nsIPostData {
+public:
+ virtual PRBool IsFile() = 0; // is the data a file (or raw data)
+ virtual const char* GetData() = 0; // get the file name or raw data
+};
+
//----------------------------------------------------------------------
// Document interface
@@ -49,7 +56,7 @@ public:
// returns the arena associated with this document.
virtual nsIArena* GetArena() = 0;
- virtual void LoadURL(nsIURL* aURL) = 0;
+ virtual void LoadURL(nsIURL* aURL, nsIPostData* aPostData = 0) = 0;
virtual void StartDocumentLoad() = 0;
virtual void PauseDocumentLoad() = 0;
@@ -169,5 +176,7 @@ public:
// XXX Belongs somewhere else
extern NS_LAYOUT nsresult
NS_NewHTMLDocument(nsIDocument** aInstancePtrResult);
+extern NS_LAYOUT nsresult
+ NS_NewPostData(nsIPostData* aPostData, nsIPostData** aInstancePtrResult);
#endif /* nsIDocument_h___ */
diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp
index b55c32284a6..add42e0beb0 100644
--- a/mozilla/content/base/src/nsDocument.cpp
+++ b/mozilla/content/base/src/nsDocument.cpp
@@ -39,6 +39,27 @@ static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
+NS_LAYOUT nsresult
+NS_NewPostData(nsIPostData* aPostData, nsIPostData** aInstancePtrResult)
+{
+ *aInstancePtrResult = new nsPostData(aPostData);
+ return NS_OK;
+}
+
+nsPostData::nsPostData(nsIPostData* aPostData)
+{
+ mIsFile = PR_FALSE;
+ mData = nsnull;
+ if (aPostData) {
+ mIsFile = aPostData->IsFile();
+ const char* data = aPostData->GetData();
+ if (data) {
+ PRInt32 len = strlen(data);
+ mData = new char[len+1];
+ strcpy(mData, data);
+ }
+ }
+}
nsDocument::nsDocument()
{
diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h
index 4b8cdc4ef37..b1e844aea73 100644
--- a/mozilla/content/base/src/nsDocument.h
+++ b/mozilla/content/base/src/nsDocument.h
@@ -25,6 +25,17 @@
class nsISelection;
+class nsPostData : public nsIPostData {
+public:
+ nsPostData(PRBool aIsFile, char* aData) : mIsFile(aIsFile), mData(aData) {}
+ nsPostData(nsIPostData* aPostData);
+ PRBool IsFile() { return mIsFile; }
+ const char* GetData() { return mData; }
+protected:
+ PRBool mIsFile;
+ char* mData;
+};
+
// Base class for our document implementations
class nsDocument : public nsIDocument, public nsIDOMDocument, public nsIScriptObjectOwner {
public:
diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp
index 81f6615b372..36832987494 100644
--- a/mozilla/content/html/document/src/nsHTMLDocument.cpp
+++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp
@@ -30,7 +30,7 @@
#include "nsIHTMLContent.h"
#include "nsIDOMElement.h"
#include "nsIDOMText.h"
-#include "nsIPostToServer.h" //XXX temp
+#include "nsIPostToServer.h"
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
@@ -72,7 +72,7 @@ NS_IMETHODIMP nsHTMLDocument::QueryInterface(REFNSIID aIID,
return nsDocument::QueryInterface(aIID, aInstancePtr);
}
-void nsHTMLDocument::LoadURL(nsIURL* aURL)
+void nsHTMLDocument::LoadURL(nsIURL* aURL, nsIPostData* aPostData)
{
// Delete references to style sheets - this should be done in superclass...
PRInt32 index = mStyleSheets.Count();
@@ -92,18 +92,18 @@ void nsHTMLDocument::LoadURL(nsIURL* aURL)
mDocumentURL = aURL;
NS_ADDREF(aURL);
- // XXX temporary hack code
static NS_DEFINE_IID(kPostToServerIID, NS_IPOSTTOSERVER_IID);
- const char* temp = aURL->GetFile();
- if (temp != NULL && strcmp(temp,"/cgi-bin/post-query") == 0) {
- nsIPostToServer* pts;
- nsresult result = aURL->QueryInterface(kPostToServerIID, (void **)&pts);
- if (NS_OK == result) {
- char buf[100];
- //strcpy(&buf[0], "Content-type: application/x-www-form-urlencoded\nname=foo");
- strcpy(&buf[0], "name=foo");
- PRInt32 len = strlen(&buf[0]);
- pts->SendData(&buf[0], len);
+ if (aPostData) {
+ const char* data = aPostData->GetData();
+ if (data) {
+ nsIPostToServer* pts;
+ nsresult result = aURL->QueryInterface(kPostToServerIID, (void **)&pts);
+ if (aPostData->IsFile()) {
+ pts->SendDataFromFile(data);
+ }
+ else {
+ pts->SendData(data, strlen(data));
+ }
}
}
diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h
index ca62208840c..df2da149826 100644
--- a/mozilla/content/html/document/src/nsHTMLDocument.h
+++ b/mozilla/content/html/document/src/nsHTMLDocument.h
@@ -30,7 +30,7 @@ public:
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
- virtual void LoadURL(nsIURL* aURL);
+ virtual void LoadURL(nsIURL* aURL, nsIPostData* aPostData = 0);
NS_IMETHOD SetTitle(const nsString& aTitle);
diff --git a/mozilla/layout/base/public/nsIDocument.h b/mozilla/layout/base/public/nsIDocument.h
index fff910f6412..10485655c5d 100644
--- a/mozilla/layout/base/public/nsIDocument.h
+++ b/mozilla/layout/base/public/nsIDocument.h
@@ -39,6 +39,13 @@ class nsString;
{ 0x94c6ceb0, 0x9447, 0x11d1, \
{0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
+// specification for data to be sent via form "post"
+class nsIPostData {
+public:
+ virtual PRBool IsFile() = 0; // is the data a file (or raw data)
+ virtual const char* GetData() = 0; // get the file name or raw data
+};
+
//----------------------------------------------------------------------
// Document interface
@@ -49,7 +56,7 @@ public:
// returns the arena associated with this document.
virtual nsIArena* GetArena() = 0;
- virtual void LoadURL(nsIURL* aURL) = 0;
+ virtual void LoadURL(nsIURL* aURL, nsIPostData* aPostData = 0) = 0;
virtual void StartDocumentLoad() = 0;
virtual void PauseDocumentLoad() = 0;
@@ -169,5 +176,7 @@ public:
// XXX Belongs somewhere else
extern NS_LAYOUT nsresult
NS_NewHTMLDocument(nsIDocument** aInstancePtrResult);
+extern NS_LAYOUT nsresult
+ NS_NewPostData(nsIPostData* aPostData, nsIPostData** aInstancePtrResult);
#endif /* nsIDocument_h___ */
diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp
index b55c32284a6..add42e0beb0 100644
--- a/mozilla/layout/base/src/nsDocument.cpp
+++ b/mozilla/layout/base/src/nsDocument.cpp
@@ -39,6 +39,27 @@ static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
+NS_LAYOUT nsresult
+NS_NewPostData(nsIPostData* aPostData, nsIPostData** aInstancePtrResult)
+{
+ *aInstancePtrResult = new nsPostData(aPostData);
+ return NS_OK;
+}
+
+nsPostData::nsPostData(nsIPostData* aPostData)
+{
+ mIsFile = PR_FALSE;
+ mData = nsnull;
+ if (aPostData) {
+ mIsFile = aPostData->IsFile();
+ const char* data = aPostData->GetData();
+ if (data) {
+ PRInt32 len = strlen(data);
+ mData = new char[len+1];
+ strcpy(mData, data);
+ }
+ }
+}
nsDocument::nsDocument()
{
diff --git a/mozilla/layout/base/src/nsDocument.h b/mozilla/layout/base/src/nsDocument.h
index 4b8cdc4ef37..b1e844aea73 100644
--- a/mozilla/layout/base/src/nsDocument.h
+++ b/mozilla/layout/base/src/nsDocument.h
@@ -25,6 +25,17 @@
class nsISelection;
+class nsPostData : public nsIPostData {
+public:
+ nsPostData(PRBool aIsFile, char* aData) : mIsFile(aIsFile), mData(aData) {}
+ nsPostData(nsIPostData* aPostData);
+ PRBool IsFile() { return mIsFile; }
+ const char* GetData() { return mData; }
+protected:
+ PRBool mIsFile;
+ char* mData;
+};
+
// Base class for our document implementations
class nsDocument : public nsIDocument, public nsIDOMDocument, public nsIScriptObjectOwner {
public:
diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp
index 81f6615b372..36832987494 100644
--- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp
+++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp
@@ -30,7 +30,7 @@
#include "nsIHTMLContent.h"
#include "nsIDOMElement.h"
#include "nsIDOMText.h"
-#include "nsIPostToServer.h" //XXX temp
+#include "nsIPostToServer.h"
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
@@ -72,7 +72,7 @@ NS_IMETHODIMP nsHTMLDocument::QueryInterface(REFNSIID aIID,
return nsDocument::QueryInterface(aIID, aInstancePtr);
}
-void nsHTMLDocument::LoadURL(nsIURL* aURL)
+void nsHTMLDocument::LoadURL(nsIURL* aURL, nsIPostData* aPostData)
{
// Delete references to style sheets - this should be done in superclass...
PRInt32 index = mStyleSheets.Count();
@@ -92,18 +92,18 @@ void nsHTMLDocument::LoadURL(nsIURL* aURL)
mDocumentURL = aURL;
NS_ADDREF(aURL);
- // XXX temporary hack code
static NS_DEFINE_IID(kPostToServerIID, NS_IPOSTTOSERVER_IID);
- const char* temp = aURL->GetFile();
- if (temp != NULL && strcmp(temp,"/cgi-bin/post-query") == 0) {
- nsIPostToServer* pts;
- nsresult result = aURL->QueryInterface(kPostToServerIID, (void **)&pts);
- if (NS_OK == result) {
- char buf[100];
- //strcpy(&buf[0], "Content-type: application/x-www-form-urlencoded\nname=foo");
- strcpy(&buf[0], "name=foo");
- PRInt32 len = strlen(&buf[0]);
- pts->SendData(&buf[0], len);
+ if (aPostData) {
+ const char* data = aPostData->GetData();
+ if (data) {
+ nsIPostToServer* pts;
+ nsresult result = aURL->QueryInterface(kPostToServerIID, (void **)&pts);
+ if (aPostData->IsFile()) {
+ pts->SendDataFromFile(data);
+ }
+ else {
+ pts->SendData(data, strlen(data));
+ }
}
}
diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.h b/mozilla/layout/html/document/src/nsHTMLDocument.h
index ca62208840c..df2da149826 100644
--- a/mozilla/layout/html/document/src/nsHTMLDocument.h
+++ b/mozilla/layout/html/document/src/nsHTMLDocument.h
@@ -30,7 +30,7 @@ public:
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
- virtual void LoadURL(nsIURL* aURL);
+ virtual void LoadURL(nsIURL* aURL, nsIPostData* aPostData = 0);
NS_IMETHOD SetTitle(const nsString& aTitle);
diff --git a/mozilla/layout/html/forms/src/nsForm.cpp b/mozilla/layout/html/forms/src/nsForm.cpp
index f9865b27003..161a0dfc828 100644
--- a/mozilla/layout/html/forms/src/nsForm.cpp
+++ b/mozilla/layout/html/forms/src/nsForm.cpp
@@ -38,6 +38,15 @@
#include "nsILinkHandler.h"
#include "nsInputRadio.h"
#include "nsIRadioButton.h"
+#include "nsInputFile.h"
+#include "nsDocument.h"
+
+#include "net.h"
+#include "xp_file.h"
+#include "prio.h"
+#include "prmem.h"
+
+#define CRLF "\015\012"
// netlib has a general function (netlib\modules\liburl\src\escape.c)
// which does url encoding. Since netlib is not yet available for raptor,
@@ -45,7 +54,7 @@
// conver each non alphanumeric char to %XY where XY is the hexadecimal
// equavalent of the binary representation of the character.
//
-void EscapeURLString(char* aInString, char* aOutString)
+void URLEncode(char* aInString, char* aOutString)
{
if (nsnull == aInString) {
return;
@@ -68,11 +77,11 @@ void EscapeURLString(char* aInString, char* aOutString)
*outChar = 0; // terminate the string
}
-nsString* EscapeURLString(nsString& aString)
+nsString* URLEncode(nsString& aString)
{
char* inBuf = aString.ToNewCString();
char* outBuf = new char[ (strlen(inBuf) * 3) + 1 ];
- EscapeURLString(inBuf, outBuf);
+ URLEncode(inBuf, outBuf);
nsString* result = new nsString(outBuf);
delete [] outBuf;
delete [] inBuf;
@@ -134,8 +143,19 @@ public:
virtual void Init(PRBool aReinit);
+ static nsString* gGET;
+ static nsString* gMULTIPART;
+
protected:
void RemoveRadioGroups();
+ void ProcessAsURLEncoded(PRBool aIsPost, nsIFormControl* aSubmitter, nsString& aData);
+ void ProcessAsMultipart(nsIFormControl* aSubmitter, nsString& aData);
+ static const char* GetFileNameWithinPath(char* aPathName);
+
+ // the following are temporary until nspr and/or netlib provide them
+ static Temp_GetTempDir(char* aTempDirName);
+ static char* Temp_GenerateTempFileName(PRInt32 aMaxSize, char* aBuffer);
+ static void Temp_GetContentType(char* aPathName, char* aContentType);
nsIAtom* mTag;
nsIHTMLAttributes* mAttributes;
@@ -154,6 +174,9 @@ protected:
// CLASS nsForm
+nsString* nsForm::gGET = new nsString("get");
+nsString* nsForm::gMULTIPART = new nsString("multipart/form-data");
+
// Note: operator new zeros our memory
nsForm::nsForm(nsIAtom* aTag)
{
@@ -269,47 +292,22 @@ void nsForm::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame,
{
nsString data; // this could be more efficient, by allocating a larger buffer
- nsAutoString method;
+ nsAutoString method, enctype;
GetAttribute("method", method);
- PRBool isPost = PR_TRUE;
- if (!method.EqualsIgnoreCase("post")) {
- isPost = PR_FALSE;
- data += '?';
+ GetAttribute("enctype", enctype);
+
+ PRBool isURLEncoded = (enctype.EqualsIgnoreCase(*gMULTIPART)) ? PR_FALSE : PR_TRUE;
+
+ // for enctype=multipart/form-data, force it to be post
+ PRBool isPost = (method.EqualsIgnoreCase(*gGET) && isURLEncoded) ? PR_FALSE : PR_TRUE;
+
+ if (isURLEncoded) {
+ ProcessAsURLEncoded(isPost, aSubmitter, data);
+ }
+ else {
+ ProcessAsMultipart(aSubmitter, data);
}
- PRBool firstTime = PR_TRUE;
-
- PRInt32 numChildren = mChildren.Count();
- // collect and encode the data from the children controls
- for (PRInt32 childX = 0; childX < numChildren; childX++) {
- nsIFormControl* child = (nsIFormControl*) mChildren.ElementAt(childX);
- if (child->IsSuccessful(aSubmitter)) {
- PRInt32 numValues = 0;
- PRInt32 maxNumValues = child->GetMaxNumValues();
- if (maxNumValues <= 0) {
- continue;
- }
- nsString* names = new nsString[maxNumValues];
- nsString* values = new nsString[maxNumValues];
- if (PR_TRUE == child->GetNamesValues(maxNumValues, numValues, values, names)) {
- for (int valueX = 0; valueX < numValues; valueX++) {
- if (PR_TRUE == firstTime) {
- firstTime = PR_FALSE;
- } else {
- data += "&";
- }
- nsString* convName = EscapeURLString(names[valueX]);
- data += *convName;
- delete convName;
- data += "=";
- nsString* convValue = EscapeURLString(values[valueX]);
- data += *convValue;
- delete convValue;
- }
- }
- delete [] values;
- }
- }
// make the url string
nsILinkHandler* handler;
@@ -339,13 +337,362 @@ void nsForm::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame,
NS_IF_RELEASE(docURL);
// Now pass on absolute url to the click handler
- handler->OnLinkClick(aFrame, absURLSpec, target);
+ nsPostData postData(!isURLEncoded, data.ToNewCString());
+ handler->OnLinkClick(aFrame, absURLSpec, target, &postData);
DebugPrint("url", absURLSpec);
DebugPrint("data", data);
}
}
+void nsForm::ProcessAsURLEncoded(PRBool isPost, nsIFormControl* aSubmitter, nsString& aData)
+{
+ nsString buf;
+ PRBool firstTime = PR_TRUE;
+
+ PRInt32 numChildren = mChildren.Count();
+ // collect and encode the data from the children controls
+ for (PRInt32 childX = 0; childX < numChildren; childX++) {
+ nsIFormControl* child = (nsIFormControl*) mChildren.ElementAt(childX);
+ if (child->IsSuccessful(aSubmitter)) {
+ PRInt32 numValues = 0;
+ PRInt32 maxNumValues = child->GetMaxNumValues();
+ if (maxNumValues <= 0) {
+ continue;
+ }
+ nsString* names = new nsString[maxNumValues];
+ nsString* values = new nsString[maxNumValues];
+ if (PR_TRUE == child->GetNamesValues(maxNumValues, numValues, values, names)) {
+ for (int valueX = 0; valueX < numValues; valueX++) {
+ if (PR_TRUE == firstTime) {
+ firstTime = PR_FALSE;
+ } else {
+ buf += "&";
+ }
+ nsString* convName = URLEncode(names[valueX]);
+ buf += *convName;
+ delete convName;
+ buf += "=";
+ nsString* convValue = URLEncode(values[valueX]);
+ buf += *convValue;
+ delete convValue;
+ }
+ }
+ delete [] names;
+ delete [] values;
+ }
+ }
+
+ aData.SetLength(0);
+ if (isPost) {
+ char size[16];
+ sprintf(size, "%d", buf.Length());
+ aData = "Content-type: application/x-www-form-urlencoded";
+ aData += CRLF;
+ aData += "Content-Length: ";
+ aData += size;
+ aData += CRLF;
+ aData += CRLF;
+ }
+ else {
+ aData += '?';
+ }
+
+ aData += buf;
+}
+
+// include the file name without the directory
+const char* nsForm::GetFileNameWithinPath(char* aPathName)
+{
+ char* fileNameStart = PL_strrchr(aPathName, '\\'); // windows
+ if (!fileNameStart) { // try unix
+ fileNameStart = PL_strrchr(aPathName, '\\');
+ }
+ if (fileNameStart) {
+ return fileNameStart+1;
+ }
+ else {
+ return aPathName;
+ }
+}
+
+// this needs to be provided by a higher level, since navigator might override
+// the temp directory. XXX does not check that parm is big enough
+nsForm::Temp_GetTempDir(char* aTempDirName)
+{
+ aTempDirName[0] = 0;
+ const char* env;
+
+ if ((env = (const char *) getenv("TMP")) == nsnull) {
+ if ((env = (const char *) getenv("TEMP")) == nsnull) {
+ strcpy(aTempDirName, ".");
+ }
+ }
+ if (*env == '\0') { // null string means "."
+ strcpy(aTempDirName, ".");
+ }
+ if (0 == aTempDirName[0]) {
+ strcpy(aTempDirName, env);
+ }
+ return PR_TRUE;
+}
+
+// the following is a temporary measure until NET_cinfo_find_type or its
+// replacement is available
+void nsForm::Temp_GetContentType(char* aPathName, char* aContentType)
+{
+ if (!aPathName) {
+ strcpy(aContentType, "unknown");
+ return;
+ }
+
+ int len = strlen(aPathName);
+ if (len <= 0) {
+ strcpy(aContentType, "unknown");
+ return;
+ }
+
+ char* fileExt = &aPathName[len-1];
+ for (int i = len-1; i >= 0; i--) {
+ if ('.' == aPathName[i]) {
+ break;
+ }
+ fileExt--;
+ }
+ if ((0 == nsCRT::strcasecmp(fileExt, ".html")) ||
+ (0 == nsCRT::strcasecmp(fileExt, ".htm"))) {
+ strcpy(aContentType, "text/html");
+ }
+ else if (0 == nsCRT::strcasecmp(fileExt, ".txt")) {
+ strcpy(aContentType, "text/plain");
+ }
+ else if (0 == nsCRT::strcasecmp(fileExt, ".gif")) {
+ strcpy(aContentType, "image/gif");
+ }
+ else if ((0 == nsCRT::strcasecmp(fileExt, ".jpeg")) ||
+ (0 == nsCRT::strcasecmp(fileExt, ".jpg"))) {
+ strcpy(aContentType, "image/jpeg");
+ }
+ else { // don't bother trying to do the others here
+ strcpy(aContentType, "unknown");
+ }
+}
+
+
+#if 0
+ char* tmpDir = aFileName; // copy name to fname */
+ // Keep generating file names till we find one that's not in use
+ while ((*env != '\0') && count++ {
+ *ptr++ = *env++;
+ }
+ if (ptr[-1] != '\\' && ptr[-1] != '/')
+ *ptr++ = '\\'; /* append backslash if not in env variable */
+ /* Append a suitable file name */
+ next_file_num++; /* advance counter */
+ sprintf(ptr, "JPG%03d.TMP", next_file_num);
+ /* Probe to see if file name is already in use */
+ if ((tfile = fopen(fname, READ_BINARY)) == NULL)
+ break;
+ fclose(tfile); /* oops, it's there; close tfile & try again */
+ }
+
+ char* tempDir = getenv("temp");
+ if (!tempDir) {
+ tempDir = getenv("tmp");
+ }
+ if (tempDir) {
+ return PR_TRUE;
+ }
+ else {
+ return PR_FALSE;
+ }
+#endif
+
+#define CONTENT_DISP "Content-Disposition: form-data; name=\""
+#define FILENAME "\"; filename=\""
+#define CONTENT_TYPE "Content-Type: "
+#define CONTENT_ENCODING "Content-Encoding: "
+#define BUFSIZE 1024
+#define MULTIPART "multipart/form-data"
+#define END "--"
+
+void nsForm::ProcessAsMultipart(nsIFormControl* aSubmitter, nsString& aData)
+{
+ aData.SetLength(0);
+ char buffer[BUFSIZE];
+ PRInt32 numChildren = mChildren.Count();
+
+ // construct a temporary file to put the data into
+ char tmpFileName[BUFSIZE];
+ char* result = Temp_GenerateTempFileName((PRInt32)BUFSIZE, tmpFileName);
+ if (!result) {
+ return;
+ }
+
+ PRFileDesc* tmpFile = PR_Open(tmpFileName, PR_CREATE_FILE | PR_WRONLY, 0644);
+ if (!tmpFile) {
+ return;
+ }
+
+ // write the content-type, boundary to the tmp file
+ char boundary[80];
+ sprintf(boundary, "-----------------------------%d%d%d",
+ boundary, rand(), rand(), rand());
+ sprintf(buffer, "Content-type: %s; boundary=%s" CRLF, MULTIPART, boundary);
+ PRInt32 len = PR_Write(tmpFile, buffer, PL_strlen(buffer));
+ if (len < 0) {
+ return;
+ }
+
+ PRInt32 boundaryLen = PL_strlen(boundary);
+ PRInt32 contDispLen = PL_strlen(CONTENT_DISP);
+ PRInt32 crlfLen = PL_strlen(CRLF);
+
+ // compute the content length, passing through all of the form controls
+ PRInt32 contentLen = crlfLen; // extra crlf after content-length header
+
+ PRInt32 childX; // stupid compiler
+ for (childX = 0; childX < numChildren; childX++) {
+ nsIFormControl* child = (nsIFormControl*) mChildren.ElementAt(childX);
+ nsAutoString type;
+ child->GetType(type);
+ if (child->IsSuccessful(aSubmitter)) {
+ PRInt32 numValues = 0;
+ PRInt32 maxNumValues = child->GetMaxNumValues();
+ if (maxNumValues <= 0) {
+ continue;
+ }
+ nsString* names = new nsString[maxNumValues];
+ nsString* values = new nsString[maxNumValues];
+ if (PR_FALSE == child->GetNamesValues(maxNumValues, numValues, values, names)) {
+ continue;
+ }
+ contentLen += boundaryLen + crlfLen;
+ contentLen += contDispLen;
+ for (int valueX = 0; valueX < numValues; valueX++) {
+ char* name = names[valueX].ToNewCString();
+ char* value = values[valueX].ToNewCString();
+ if ((0 == names[valueX].Length()) || (0 == values[valueX].Length())) {
+ continue;
+ }
+ contentLen += PL_strlen(name);
+ contentLen += 1 + crlfLen; // ending name quote plus CRLF
+ if (type.EqualsIgnoreCase(*nsInputFile::gFILE_TYPE)) { //
+ contentLen += PL_strlen(FILENAME);
+
+ // include the file name without the directory
+ char* fileNameStart = PL_strrchr(value, '/'); // unix
+ if (!fileNameStart) { // try windows
+ fileNameStart = PL_strrchr(value, '\\');
+ }
+ fileNameStart = (fileNameStart) ? fileNameStart+1 : value;
+ contentLen += PL_strlen(fileNameStart);
+
+ // determine the content-type of the file
+
+ char contentType[128];
+ Temp_GetContentType(value, &contentType[0]);
+ contentLen += PL_strlen(CONTENT_TYPE);
+ contentLen += PL_strlen(contentType) + crlfLen + crlfLen;
+
+ // get the size of the file
+ PRFileInfo fileInfo;
+ if (PR_SUCCESS == PR_GetFileInfo(value, &fileInfo)) {
+ contentLen += fileInfo.size;
+ }
+ }
+ else {
+ contentLen += PL_strlen(value) + crlfLen;
+ }
+ delete [] name;
+ delete [] value;
+ }
+ delete [] names;
+ delete [] values;
+ }
+
+ aData = tmpFileName;
+ }
+
+ contentLen += boundaryLen + PL_strlen(END) + crlfLen;
+
+ // write the content
+ sprintf(buffer, "Content-Length: %ld" CRLF CRLF, contentLen);
+ PR_Write(tmpFile, buffer, PL_strlen(buffer));
+
+ // write the content passing through all of the form controls a 2nd time
+ for (childX = 0; childX < numChildren; childX++) {
+ nsIFormControl* child = (nsIFormControl*) mChildren.ElementAt(childX);
+ nsAutoString type;
+ child->GetType(type);
+ if (child->IsSuccessful(aSubmitter)) {
+ PRInt32 numValues = 0;
+ PRInt32 maxNumValues = child->GetMaxNumValues();
+ if (maxNumValues <= 0) {
+ continue;
+ }
+ nsString* names = new nsString[maxNumValues];
+ nsString* values = new nsString[maxNumValues];
+ if (PR_FALSE == child->GetNamesValues(maxNumValues, numValues, values, names)) {
+ continue;
+ }
+ for (int valueX = 0; valueX < numValues; valueX++) {
+ char* name = names[valueX].ToNewCString();
+ char* value = values[valueX].ToNewCString();
+ if ((0 == names[valueX].Length()) || (0 == values[valueX].Length())) {
+ continue;
+ }
+ sprintf(buffer, "%s" CRLF, boundary);
+ PR_Write(tmpFile, buffer, PL_strlen(buffer));
+ PR_Write(tmpFile, CONTENT_DISP, contDispLen);
+ PR_Write(tmpFile, name, PL_strlen(name));
+
+ if (type.EqualsIgnoreCase(*nsInputFile::gFILE_TYPE)) { //
+ PR_Write(tmpFile, FILENAME, PL_strlen(FILENAME));
+ const char* fileNameStart = GetFileNameWithinPath(value);
+ PR_Write(tmpFile, fileNameStart, PL_strlen(fileNameStart));
+ }
+ PR_Write(tmpFile, "\"" CRLF, PL_strlen("\"" CRLF)); // end content disp
+
+ if (type.EqualsIgnoreCase(*nsInputFile::gFILE_TYPE)) {
+ // determine the content-type of the file
+ char contentType[128];
+ Temp_GetContentType(value, &contentType[0]);
+ PR_Write(tmpFile, CONTENT_TYPE, PL_strlen(CONTENT_TYPE));
+ PR_Write(tmpFile, contentType, PL_strlen(contentType));
+ PR_Write(tmpFile, CRLF, PL_strlen(CRLF));
+ PR_Write(tmpFile, CRLF, PL_strlen(CRLF)); // end content-type header
+
+ PRFileDesc* contentFile = PR_Open(value, PR_RDONLY, 0644);
+ if(contentFile) {
+ PRInt32 size;
+ while((size = PR_Read(contentFile, buffer, BUFSIZE)) > 0) {
+ PR_Write(tmpFile, buffer, size);
+ }
+ PR_Close(contentFile);
+ }
+ }
+ else {
+ PR_Write(tmpFile, value, PL_strlen(value));
+ PR_Write(tmpFile, CRLF, crlfLen);
+ }
+ delete [] name;
+ delete [] value;
+ }
+ delete [] names;
+ delete [] values;
+ }
+ }
+
+ sprintf(buffer, "%s--" CRLF, boundary);
+ PR_Write(tmpFile, buffer, PL_strlen(buffer));
+
+ PR_Close(tmpFile);
+
+ //StrAllocCopy(url_struct->post_data, tmpfilename);
+ //url_struct->post_data_is_file = TRUE;
+}
+
void
nsForm::OnTab()
{
@@ -555,3 +902,159 @@ NS_NewHTMLForm(nsIFormManager** aInstancePtrResult,
return result;
}
+// THE FOLLOWING WAS TAKEN FROM CMD/WINFE/FEGUI AND MODIFIED TO JUST
+// GENERATE A TEMPFILE NAME.
+
+
+// Windows _tempnam() lets the TMP environment variable override things sent in
+// so it look like we're going to have to make a temp name by hand
+//
+// The user should *NOT* free the returned string. It is stored in static space
+// and so is not valid across multiple calls to this function
+//
+// The names generated look like
+// c:\netscape\cache\m0.moz
+// c:\netscape\cache\m1.moz
+// up to...
+// c:\netscape\cache\m9999999.moz
+// after that if fails
+//
+char* nsForm::Temp_GenerateTempFileName(PRInt32 aMaxSize, char* file_buf)
+{
+ char directory[128];
+ Temp_GetTempDir(&directory[0]);
+ static char ext[] = ".TMP";
+ static char prefix[] = "nsform";
+
+ // We need to base our temporary file names on time, and not on sequential
+ // addition because of the cache not being updated when the user
+ // crashes and files that have been deleted are over written with
+ // other files; bad data.
+ // The 52 valid DOS file name characters are
+ // 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_^$~!#%&-{}@`'()
+ // We will only be using the first 32 of the choices.
+ //
+ // Time name format will be M+++++++.MOZ
+ // Where M is the single letter prefix (can be longer....)
+ // Where +++++++ is the 7 character time representation (a full 8.3
+ // file name will be made).
+ // Where .MOZ is the file extension to be used.
+ //
+ // In the event that the time requested is the same time as the last call
+ // to this function, then the current time is incremented by one,
+ // as is the last time called to facilitate unique file names.
+ // In the event that the invented file name already exists (can't
+ // really happen statistically unless the clock is messed up or we
+ // manually incremented the time), then the times are incremented
+ // until an open name can be found.
+ //
+ // time_t (the time) has 32 bits, or 4,294,967,296 combinations.
+ // We will map the 32 bits into the 7 possible characters as follows:
+ // Starting with the lsb, sets of 5 bits (32 values) will be mapped
+ // over to the appropriate file name character, and then
+ // incremented to an approprate file name character.
+ // The left over 2 bits will be mapped into the seventh file name
+ // character.
+ //
+
+ int i_letter, i_timechars, i_numtries = 0;
+ char ca_time[8];
+ time_t this_call = (time_t)0;
+
+ // We have to base the length of our time string on the length
+ // of the incoming prefix....
+ //
+ i_timechars = 8 - strlen(prefix);
+
+ // Infinite loop until the conditions are satisfied.
+ // There is no danger, unless every possible file name is used.
+ //
+ while(1) {
+ // We used to use the time to generate this.
+ // Now, we use some crypto to avoid bug #47027
+ //RNG_GenerateGlobalRandomBytes((void *)&this_call, sizeof(this_call));
+ char* output=(char *)&this_call;
+ size_t len = sizeof(this_call);
+ size_t i;
+ srand((unsigned int) PR_IntervalToMilliseconds(PR_IntervalNow()));
+ for (i=0;i> (i_letter * 5)) & 0x1F);
+
+ // Convert any numbers to their equivalent ascii code
+ //
+ if(ca_time[i_letter] <= 9) {
+ ca_time[i_letter] += '0';
+ }
+ // Convert the character to it's equivalent ascii code
+ //
+ else {
+ ca_time[i_letter] += 'A' - 10;
+ }
+ }
+
+ // End the created time string.
+ //
+ ca_time[i_letter] = '\0';
+
+ // Reverse the time string.
+ //
+ _strrev(ca_time);
+
+ // Create the fully qualified path and file name.
+ //
+ sprintf(file_buf, "%s\\%s%s%s", directory, prefix, ca_time, ext);
+
+ // Determine if the file exists, and mark that we've tried yet
+ // another file name (mark to be used later).
+ //
+ // Use the system call instead of XP_Stat since we already
+ // know the name and we don't want recursion
+ //
+ struct _stat statinfo;
+ int status = _stat(file_buf, &statinfo);
+ i_numtries++;
+
+ // If it does not exists, we are successful, return the name.
+ //
+ if(status == -1) {
+ // TRACE("Temp file name is %s\n", file_buf);
+ return(file_buf);
+ }
+
+ // If there is no room for additional characters in the time,
+ // we'll have to return NULL here, or we go infinite.
+ // This is a one case scenario where the requested prefix is
+ // actually 8 letters long.
+ // Infinite loops could occur with a 7, 6, 5, etc character prefixes
+ // if available files are all eaten up (rare to impossible), in
+ // which case, we should check at some arbitrary frequency of
+ // tries before we give up instead of attempting to Vulcanize
+ // this code. Live long and prosper.
+ //
+ if(i_timechars == 0) {
+ break;
+ }
+ else if(i_numtries == 0x00FF) {
+ break;
+ }
+ }
+
+ // Requested name is thought to be impossible to generate.
+ //
+ //TRACE("No more temp file names....\n");
+ return(NULL);
+
+}
+
+
diff --git a/mozilla/layout/html/forms/src/nsInputButton.cpp b/mozilla/layout/html/forms/src/nsInputButton.cpp
index 83247e469eb..70b4b8f3aea 100644
--- a/mozilla/layout/html/forms/src/nsInputButton.cpp
+++ b/mozilla/layout/html/forms/src/nsInputButton.cpp
@@ -155,7 +155,7 @@ nsInputButton::~nsInputButton()
PRBool nsInputButton::IsSuccessful(nsIFormControl* aSubmitter) const
{
- if ((void*)&mControl == (void*)aSubmitter) {
+ if ((kButton_Hidden == mType) || ((void*)&mControl == (void*)aSubmitter)) {
return nsInputButtonSuper::IsSuccessful(aSubmitter);
}
return PR_FALSE;
@@ -181,6 +181,7 @@ void nsInputButton::GetType(nsString& aResult) const
return;
}
+ // XXX put these and other literals into statics (e.g. gBUTTON_TYPE)
switch (mType) {
case kButton_Button:
aResult.Append("button");
diff --git a/mozilla/layout/html/forms/src/nsInputFile.cpp b/mozilla/layout/html/forms/src/nsInputFile.cpp
index 471d39ee261..55bb6847173 100644
--- a/mozilla/layout/html/forms/src/nsInputFile.cpp
+++ b/mozilla/layout/html/forms/src/nsInputFile.cpp
@@ -37,6 +37,7 @@
#include "nsIView.h"
PRInt32 nsInputFileFrame::gSpacing = 40;
+nsString* nsInputFile::gFILE_TYPE = new nsString("file");
nsInputFileFrame::nsInputFileFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsInlineFrame(aContent, aParentFrame)
@@ -108,7 +109,8 @@ void nsInputFileFrame::MouseClicked(nsIPresContext* aPresContext)
NS_IMETHODIMP
nsInputFileFrame::MoveTo(nscoord aX, nscoord aY)
{
- if ( ((aX == 0) && (aY == 0)) || (aX != mRect.x) || (aY != mRect.y)) {
+ //if ( ((aX == 0) && (aY == 0)) || (aX != mRect.x) || (aY != mRect.y)) {
+ if ((aX != mRect.x) || (aY != mRect.y)) {
nsIFrame* childFrame = mFirstChild;
nscoord x = aX;
nscoord y = aY;
@@ -238,6 +240,31 @@ void nsInputFile::GetType(nsString& aResult) const
}
+PRInt32
+nsInputFile::GetMaxNumValues()
+{
+ return 1;
+}
+
+PRBool
+nsInputFile::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
+ nsString* aValues, nsString* aNames)
+{
+ if ((aMaxNumValues <= 0) || (nsnull == mName)) {
+ return PR_FALSE;
+ }
+ nsInput* text = (nsInput *)ChildAt(0);
+ // use our name and the text widgets value
+ aNames[0] = *mName;
+ nsITextWidget* textWidget = (nsITextWidget *)text->GetWidget();
+ textWidget->GetText(aValues[0], 0); // the last parm is not used
+
+ NS_IF_RELEASE(text);
+ aNumValues = 1;
+
+ return PR_TRUE;
+}
+
void nsInputFile::SetAttribute(nsIAtom* aAttribute, const nsString& aValue)
{
// get the text and set its relevant attributes
diff --git a/mozilla/layout/html/forms/src/nsInputFile.h b/mozilla/layout/html/forms/src/nsInputFile.h
index 51e6a54cae9..157a8ad5f72 100644
--- a/mozilla/layout/html/forms/src/nsInputFile.h
+++ b/mozilla/layout/html/forms/src/nsInputFile.h
@@ -47,6 +47,8 @@ protected:
class nsInputFile : public nsInput {
public:
typedef nsInput nsInputFileSuper;
+ static nsString* gFILE_TYPE;
+
nsInputFile (nsIAtom* aTag, nsIFormManager* aManager);
virtual nsresult CreateFrame(nsIPresContext* aPresContext,
@@ -55,6 +57,9 @@ public:
nsIFrame*& aResult);
virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue);
+ virtual PRInt32 GetMaxNumValues();
+ virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
+ nsString* aValues, nsString* aNames);
protected:
virtual ~nsInputFile();
diff --git a/mozilla/layout/html/forms/src/nsInputFrame.cpp b/mozilla/layout/html/forms/src/nsInputFrame.cpp
index 84a21516e62..eb07edde458 100644
--- a/mozilla/layout/html/forms/src/nsInputFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsInputFrame.cpp
@@ -79,7 +79,8 @@ NS_METHOD nsInputFrame::SetRect(const nsRect& aRect)
NS_METHOD
nsInputFrame::MoveTo(nscoord aX, nscoord aY)
{
- if ( ((aX == 0) && (aY == 0)) || (aX != mRect.x) || (aY != mRect.y)) {
+ //if ( ((aX == 0) && (aY == 0)) || (aX != mRect.x) || (aY != mRect.y)) {
+ if ((aX != mRect.x) || (aY != mRect.y)) {
mRect.x = aX;
mRect.y = aY;
diff --git a/mozilla/layout/html/tests/TestAttributes.cpp b/mozilla/layout/html/tests/TestAttributes.cpp
index 68e36ad453d..d64ea1054f8 100644
--- a/mozilla/layout/html/tests/TestAttributes.cpp
+++ b/mozilla/layout/html/tests/TestAttributes.cpp
@@ -167,7 +167,7 @@ void testStrings(nsIDocument* aDoc) {
class MyDocument : public nsDocument {
public:
MyDocument();
- void LoadURL(nsIURL* aURL);
+ void LoadURL(nsIURL* aURL, nsIPostData* aPostData);
protected:
virtual ~MyDocument();
@@ -181,7 +181,7 @@ MyDocument::~MyDocument()
{
}
-void MyDocument::LoadURL(nsIURL* aURL)
+void MyDocument::LoadURL(nsIURL* aURL, nsIPostData* aPostData)
{
}
diff --git a/mozilla/webshell/public/nsIDocumentWidget.h b/mozilla/webshell/public/nsIDocumentWidget.h
index e581cf903b1..3b94cffce8d 100644
--- a/mozilla/webshell/public/nsIDocumentWidget.h
+++ b/mozilla/webshell/public/nsIDocumentWidget.h
@@ -23,6 +23,7 @@
class nsIDocument;
class nsString;
class nsIScriptContext;
+class nsIPostData;
// Interface to the web widget. The web widget is a container for web
// content.
@@ -40,7 +41,7 @@ public:
virtual void Hide() = 0;
- NS_IMETHOD LoadURL(const nsString& aURLSpec) = 0;
+ NS_IMETHOD LoadURL(const nsString& aURLSpec, nsIPostData* aPostData = 0) = 0;
virtual nsIWidget* GetWWWindow() = 0;
diff --git a/mozilla/webshell/public/nsILinkHandler.h b/mozilla/webshell/public/nsILinkHandler.h
index 9acd5d550c7..c9d5a147de8 100644
--- a/mozilla/webshell/public/nsILinkHandler.h
+++ b/mozilla/webshell/public/nsILinkHandler.h
@@ -22,6 +22,7 @@
#include "nsIWebWidget.h"
class nsIFrame;
class nsString;
+class nsIPostData;
struct nsGUIEvent;
/* 52bd1e30-ce3f-11d1-9328-00805f8add32 */
@@ -52,8 +53,10 @@ public:
* destination for the link. aTargetSpec indicates where the link is
* targeted (it may be an empty string).
*/
- NS_IMETHOD OnLinkClick(nsIFrame* aFrame, const nsString& aURLSpec,
- const nsString& aTargetSpec) = 0;
+ NS_IMETHOD OnLinkClick(nsIFrame* aFrame,
+ const nsString& aURLSpec,
+ const nsString& aTargetSpec,
+ nsIPostData* aPostData = 0) = 0;
/**
* Get the state of a link to a given absolute URL
diff --git a/mozilla/webshell/src/nsLinkHandler.cpp b/mozilla/webshell/src/nsLinkHandler.cpp
index 57eb551cebd..4be36dd32bc 100644
--- a/mozilla/webshell/src/nsLinkHandler.cpp
+++ b/mozilla/webshell/src/nsLinkHandler.cpp
@@ -16,6 +16,7 @@
* Reserved.
*/
#include "nsILinkHandler.h"
+#include "nsIDocument.h"
#include "nsString.h"
#include "nsCRT.h"
#include "prthread.h"
@@ -40,28 +41,33 @@ public:
// nsILinkHandler
NS_IMETHOD Init(nsIWebWidget* aWidget);
NS_IMETHOD GetWebWidget(nsIWebWidget** aResult);
- NS_IMETHOD OnLinkClick(nsIFrame* aFrame, const nsString& aURLSpec,
- const nsString& aTargetSpec);
+ NS_IMETHOD OnLinkClick(nsIFrame* aFrame,
+ const nsString& aURLSpec,
+ const nsString& aTargetSpec,
+ nsIPostData* aPostData = 0);
NS_IMETHOD GetLinkState(const nsString& aURLSpec, nsLinkState& aState);
void HandleLinkClickEvent(const nsString& aURLSpec,
- const nsString& aTargetSpec);
+ const nsString& aTargetSpec,
+ nsIPostData* aPostDat = 0);
nsIWebWidget* mWidget;
+ nsIPostData* mPostData;
};
//----------------------------------------------------------------------
struct OnLinkClickEvent : public PLEvent {
OnLinkClickEvent(LinkHandlerImpl* aHandler, const nsString& aURLSpec,
- const nsString& aTargetSpec);
+ const nsString& aTargetSpec, nsIPostData* aPostData = 0);
~OnLinkClickEvent();
void HandleEvent();
LinkHandlerImpl* mHandler;
- nsString* mURLSpec;
- nsString* mTargetSpec;
+ nsString* mURLSpec;
+ nsString* mTargetSpec;
+ nsIPostData *mPostData;
};
static void PR_CALLBACK HandleEvent(OnLinkClickEvent* aEvent)
@@ -75,13 +81,18 @@ static void PR_CALLBACK DestroyEvent(OnLinkClickEvent* aEvent)
}
OnLinkClickEvent::OnLinkClickEvent(LinkHandlerImpl* aHandler,
- const nsString& aURLSpec,
- const nsString& aTargetSpec)
+ const nsString& aURLSpec,
+ const nsString& aTargetSpec,
+ nsIPostData* aPostData)
{
mHandler = aHandler;
NS_ADDREF(aHandler);
mURLSpec = new nsString(aURLSpec);
mTargetSpec = new nsString(aTargetSpec);
+ mPostData = nsnull;
+ if (aPostData) {
+ NS_NewPostData(aPostData, &mPostData);
+ }
PL_InitEvent(this, nsnull,
(PLHandleEventProc) ::HandleEvent,
@@ -98,11 +109,12 @@ OnLinkClickEvent::~OnLinkClickEvent()
NS_IF_RELEASE(mHandler);
if (nsnull != mURLSpec) delete mURLSpec;
if (nsnull != mTargetSpec) delete mTargetSpec;
+ if (nsnull != mPostData) delete mPostData;
}
void OnLinkClickEvent::HandleEvent()
{
- mHandler->HandleLinkClickEvent(*mURLSpec, *mTargetSpec);
+ mHandler->HandleLinkClickEvent(*mURLSpec, *mTargetSpec, mPostData);
}
//----------------------------------------------------------------------
@@ -147,10 +159,11 @@ NS_IMETHODIMP LinkHandlerImpl::GetWebWidget(nsIWebWidget** aResult)
NS_IMETHODIMP LinkHandlerImpl::OnLinkClick(nsIFrame* aFrame,
const nsString& aURLSpec,
- const nsString& aTargetSpec)
+ const nsString& aTargetSpec,
+ nsIPostData* aPostData)
{
- new OnLinkClickEvent(this, aURLSpec, aTargetSpec);
+ new OnLinkClickEvent(this, aURLSpec, aTargetSpec, aPostData);
return NS_OK;
}
@@ -177,10 +190,10 @@ NS_IMETHODIMP LinkHandlerImpl::GetLinkState(const nsString& aURLSpec, nsLinkStat
}
void LinkHandlerImpl::HandleLinkClickEvent(const nsString& aURLSpec,
- const nsString& aTargetSpec)
+ const nsString& aTargetSpec, nsIPostData* aPostData)
{
if (nsnull != mWidget) {
- mWidget->LoadURL(aURLSpec);
+ mWidget->LoadURL(aURLSpec, aPostData);
}
}
diff --git a/mozilla/webshell/src/nsWebWidget.cpp b/mozilla/webshell/src/nsWebWidget.cpp
index 31535231116..aa9e23b99e1 100644
--- a/mozilla/webshell/src/nsWebWidget.cpp
+++ b/mozilla/webshell/src/nsWebWidget.cpp
@@ -81,8 +81,7 @@ public:
NS_IMETHOD GetLinkHandler(nsILinkHandler** aResult);
- NS_IMETHOD LoadURL(const nsString& aURL);
-
+ NS_IMETHOD LoadURL(const nsString& aURL, nsIPostData* aPostData);
virtual nsIDocument* GetDocument();
virtual void DumpContent(FILE* out);
@@ -382,7 +381,7 @@ nsresult WebWidgetImpl::ProvideDefaultHandlers()
// XXX need to save old document in case of failure? Does caller do that?
-NS_IMETHODIMP WebWidgetImpl::LoadURL(const nsString& aURLSpec)
+NS_IMETHODIMP WebWidgetImpl::LoadURL(const nsString& aURLSpec, nsIPostData* aPostData)
{
#ifdef NS_DEBUG
printf("WebWidgetImpl::LoadURL: loadURL(");
@@ -447,7 +446,7 @@ NS_IMETHODIMP WebWidgetImpl::LoadURL(const nsString& aURLSpec)
// Now load the document
mPresShell->EnterReflowLock();
- doc->LoadURL(url);
+ doc->LoadURL(url, aPostData);
mPresShell->ExitReflowLock();
PRTime end = PR_Now();
diff --git a/mozilla/webshell/tests/viewer/samples/test8.html b/mozilla/webshell/tests/viewer/samples/test8.html
index 29fac8d5a2b..2dc0669feac 100644
--- a/mozilla/webshell/tests/viewer/samples/test8.html
+++ b/mozilla/webshell/tests/viewer/samples/test8.html
@@ -65,11 +65,6 @@ a checkbox:
an image submit. For now, click twice.
-
-
-