Bug 1450989 - Capture the action and target as part of the form submission creation; r=bz

This commit is contained in:
Edgar Chen 2018-07-22 11:11:27 +02:00
Родитель b9c1a2f365
Коммит 106676d84e
5 изменённых файлов: 91 добавлений и 56 удалений

Просмотреть файл

@ -17,7 +17,7 @@ using namespace mozilla;
using namespace mozilla::dom;
FormData::FormData(nsISupports* aOwner)
: HTMLFormSubmission(UTF_8_ENCODING, nullptr)
: HTMLFormSubmission(nullptr, EmptyString(), UTF_8_ENCODING, nullptr)
, mOwner(aOwner)
{
}
@ -350,7 +350,7 @@ nsresult
FormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
nsACString& aContentTypeWithCharset, nsACString& aCharset) const
{
FSMultipartFormData fs(UTF_8_ENCODING, nullptr);
FSMultipartFormData fs(nullptr, EmptyString(), UTF_8_ENCODING, nullptr);
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
if (mFormData[i].wasNullBlob) {

Просмотреть файл

@ -178,13 +178,6 @@ HTMLFormElement::BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
{
if (aNamespaceID == kNameSpaceID_None) {
if (aName == nsGkAtoms::action || aName == nsGkAtoms::target) {
if (mPendingSubmission) {
// aha, there is a pending submission that means we're in
// the script and we need to flush it. let's tell it
// that the event was ignored to force the flush.
// the second argument is not playing a role at all.
FlushPendingSubmission();
}
// Don't forget we've notified the password manager already if the
// page sets the action/target in the during submit. (bug 343182)
bool notifiedObservers = mNotifiedObservers;
@ -680,15 +673,8 @@ nsresult
HTMLFormElement::SubmitSubmission(HTMLFormSubmission* aFormSubmission)
{
nsresult rv;
Element* originatingElement = aFormSubmission->GetOriginatingElement();
//
// Get the action and target
//
nsCOMPtr<nsIURI> actionURI;
rv = GetActionURL(getter_AddRefs(actionURI), originatingElement);
NS_ENSURE_SUBMIT_SUCCESS(rv);
nsCOMPtr<nsIURI> actionURI = aFormSubmission->GetActionURL();
if (!actionURI) {
mIsSubmitting = false;
return NS_OK;
@ -720,21 +706,6 @@ HTMLFormElement::SubmitSubmission(HTMLFormSubmission* aFormSubmission)
mIsSubmitting = false;
}
// The target is the originating element formtarget attribute if the element
// is a submit control and has such an attribute.
// Otherwise, the target is the form owner's target attribute,
// if it has such an attribute.
// Finally, if one of the child nodes of the head element is a base element
// with a target attribute, then the value of the target attribute of the
// first such base element; or, if there is no such element, the empty string.
nsAutoString target;
if (!(originatingElement && originatingElement->GetAttr(kNameSpaceID_None,
nsGkAtoms::formtarget,
target)) &&
!GetAttr(kNameSpaceID_None, nsGkAtoms::target, target)) {
GetBaseTarget(target);
}
//
// Notify observers of submit
//
@ -778,6 +749,8 @@ HTMLFormElement::SubmitSubmission(HTMLFormSubmission* aFormSubmission)
actionURI);
NS_ENSURE_SUBMIT_SUCCESS(rv);
nsAutoString target;
aFormSubmission->GetTarget(target);
rv = linkHandler->OnLinkClickSync(this, actionURI,
target.get(),
VoidString(),

Просмотреть файл

@ -510,14 +510,6 @@ protected:
*/
already_AddRefed<nsISupports> DoResolveName(const nsAString& aName, bool aFlushContent);
/**
* Get the full URL to submit to. Do not submit if the returned URL is null.
*
* @param aActionURL the full, unadulterated URL you'll be submitting to [OUT]
* @param aOriginatingElement the originating element of the form submission [IN]
*/
nsresult GetActionURL(nsIURI** aActionURL, Element* aOriginatingElement);
/**
* Check the form validity following this algorithm:
* http://www.whatwg.org/specs/web-apps/current-work/#statically-validate-the-constraints
@ -557,6 +549,14 @@ public:
* returns false or there is an action/target change in the script)
*/
void FlushPendingSubmission();
/**
* Get the full URL to submit to. Do not submit if the returned URL is null.
*
* @param aActionURL the full, unadulterated URL you'll be submitting to [OUT]
* @param aOriginatingElement the originating element of the form submission [IN]
*/
nsresult GetActionURL(nsIURI** aActionURL, Element* aOriginatingElement);
protected:
//

Просмотреть файл

@ -92,11 +92,13 @@ public:
* @param aMethod the method of the submit (either NS_FORM_METHOD_GET or
* NS_FORM_METHOD_POST).
*/
FSURLEncoded(NotNull<const Encoding*> aEncoding,
FSURLEncoded(nsIURI* aActionURL,
const nsAString& aTarget,
NotNull<const Encoding*> aEncoding,
int32_t aMethod,
nsIDocument* aDocument,
Element* aOriginatingElement)
: EncodingFormSubmission(aEncoding, aOriginatingElement)
: EncodingFormSubmission(aActionURL, aTarget, aEncoding, aOriginatingElement)
, mMethod(aMethod)
, mDocument(aDocument)
, mWarnedFileControl(false)
@ -395,9 +397,11 @@ FSURLEncoded::URLEncode(const nsAString& aStr, nsACString& aEncoded)
// --------------------------------------------------------------------------
FSMultipartFormData::FSMultipartFormData(NotNull<const Encoding*> aEncoding,
FSMultipartFormData::FSMultipartFormData(nsIURI* aActionURL,
const nsAString& aTarget,
NotNull<const Encoding*> aEncoding,
Element* aOriginatingElement)
: EncodingFormSubmission(aEncoding, aOriginatingElement)
: EncodingFormSubmission(aActionURL, aTarget, aEncoding, aOriginatingElement)
{
mPostData =
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
@ -669,9 +673,11 @@ namespace {
class FSTextPlain : public EncodingFormSubmission
{
public:
FSTextPlain(NotNull<const Encoding*> aEncoding,
FSTextPlain(nsIURI* aActionURL,
const nsAString& aTarget,
NotNull<const Encoding*> aEncoding,
Element* aOriginatingElement)
: EncodingFormSubmission(aEncoding, aOriginatingElement)
: EncodingFormSubmission(aActionURL, aTarget, aEncoding, aOriginatingElement)
{
}
@ -794,9 +800,11 @@ FSTextPlain::GetEncodedSubmission(nsIURI* aURI,
// --------------------------------------------------------------------------
EncodingFormSubmission::EncodingFormSubmission(
nsIURI* aActionURL,
const nsAString& aTarget,
NotNull<const Encoding*> aEncoding,
Element* aOriginatingElement)
: HTMLFormSubmission(aEncoding, aOriginatingElement)
: HTMLFormSubmission(aActionURL, aTarget, aEncoding, aOriginatingElement)
{
if (!aEncoding->CanEncodeEverything()) {
nsAutoCString name;
@ -893,7 +901,7 @@ GetEnumAttr(nsGenericHTMLElement* aContent,
} // anonymous namespace
/* static */ nsresult
HTMLFormSubmission::GetFromForm(nsGenericHTMLElement* aForm,
HTMLFormSubmission::GetFromForm(HTMLFormElement* aForm,
nsGenericHTMLElement* aOriginatingElement,
HTMLFormSubmission** aFormSubmission)
{
@ -901,6 +909,29 @@ HTMLFormSubmission::GetFromForm(nsGenericHTMLElement* aForm,
NS_ASSERTION(aForm->GetComposedDoc(),
"Should have doc if we're building submission!");
nsresult rv;
// Get action
nsCOMPtr<nsIURI> actionURL;
rv = aForm->GetActionURL(getter_AddRefs(actionURL), aOriginatingElement);
NS_ENSURE_SUCCESS(rv, rv);
// Get target
// The target is the originating element formtarget attribute if the element
// is a submit control and has such an attribute.
// Otherwise, the target is the form owner's target attribute,
// if it has such an attribute.
// Finally, if one of the child nodes of the head element is a base element
// with a target attribute, then the value of the target attribute of the
// first such base element; or, if there is no such element, the empty string.
nsAutoString target;
if (!(aOriginatingElement && aOriginatingElement->GetAttr(kNameSpaceID_None,
nsGkAtoms::formtarget,
target)) &&
!aForm->GetAttr(kNameSpaceID_None, nsGkAtoms::target, target)) {
aForm->GetBaseTarget(target);
}
// Get encoding type (default: urlencoded)
int32_t enctype = NS_FORM_ENCTYPE_URLENCODED;
if (aOriginatingElement &&
@ -925,10 +956,10 @@ HTMLFormSubmission::GetFromForm(nsGenericHTMLElement* aForm,
// Choose encoder
if (method == NS_FORM_METHOD_POST &&
enctype == NS_FORM_ENCTYPE_MULTIPART) {
*aFormSubmission = new FSMultipartFormData(encoding, aOriginatingElement);
*aFormSubmission = new FSMultipartFormData(actionURL, target, encoding, aOriginatingElement);
} else if (method == NS_FORM_METHOD_POST &&
enctype == NS_FORM_ENCTYPE_TEXTPLAIN) {
*aFormSubmission = new FSTextPlain(encoding, aOriginatingElement);
*aFormSubmission = new FSTextPlain(actionURL, target, encoding, aOriginatingElement);
} else {
nsIDocument* doc = aForm->OwnerDoc();
if (enctype == NS_FORM_ENCTYPE_MULTIPART ||
@ -947,7 +978,7 @@ HTMLFormSubmission::GetFromForm(nsGenericHTMLElement* aForm,
&enctypeStrPtr, 1);
}
*aFormSubmission =
new FSURLEncoded(encoding, method, doc, aOriginatingElement);
new FSURLEncoded(actionURL, target, encoding, method, doc, aOriginatingElement);
}
return NS_OK;

Просмотреть файл

@ -23,6 +23,7 @@ namespace dom {
class Blob;
class Directory;
class HTMLFormElement;
/**
* Class for form submissions; encompasses the function to call to submit as
@ -40,7 +41,7 @@ public:
* @param aFormSubmission the form submission object (out param)
*/
static nsresult
GetFromForm(nsGenericHTMLElement* aForm,
GetFromForm(HTMLFormElement* aForm,
nsGenericHTMLElement* aOriginatingElement,
HTMLFormSubmission** aFormSubmission);
@ -100,6 +101,22 @@ public:
return mOriginatingElement.get();
}
/**
* Get the action URI that will be used for submission.
*/
nsIURI* GetActionURL() const
{
return mActionURL;
}
/**
* Get the target that will be used for submission.
*/
void GetTarget(nsAString& aTarget)
{
aTarget = mTarget;
}
protected:
/**
* Can only be constructed by subclasses.
@ -107,14 +124,24 @@ protected:
* @param aEncoding the character encoding of the form
* @param aOriginatingElement the originating element (can be null)
*/
HTMLFormSubmission(mozilla::NotNull<const mozilla::Encoding*> aEncoding,
HTMLFormSubmission(nsIURI* aActionURL,
const nsAString& aTarget,
mozilla::NotNull<const mozilla::Encoding*> aEncoding,
Element* aOriginatingElement)
: mEncoding(aEncoding)
: mActionURL(aActionURL)
, mTarget(aTarget)
, mEncoding(aEncoding)
, mOriginatingElement(aOriginatingElement)
{
MOZ_COUNT_CTOR(HTMLFormSubmission);
}
// The action url.
nsCOMPtr<nsIURI> mActionURL;
// The target.
nsString mTarget;
// The character encoding of this form submission
mozilla::NotNull<const mozilla::Encoding*> mEncoding;
@ -125,7 +152,9 @@ protected:
class EncodingFormSubmission : public HTMLFormSubmission
{
public:
EncodingFormSubmission(mozilla::NotNull<const mozilla::Encoding*> aEncoding,
EncodingFormSubmission(nsIURI* aActionURL,
const nsAString& aTarget,
mozilla::NotNull<const mozilla::Encoding*> aEncoding,
Element* aOriginatingElement);
virtual ~EncodingFormSubmission();
@ -153,7 +182,9 @@ public:
/**
* @param aEncoding the character encoding of the form
*/
FSMultipartFormData(mozilla::NotNull<const mozilla::Encoding*> aEncoding,
FSMultipartFormData(nsIURI* aActionURL,
const nsAString& aTarget,
mozilla::NotNull<const mozilla::Encoding*> aEncoding,
Element* aOriginatingElement);
~FSMultipartFormData();