Backed out 2 changesets (bug 1553705) for causing Bug1562142 . CLOSED TREE
Backed out changeset fbb26a04ec1f (bug 1553705) Backed out changeset dd6e7c0970d5 (bug 1553705)
This commit is contained in:
@@ -38,7 +38,6 @@
|
|||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
|
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/dom/HTMLFormElement.h"
|
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIForm.h"
|
#include "nsIForm.h"
|
||||||
#include "nsIFormControl.h"
|
#include "nsIFormControl.h"
|
||||||
@@ -1731,7 +1730,8 @@ Relation Accessible::RelationByType(RelationType aType) const {
|
|||||||
// HTML form controls implements nsIFormControl interface.
|
// HTML form controls implements nsIFormControl interface.
|
||||||
nsCOMPtr<nsIFormControl> control(do_QueryInterface(mContent));
|
nsCOMPtr<nsIFormControl> control(do_QueryInterface(mContent));
|
||||||
if (control) {
|
if (control) {
|
||||||
if (dom::HTMLFormElement* form = control->GetFormElement()) {
|
nsCOMPtr<nsIForm> form(do_QueryInterface(control->GetFormElement()));
|
||||||
|
if (form) {
|
||||||
nsCOMPtr<nsIContent> formContent =
|
nsCOMPtr<nsIContent> formContent =
|
||||||
do_QueryInterface(form->GetDefaultSubmitElement());
|
do_QueryInterface(form->GetDefaultSubmitElement());
|
||||||
return Relation(mDoc, formContent);
|
return Relation(mDoc, formContent);
|
||||||
|
|||||||
@@ -1338,9 +1338,7 @@ Document::Document(const char* aContentType)
|
|||||||
mPendingInitialTranslation(false),
|
mPendingInitialTranslation(false),
|
||||||
mGeneration(0),
|
mGeneration(0),
|
||||||
mCachedTabSizeGeneration(0),
|
mCachedTabSizeGeneration(0),
|
||||||
mInRDMPane(false),
|
mInRDMPane(false) {
|
||||||
mNextFormNumber(0),
|
|
||||||
mNextControlNumber(0) {
|
|
||||||
MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p created", this));
|
MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p created", this));
|
||||||
|
|
||||||
SetIsInDocument();
|
SetIsInDocument();
|
||||||
|
|||||||
@@ -1697,18 +1697,6 @@ class Document : public nsINode,
|
|||||||
|
|
||||||
void SetKeyPressEventModel(uint16_t aKeyPressEventModel);
|
void SetKeyPressEventModel(uint16_t aKeyPressEventModel);
|
||||||
|
|
||||||
// Gets the next form number.
|
|
||||||
//
|
|
||||||
// Used by nsContentUtils::GenerateStateKey to get a unique number for each
|
|
||||||
// parser inserted form element.
|
|
||||||
int32_t GetNextFormNumber() { return mNextFormNumber++; }
|
|
||||||
|
|
||||||
// Gets the next form control number.
|
|
||||||
//
|
|
||||||
// Used by nsContentUtils::GenerateStateKey to get a unique number for each
|
|
||||||
// parser inserted form control element.
|
|
||||||
int32_t GetNextControlNumber() { return mNextControlNumber++; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class nsUnblockOnloadEvent;
|
friend class nsUnblockOnloadEvent;
|
||||||
|
|
||||||
@@ -5209,10 +5197,6 @@ class Document : public nsINode,
|
|||||||
// The principal to use for the storage area of this document.
|
// The principal to use for the storage area of this document.
|
||||||
nsCOMPtr<nsIPrincipal> mIntrinsicStoragePrincipal;
|
nsCOMPtr<nsIPrincipal> mIntrinsicStoragePrincipal;
|
||||||
|
|
||||||
// See GetNextFormNumber and GetNextControlNumber.
|
|
||||||
int32_t mNextFormNumber;
|
|
||||||
int32_t mNextControlNumber;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Needs to be public because the bindings code pokes at it.
|
// Needs to be public because the bindings code pokes at it.
|
||||||
js::ExpandoAndGeneration mExpandoAndGeneration;
|
js::ExpandoAndGeneration mExpandoAndGeneration;
|
||||||
|
|||||||
@@ -2668,21 +2668,23 @@ static inline bool IsAutocompleteOff(const nsIContent* aContent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
void nsContentUtils::GenerateStateKey(nsIContent* aContent, Document* aDocument,
|
nsresult nsContentUtils::GenerateStateKey(nsIContent* aContent,
|
||||||
nsACString& aKey) {
|
Document* aDocument,
|
||||||
MOZ_ASSERT(aContent);
|
nsACString& aKey) {
|
||||||
|
|
||||||
aKey.Truncate();
|
aKey.Truncate();
|
||||||
|
|
||||||
uint32_t partID = aDocument ? aDocument->GetPartID() : 0;
|
uint32_t partID = aDocument ? aDocument->GetPartID() : 0;
|
||||||
|
|
||||||
|
// We must have content if we're not using a special state id
|
||||||
|
NS_ENSURE_TRUE(aContent, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
// Don't capture state for anonymous content
|
// Don't capture state for anonymous content
|
||||||
if (aContent->IsInAnonymousSubtree()) {
|
if (aContent->IsInAnonymousSubtree()) {
|
||||||
return;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsAutocompleteOff(aContent)) {
|
if (IsAutocompleteOff(aContent)) {
|
||||||
return;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Document> doc = aContent->GetUncomposedDoc();
|
RefPtr<Document> doc = aContent->GetUncomposedDoc();
|
||||||
@@ -2692,6 +2694,10 @@ void nsContentUtils::GenerateStateKey(nsIContent* aContent, Document* aDocument,
|
|||||||
|
|
||||||
if (doc && doc->IsHTMLOrXHTML()) {
|
if (doc && doc->IsHTMLOrXHTML()) {
|
||||||
nsHTMLDocument* htmlDoc = doc->AsHTMLDocument();
|
nsHTMLDocument* htmlDoc = doc->AsHTMLDocument();
|
||||||
|
RefPtr<nsContentList> htmlForms;
|
||||||
|
RefPtr<nsContentList> htmlFormControls;
|
||||||
|
htmlDoc->GetFormsAndFormControls(getter_AddRefs(htmlForms),
|
||||||
|
getter_AddRefs(htmlFormControls));
|
||||||
|
|
||||||
// If we have a form control and can calculate form information, use that
|
// If we have a form control and can calculate form information, use that
|
||||||
// as the key - it is more reliable than just recording position in the
|
// as the key - it is more reliable than just recording position in the
|
||||||
@@ -2699,84 +2705,47 @@ void nsContentUtils::GenerateStateKey(nsIContent* aContent, Document* aDocument,
|
|||||||
// XXXbz Is it, really? We have bugs on this, I think...
|
// XXXbz Is it, really? We have bugs on this, I think...
|
||||||
// Important to have a unique key, and tag/type/name may not be.
|
// Important to have a unique key, and tag/type/name may not be.
|
||||||
//
|
//
|
||||||
// The format of the key depends on whether the control has a form,
|
// If the control has a form, the format of the key is:
|
||||||
// and whether the element was parser inserted:
|
// f>type>IndOfFormInDoc>IndOfControlInForm>FormName>name
|
||||||
//
|
// else:
|
||||||
// [Has Form, Parser Inserted]:
|
// d>type>IndOfControlInDoc>name
|
||||||
// fp>type>FormNum>IndOfControlInForm>FormName>name
|
|
||||||
//
|
|
||||||
// [No Form, Parser Inserted]:
|
|
||||||
// dp>type>ControlNum>name
|
|
||||||
//
|
|
||||||
// [Has Form, Not Parser Inserted]:
|
|
||||||
// fn>type>IndOfFormInDoc>IndOfControlInForm>FormName>name
|
|
||||||
//
|
|
||||||
// [No Form, Not Parser Inserted]:
|
|
||||||
// dn>type>IndOfControlInDoc>name
|
|
||||||
//
|
//
|
||||||
// XXX We don't need to use index if name is there
|
// XXX We don't need to use index if name is there
|
||||||
// XXXbz We don't? Why not? I don't follow.
|
// XXXbz We don't? Why not? I don't follow.
|
||||||
//
|
//
|
||||||
nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
|
nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
|
||||||
if (control) {
|
if (control) {
|
||||||
// Get the control number if this was a parser inserted element from the
|
|
||||||
// network.
|
|
||||||
int32_t controlNumber =
|
|
||||||
control->GetParserInsertedControlNumberForStateKey();
|
|
||||||
bool parserInserted = controlNumber != -1;
|
|
||||||
|
|
||||||
RefPtr<nsContentList> htmlForms;
|
|
||||||
RefPtr<nsContentList> htmlFormControls;
|
|
||||||
if (!parserInserted) {
|
|
||||||
// Getting these lists is expensive, as we need to keep them up to date
|
|
||||||
// as the document loads, so we avoid it if we don't need them.
|
|
||||||
htmlDoc->GetFormsAndFormControls(getter_AddRefs(htmlForms),
|
|
||||||
getter_AddRefs(htmlFormControls));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the control type
|
// Append the control type
|
||||||
KeyAppendInt(control->ControlType(), aKey);
|
KeyAppendInt(control->ControlType(), aKey);
|
||||||
|
|
||||||
// If in a form, add form name / index of form / index in form
|
// If in a form, add form name / index of form / index in form
|
||||||
HTMLFormElement* formElement = control->GetFormElement();
|
Element* formElement = control->GetFormElement();
|
||||||
if (formElement) {
|
if (formElement) {
|
||||||
if (IsAutocompleteOff(formElement)) {
|
if (IsAutocompleteOff(formElement)) {
|
||||||
aKey.Truncate();
|
aKey.Truncate();
|
||||||
return;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the form number, if this is a parser inserted control, or
|
KeyAppendString(NS_LITERAL_CSTRING("f"), aKey);
|
||||||
// the index of the form in the document otherwise.
|
|
||||||
bool appendedForm = false;
|
// Append the index of the form in the document
|
||||||
if (parserInserted) {
|
int32_t index = htmlForms->IndexOf(formElement, false);
|
||||||
MOZ_ASSERT(formElement->GetFormNumberForStateKey() != -1,
|
if (index <= -1) {
|
||||||
"when generating a state key for a parser inserted form "
|
//
|
||||||
"control we should have a parser inserted <form> element");
|
// XXX HACK this uses some state that was dumped into the document
|
||||||
KeyAppendString(NS_LITERAL_CSTRING("fp"), aKey);
|
// specifically to fix bug 138892. What we are trying to do is
|
||||||
KeyAppendInt(formElement->GetFormNumberForStateKey(), aKey);
|
// *guess* which form this control's state is found in, with the
|
||||||
appendedForm = true;
|
// highly likely guess that the highest form parsed so far is the one.
|
||||||
} else {
|
// This code should not be on trunk, only branch.
|
||||||
KeyAppendString(NS_LITERAL_CSTRING("fn"), aKey);
|
//
|
||||||
int32_t index = htmlForms->IndexOf(formElement, false);
|
index = htmlDoc->GetNumFormsSynchronous() - 1;
|
||||||
if (index <= -1) {
|
}
|
||||||
//
|
if (index > -1) {
|
||||||
// XXX HACK this uses some state that was dumped into the document
|
KeyAppendInt(index, aKey);
|
||||||
// specifically to fix bug 138892. What we are trying to do is
|
|
||||||
// *guess* which form this control's state is found in, with the
|
|
||||||
// highly likely guess that the highest form parsed so far is the
|
|
||||||
// one. This code should not be on trunk, only branch.
|
|
||||||
//
|
|
||||||
index = htmlDoc->GetNumFormsSynchronous() - 1;
|
|
||||||
}
|
|
||||||
if (index > -1) {
|
|
||||||
KeyAppendInt(index, aKey);
|
|
||||||
appendedForm = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appendedForm) {
|
|
||||||
// Append the index of the control in the form
|
// Append the index of the control in the form
|
||||||
int32_t index = formElement->IndexOfControl(control);
|
nsCOMPtr<nsIForm> form(do_QueryInterface(formElement));
|
||||||
|
index = form->IndexOfControl(control);
|
||||||
|
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
KeyAppendInt(index, aKey);
|
KeyAppendInt(index, aKey);
|
||||||
@@ -2788,30 +2757,29 @@ void nsContentUtils::GenerateStateKey(nsIContent* aContent, Document* aDocument,
|
|||||||
nsAutoString formName;
|
nsAutoString formName;
|
||||||
formElement->GetAttr(kNameSpaceID_None, nsGkAtoms::name, formName);
|
formElement->GetAttr(kNameSpaceID_None, nsGkAtoms::name, formName);
|
||||||
KeyAppendString(formName, aKey);
|
KeyAppendString(formName, aKey);
|
||||||
} else {
|
|
||||||
// Not in a form. Append the control number, if this is a parser
|
|
||||||
// inserted control, or the index of the control in the document
|
|
||||||
// otherwise.
|
|
||||||
if (parserInserted) {
|
|
||||||
KeyAppendString(NS_LITERAL_CSTRING("dp"), aKey);
|
|
||||||
KeyAppendInt(control->GetParserInsertedControlNumberForStateKey(),
|
|
||||||
aKey);
|
|
||||||
generatedUniqueKey = true;
|
|
||||||
} else {
|
|
||||||
KeyAppendString(NS_LITERAL_CSTRING("dn"), aKey);
|
|
||||||
int32_t index = htmlFormControls->IndexOf(aContent, true);
|
|
||||||
if (index > -1) {
|
|
||||||
KeyAppendInt(index, aKey);
|
|
||||||
generatedUniqueKey = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the control name
|
} else {
|
||||||
nsAutoString name;
|
KeyAppendString(NS_LITERAL_CSTRING("d"), aKey);
|
||||||
aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::name,
|
|
||||||
name);
|
// If not in a form, add index of control in document
|
||||||
KeyAppendString(name, aKey);
|
// Less desirable than indexing by form info.
|
||||||
|
|
||||||
|
// Hash by index of control in doc (we are not in a form)
|
||||||
|
// These are important as they are unique, and type/name may not be.
|
||||||
|
|
||||||
|
// We have to flush sink notifications at this point to make
|
||||||
|
// sure that htmlFormControls is up to date.
|
||||||
|
int32_t index = htmlFormControls->IndexOf(aContent, true);
|
||||||
|
if (index > -1) {
|
||||||
|
KeyAppendInt(index, aKey);
|
||||||
|
generatedUniqueKey = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Append the control name
|
||||||
|
nsAutoString name;
|
||||||
|
aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
|
||||||
|
KeyAppendString(name, aKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2839,6 +2807,8 @@ void nsContentUtils::GenerateStateKey(nsIContent* aContent, Document* aDocument,
|
|||||||
parent = content->GetParentNode();
|
parent = content->GetParentNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|||||||
@@ -723,8 +723,8 @@ class nsContentUtils {
|
|||||||
// with a single realm.
|
// with a single realm.
|
||||||
static nsIPrincipal* ObjectPrincipal(JSObject* aObj);
|
static nsIPrincipal* ObjectPrincipal(JSObject* aObj);
|
||||||
|
|
||||||
static void GenerateStateKey(nsIContent* aContent, Document* aDocument,
|
static nsresult GenerateStateKey(nsIContent* aContent, Document* aDocument,
|
||||||
nsACString& aKey);
|
nsACString& aKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new nsIURI from aSpec, using aBaseURI as the base. The
|
* Create a new nsIURI from aSpec, using aBaseURI as the base. The
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ static const nsAttrValue::EnumTable* kButtonDefaultType = &kButtonTypeTable[2];
|
|||||||
HTMLButtonElement::HTMLButtonElement(
|
HTMLButtonElement::HTMLButtonElement(
|
||||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
||||||
FromParser aFromParser)
|
FromParser aFromParser)
|
||||||
: nsGenericHTMLFormElementWithState(std::move(aNodeInfo), aFromParser,
|
: nsGenericHTMLFormElementWithState(std::move(aNodeInfo),
|
||||||
kButtonDefaultType->value),
|
kButtonDefaultType->value),
|
||||||
mDisabledChanged(false),
|
mDisabledChanged(false),
|
||||||
mInInternalActivate(false),
|
mInInternalActivate(false),
|
||||||
@@ -345,9 +345,11 @@ HTMLButtonElement::SubmitNamesValues(HTMLFormSubmission* aFormSubmission) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HTMLButtonElement::DoneCreatingElement() {
|
void HTMLButtonElement::DoneCreatingElement() {
|
||||||
GenerateStateKey();
|
|
||||||
if (!mInhibitStateRestoration) {
|
if (!mInhibitStateRestoration) {
|
||||||
RestoreFormControlState();
|
nsresult rv = GenerateStateKey();
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
RestoreFormControlState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ HTMLFormElement::HTMLFormElement(
|
|||||||
mPastNameLookupTable(FORM_CONTROL_LIST_HASHTABLE_LENGTH),
|
mPastNameLookupTable(FORM_CONTROL_LIST_HASHTABLE_LENGTH),
|
||||||
mSubmitPopupState(PopupBlocker::openAbused),
|
mSubmitPopupState(PopupBlocker::openAbused),
|
||||||
mInvalidElementsCount(0),
|
mInvalidElementsCount(0),
|
||||||
mFormNumber(-1),
|
|
||||||
mGeneratingSubmit(false),
|
mGeneratingSubmit(false),
|
||||||
mGeneratingReset(false),
|
mGeneratingReset(false),
|
||||||
mIsSubmitting(false),
|
mIsSubmitting(false),
|
||||||
@@ -2313,26 +2312,5 @@ JSObject* HTMLFormElement::WrapNode(JSContext* aCx,
|
|||||||
return HTMLFormElement_Binding::Wrap(aCx, this, aGivenProto);
|
return HTMLFormElement_Binding::Wrap(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t HTMLFormElement::GetFormNumberForStateKey() {
|
|
||||||
if (mFormNumber == -1) {
|
|
||||||
mFormNumber = OwnerDoc()->GetNextFormNumber();
|
|
||||||
}
|
|
||||||
return mFormNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HTMLFormElement::NodeInfoChanged(Document* aOldDoc) {
|
|
||||||
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
|
|
||||||
|
|
||||||
// When a <form> element is adopted into a new document, we want any state
|
|
||||||
// keys generated from it to no longer consider this element to be parser
|
|
||||||
// inserted, and so have state keys based on the position of the <form>
|
|
||||||
// element in the document, rather than the order it was inserted in.
|
|
||||||
//
|
|
||||||
// This is not strictly necessary, since we only ever look at the form number
|
|
||||||
// for parser inserted form controls, and we do that at the time the form
|
|
||||||
// control element is inserted into its original document by the parser.
|
|
||||||
mFormNumber = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -520,17 +520,6 @@ class HTMLFormElement final : public nsGenericHTMLElement,
|
|||||||
*/
|
*/
|
||||||
nsresult GetActionURL(nsIURI** aActionURL, Element* aOriginatingElement);
|
nsresult GetActionURL(nsIURI** aActionURL, Element* aOriginatingElement);
|
||||||
|
|
||||||
// Returns a number for this form that is unique within its owner document.
|
|
||||||
// This is used by nsContentUtils::GenerateStateKey to identify form controls
|
|
||||||
// that are inserted into the document by the parser.
|
|
||||||
int32_t GetFormNumberForStateKey();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when we have been cloned and adopted, and the information of the
|
|
||||||
* node has been changed.
|
|
||||||
*/
|
|
||||||
void NodeInfoChanged(Document* aOldDoc) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//
|
//
|
||||||
// Data members
|
// Data members
|
||||||
@@ -591,9 +580,6 @@ class HTMLFormElement final : public nsGenericHTMLElement,
|
|||||||
*/
|
*/
|
||||||
int32_t mInvalidElementsCount;
|
int32_t mInvalidElementsCount;
|
||||||
|
|
||||||
// See GetFormNumberForStateKey.
|
|
||||||
int32_t mFormNumber;
|
|
||||||
|
|
||||||
/** Whether we are currently processing a submit event or not */
|
/** Whether we are currently processing a submit event or not */
|
||||||
bool mGeneratingSubmit;
|
bool mGeneratingSubmit;
|
||||||
/** Whether we are currently processing a reset event or not */
|
/** Whether we are currently processing a reset event or not */
|
||||||
|
|||||||
@@ -939,7 +939,7 @@ void HTMLInputElement::Shutdown() {
|
|||||||
HTMLInputElement::HTMLInputElement(
|
HTMLInputElement::HTMLInputElement(
|
||||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
||||||
FromParser aFromParser, FromClone aFromClone)
|
FromParser aFromParser, FromClone aFromClone)
|
||||||
: nsGenericHTMLFormElementWithState(std::move(aNodeInfo), aFromParser,
|
: nsGenericHTMLFormElementWithState(std::move(aNodeInfo),
|
||||||
kInputDefaultType->value),
|
kInputDefaultType->value),
|
||||||
mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
||||||
mAutocompleteInfoState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
mAutocompleteInfoState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
||||||
@@ -5894,8 +5894,9 @@ void HTMLInputElement::DoneCreatingElement() {
|
|||||||
// Restore state as needed. Note that disabled state applies to all control
|
// Restore state as needed. Note that disabled state applies to all control
|
||||||
// types.
|
// types.
|
||||||
//
|
//
|
||||||
GenerateStateKey();
|
bool restoredCheckedState = !mInhibitRestoration &&
|
||||||
bool restoredCheckedState = !mInhibitRestoration && RestoreFormControlState();
|
NS_SUCCEEDED(GenerateStateKey()) &&
|
||||||
|
RestoreFormControlState();
|
||||||
|
|
||||||
//
|
//
|
||||||
// If restore does not occur, we initialize .checked using the CHECKED
|
// If restore does not occur, we initialize .checked using the CHECKED
|
||||||
|
|||||||
@@ -111,8 +111,7 @@ SafeOptionListMutation::~SafeOptionListMutation() {
|
|||||||
HTMLSelectElement::HTMLSelectElement(
|
HTMLSelectElement::HTMLSelectElement(
|
||||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
||||||
FromParser aFromParser)
|
FromParser aFromParser)
|
||||||
: nsGenericHTMLFormElementWithState(std::move(aNodeInfo), aFromParser,
|
: nsGenericHTMLFormElementWithState(std::move(aNodeInfo), NS_FORM_SELECT),
|
||||||
NS_FORM_SELECT),
|
|
||||||
mOptions(new HTMLOptionsCollection(this)),
|
mOptions(new HTMLOptionsCollection(this)),
|
||||||
mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
||||||
mAutocompleteInfoState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
mAutocompleteInfoState(nsContentUtils::eAutocompleteAttrState_Unknown),
|
||||||
@@ -1113,9 +1112,11 @@ void HTMLSelectElement::DoneAddingChildren(bool aHaveNotified) {
|
|||||||
selectFrame->DoneAddingChildren(true);
|
selectFrame->DoneAddingChildren(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateStateKey();
|
|
||||||
if (!mInhibitStateRestoration) {
|
if (!mInhibitStateRestoration) {
|
||||||
RestoreFormControlState();
|
nsresult rv = GenerateStateKey();
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
RestoreFormControlState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we're done, select something (if it's a single select something
|
// Now that we're done, select something (if it's a single select something
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ namespace dom {
|
|||||||
HTMLTextAreaElement::HTMLTextAreaElement(
|
HTMLTextAreaElement::HTMLTextAreaElement(
|
||||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
||||||
FromParser aFromParser)
|
FromParser aFromParser)
|
||||||
: nsGenericHTMLFormElementWithState(std::move(aNodeInfo), aFromParser,
|
: nsGenericHTMLFormElementWithState(std::move(aNodeInfo), NS_FORM_TEXTAREA),
|
||||||
NS_FORM_TEXTAREA),
|
|
||||||
mValueChanged(false),
|
mValueChanged(false),
|
||||||
mLastValueChangeWasInteractive(false),
|
mLastValueChangeWasInteractive(false),
|
||||||
mHandlingSelect(false),
|
mHandlingSelect(false),
|
||||||
@@ -518,9 +517,11 @@ void HTMLTextAreaElement::DoneAddingChildren(bool aHaveNotified) {
|
|||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateStateKey();
|
|
||||||
if (!mInhibitStateRestoration) {
|
if (!mInhibitStateRestoration) {
|
||||||
RestoreFormControlState();
|
nsresult rv = GenerateStateKey();
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
RestoreFormControlState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1611,7 +1611,7 @@ void nsGenericHTMLFormElement::ClearForm(bool aRemoveFromForm,
|
|||||||
AfterClearForm(aUnbindOrDelete);
|
AfterClearForm(aUnbindOrDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
HTMLFormElement* nsGenericHTMLFormElement::GetFormElement() { return mForm; }
|
Element* nsGenericHTMLFormElement::GetFormElement() { return mForm; }
|
||||||
|
|
||||||
HTMLFieldSetElement* nsGenericHTMLFormElement::GetFieldSet() {
|
HTMLFieldSetElement* nsGenericHTMLFormElement::GetFieldSet() {
|
||||||
return mFieldSet;
|
return mFieldSet;
|
||||||
@@ -2520,29 +2520,29 @@ void nsGenericHTMLElement::ChangeEditableState(int32_t aChange) {
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
nsGenericHTMLFormElementWithState::nsGenericHTMLFormElementWithState(
|
nsGenericHTMLFormElementWithState::nsGenericHTMLFormElementWithState(
|
||||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, uint8_t aType)
|
||||||
FromParser aFromParser, uint8_t aType)
|
: nsGenericHTMLFormElement(std::move(aNodeInfo), aType) {
|
||||||
: nsGenericHTMLFormElement(std::move(aNodeInfo), aType),
|
|
||||||
mControlNumber(!!(aFromParser & FROM_PARSER_NETWORK)
|
|
||||||
? OwnerDoc()->GetNextControlNumber()
|
|
||||||
: -1) {
|
|
||||||
mStateKey.SetIsVoid(true);
|
mStateKey.SetIsVoid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsGenericHTMLFormElementWithState::GenerateStateKey() {
|
nsresult nsGenericHTMLFormElementWithState::GenerateStateKey() {
|
||||||
// Keep the key if already computed
|
// Keep the key if already computed
|
||||||
if (!mStateKey.IsVoid()) {
|
if (!mStateKey.IsVoid()) {
|
||||||
return;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Document* doc = GetUncomposedDoc();
|
Document* doc = GetUncomposedDoc();
|
||||||
if (!doc) {
|
if (!doc) {
|
||||||
mStateKey.Truncate();
|
return NS_OK;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the state key
|
// Generate the state key
|
||||||
nsContentUtils::GenerateStateKey(this, doc, mStateKey);
|
nsresult rv = nsContentUtils::GenerateStateKey(this, doc, mStateKey);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
mStateKey.SetIsVoid(true);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// If the state key is blank, this is anonymous content or for whatever
|
// If the state key is blank, this is anonymous content or for whatever
|
||||||
// reason we are not supposed to save/restore state: keep it as such.
|
// reason we are not supposed to save/restore state: keep it as such.
|
||||||
@@ -2550,6 +2550,7 @@ void nsGenericHTMLFormElementWithState::GenerateStateKey() {
|
|||||||
// Add something unique to content so layout doesn't muck us up.
|
// Add something unique to content so layout doesn't muck us up.
|
||||||
mStateKey += "-C";
|
mStateKey += "-C";
|
||||||
}
|
}
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
PresState* nsGenericHTMLFormElementWithState::GetPrimaryPresState() {
|
PresState* nsGenericHTMLFormElementWithState::GetPrimaryPresState() {
|
||||||
@@ -2597,9 +2598,6 @@ nsGenericHTMLFormElementWithState::GetLayoutHistory(bool aRead) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool nsGenericHTMLFormElementWithState::RestoreFormControlState() {
|
bool nsGenericHTMLFormElementWithState::RestoreFormControlState() {
|
||||||
MOZ_ASSERT(!mStateKey.IsVoid(),
|
|
||||||
"GenerateStateKey must already have been called");
|
|
||||||
|
|
||||||
if (mStateKey.IsEmpty()) {
|
if (mStateKey.IsEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2622,12 +2620,6 @@ bool nsGenericHTMLFormElementWithState::RestoreFormControlState() {
|
|||||||
|
|
||||||
void nsGenericHTMLFormElementWithState::NodeInfoChanged(Document* aOldDoc) {
|
void nsGenericHTMLFormElementWithState::NodeInfoChanged(Document* aOldDoc) {
|
||||||
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
|
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
|
||||||
|
|
||||||
// We need to regenerate the state key now we're in a new document. Clearing
|
|
||||||
// mControlNumber means we stop considering this control to be parser
|
|
||||||
// inserted, and we'll generate a state key based on its position in the
|
|
||||||
// document rather than the order it was inserted into the document.
|
|
||||||
mControlNumber = -1;
|
|
||||||
mStateKey.SetIsVoid(true);
|
mStateKey.SetIsVoid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -930,7 +930,7 @@ class nsGenericHTMLFormElement : public nsGenericHTMLElement,
|
|||||||
|
|
||||||
// nsIFormControl
|
// nsIFormControl
|
||||||
virtual mozilla::dom::HTMLFieldSetElement* GetFieldSet() override;
|
virtual mozilla::dom::HTMLFieldSetElement* GetFieldSet() override;
|
||||||
virtual mozilla::dom::HTMLFormElement* GetFormElement() override;
|
virtual mozilla::dom::Element* GetFormElement() override;
|
||||||
mozilla::dom::HTMLFormElement* GetForm() const { return mForm; }
|
mozilla::dom::HTMLFormElement* GetForm() const { return mForm; }
|
||||||
virtual void SetForm(mozilla::dom::HTMLFormElement* aForm) override;
|
virtual void SetForm(mozilla::dom::HTMLFormElement* aForm) override;
|
||||||
virtual void ClearForm(bool aRemoveFromForm, bool aUnbindOrDelete) override;
|
virtual void ClearForm(bool aRemoveFromForm, bool aUnbindOrDelete) override;
|
||||||
@@ -1083,8 +1083,7 @@ class nsGenericHTMLFormElement : public nsGenericHTMLElement,
|
|||||||
class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement {
|
class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement {
|
||||||
public:
|
public:
|
||||||
nsGenericHTMLFormElementWithState(
|
nsGenericHTMLFormElementWithState(
|
||||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, uint8_t aType);
|
||||||
mozilla::dom::FromParser aFromParser, uint8_t aType);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the presentation state for a piece of content, or create it if it does
|
* Get the presentation state for a piece of content, or create it if it does
|
||||||
@@ -1102,40 +1101,28 @@ class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement {
|
|||||||
already_AddRefed<nsILayoutHistoryState> GetLayoutHistory(bool aRead);
|
already_AddRefed<nsILayoutHistoryState> GetLayoutHistory(bool aRead);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when we have been cloned and adopted, and the information of the
|
* Restore the state for a form control. Ends up calling
|
||||||
* node has been changed.
|
|
||||||
*/
|
|
||||||
virtual void NodeInfoChanged(Document* aOldDoc) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* Restore the state for a form control in response to the element being
|
|
||||||
* inserted into the document by the parser. Ends up calling
|
|
||||||
* nsIFormControl::RestoreState().
|
* nsIFormControl::RestoreState().
|
||||||
*
|
*
|
||||||
* GenerateStateKey() must already have been called.
|
|
||||||
*
|
|
||||||
* @return false if RestoreState() was not called, the return
|
* @return false if RestoreState() was not called, the return
|
||||||
* value of RestoreState() otherwise.
|
* value of RestoreState() otherwise.
|
||||||
*/
|
*/
|
||||||
bool RestoreFormControlState();
|
bool RestoreFormControlState();
|
||||||
|
|
||||||
/* Generates the state key for saving the form state in the session if not
|
/**
|
||||||
computed already. The result is stored in mStateKey. */
|
* Called when we have been cloned and adopted, and the information of the
|
||||||
void GenerateStateKey();
|
* node has been changed.
|
||||||
|
*/
|
||||||
|
virtual void NodeInfoChanged(Document* aOldDoc) override;
|
||||||
|
|
||||||
int32_t GetParserInsertedControlNumberForStateKey() const override {
|
protected:
|
||||||
return mControlNumber;
|
/* Generates the state key for saving the form state in the session if not
|
||||||
}
|
computed already. The result is stored in mStateKey on success */
|
||||||
|
nsresult GenerateStateKey();
|
||||||
|
|
||||||
/* Used to store the key to that element in the session. Is void until
|
/* Used to store the key to that element in the session. Is void until
|
||||||
GenerateStateKey has been used */
|
GenerateStateKey has been used */
|
||||||
nsCString mStateKey;
|
nsCString mStateKey;
|
||||||
|
|
||||||
// A number for this form control that is unique within its owner document.
|
|
||||||
// This is only set to a number for elements inserted into the document by
|
|
||||||
// the parser from the network. Otherwise, it is -1.
|
|
||||||
int32_t mControlNumber;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NS_INTERFACE_MAP_ENTRY_IF_TAG(_interface, _tag) \
|
#define NS_INTERFACE_MAP_ENTRY_IF_TAG(_interface, _tag) \
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class nsIFormControl : public nsISupports {
|
|||||||
* Get the form for this form control.
|
* Get the form for this form control.
|
||||||
* @return the form
|
* @return the form
|
||||||
*/
|
*/
|
||||||
virtual mozilla::dom::HTMLFormElement* GetFormElement() = 0;
|
virtual mozilla::dom::Element* GetFormElement() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the form for this form control.
|
* Set the form for this form control.
|
||||||
@@ -222,16 +222,6 @@ class nsIFormControl : public nsISupports {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a number for this form control that is unique within its
|
|
||||||
// owner document. This is used by nsContentUtils::GenerateStateKey
|
|
||||||
// to identify form controls that are inserted into the document by
|
|
||||||
// the parser. -1 is returned for form controls with no state or
|
|
||||||
// which were inserted into the document by some other means than
|
|
||||||
// the parser from the network.
|
|
||||||
virtual int32_t GetParserInsertedControlNumberForStateKey() const {
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Returns whether mType corresponds to a single line text control type.
|
* Returns whether mType corresponds to a single line text control type.
|
||||||
|
|||||||
@@ -146,8 +146,8 @@ void nsFrameManager::CaptureFrameStateFor(nsIFrame* aFrame,
|
|||||||
nsAutoCString stateKey;
|
nsAutoCString stateKey;
|
||||||
nsIContent* content = aFrame->GetContent();
|
nsIContent* content = aFrame->GetContent();
|
||||||
Document* doc = content ? content->GetUncomposedDoc() : nullptr;
|
Document* doc = content ? content->GetUncomposedDoc() : nullptr;
|
||||||
statefulFrame->GenerateStateKey(content, doc, stateKey);
|
nsresult rv = statefulFrame->GenerateStateKey(content, doc, stateKey);
|
||||||
if (stateKey.IsEmpty()) {
|
if (NS_FAILED(rv) || stateKey.IsEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,8 +207,8 @@ void nsFrameManager::RestoreFrameStateFor(nsIFrame* aFrame,
|
|||||||
|
|
||||||
nsAutoCString stateKey;
|
nsAutoCString stateKey;
|
||||||
Document* doc = content->GetUncomposedDoc();
|
Document* doc = content->GetUncomposedDoc();
|
||||||
statefulFrame->GenerateStateKey(content, doc, stateKey);
|
nsresult rv = statefulFrame->GenerateStateKey(content, doc, stateKey);
|
||||||
if (stateKey.IsEmpty()) {
|
if (NS_FAILED(rv) || stateKey.IsEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ void nsFrameManager::RestoreFrameStateFor(nsIFrame* aFrame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore it
|
// Restore it
|
||||||
nsresult rv = statefulFrame->RestoreState(frameState);
|
rv = statefulFrame->RestoreState(frameState);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1569,14 +1569,16 @@ nsComboboxControlFrame::RestoreState(PresState* aState) {
|
|||||||
// Append a suffix so that the state key for the combobox is different
|
// Append a suffix so that the state key for the combobox is different
|
||||||
// from the state key the list control uses to sometimes save the scroll
|
// from the state key the list control uses to sometimes save the scroll
|
||||||
// position for the same Element
|
// position for the same Element
|
||||||
void nsComboboxControlFrame::GenerateStateKey(nsIContent* aContent,
|
NS_IMETHODIMP
|
||||||
Document* aDocument,
|
nsComboboxControlFrame::GenerateStateKey(nsIContent* aContent,
|
||||||
nsACString& aKey) {
|
Document* aDocument,
|
||||||
nsContentUtils::GenerateStateKey(aContent, aDocument, aKey);
|
nsACString& aKey) {
|
||||||
if (aKey.IsEmpty()) {
|
nsresult rv = nsContentUtils::GenerateStateKey(aContent, aDocument, aKey);
|
||||||
return;
|
if (NS_FAILED(rv) || aKey.IsEmpty()) {
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
aKey.AppendLiteral("CCF");
|
aKey.AppendLiteral("CCF");
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fennec uses a custom combobox built-in widget.
|
// Fennec uses a custom combobox built-in widget.
|
||||||
|
|||||||
@@ -209,8 +209,9 @@ class nsComboboxControlFrame final : public nsBlockFrame,
|
|||||||
mozilla::UniquePtr<mozilla::PresState> SaveState() override;
|
mozilla::UniquePtr<mozilla::PresState> SaveState() override;
|
||||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||||
NS_IMETHOD RestoreState(mozilla::PresState* aState) override;
|
NS_IMETHOD RestoreState(mozilla::PresState* aState) override;
|
||||||
void GenerateStateKey(nsIContent* aContent, mozilla::dom::Document* aDocument,
|
NS_IMETHOD GenerateStateKey(nsIContent* aContent,
|
||||||
nsACString& aKey) override;
|
mozilla::dom::Document* aDocument,
|
||||||
|
nsACString& aKey) override;
|
||||||
|
|
||||||
static bool ToolkitHasNativePopup();
|
static bool ToolkitHasNativePopup();
|
||||||
|
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ class nsIStatefulFrame {
|
|||||||
NS_IMETHOD RestoreState(mozilla::PresState* aState) = 0;
|
NS_IMETHOD RestoreState(mozilla::PresState* aState) = 0;
|
||||||
|
|
||||||
// Generate a key for this stateful frame
|
// Generate a key for this stateful frame
|
||||||
virtual void GenerateStateKey(nsIContent* aContent,
|
NS_IMETHOD GenerateStateKey(nsIContent* aContent,
|
||||||
mozilla::dom::Document* aDocument,
|
mozilla::dom::Document* aDocument,
|
||||||
nsACString& aKey) {
|
nsACString& aKey) {
|
||||||
nsContentUtils::GenerateStateKey(aContent, aDocument, aKey);
|
return nsContentUtils::GenerateStateKey(aContent, aDocument, aKey);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user