зеркало из https://github.com/mozilla/gecko-dev.git
Bug 737851 - Generate form state key at page load instead of page unload. r=bz
This commit is contained in:
Родитель
341f7bc310
Коммит
a5fb99687b
|
@ -54,7 +54,7 @@ static const nsAttrValue::EnumTable* kButtonDefaultType = &kButtonTypeTable[2];
|
|||
// Construction, destruction
|
||||
HTMLButtonElement::HTMLButtonElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
: nsGenericHTMLFormElement(aNodeInfo),
|
||||
: nsGenericHTMLFormElementWithState(aNodeInfo),
|
||||
mType(kButtonDefaultType->value),
|
||||
mDisabledChanged(false),
|
||||
mInInternalActivate(false),
|
||||
|
@ -73,7 +73,8 @@ HTMLButtonElement::~HTMLButtonElement()
|
|||
|
||||
// nsISupports
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLButtonElement, nsGenericHTMLFormElement,
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLButtonElement,
|
||||
nsGenericHTMLFormElementWithState,
|
||||
mValidity)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(HTMLButtonElement, Element)
|
||||
|
@ -82,7 +83,7 @@ NS_IMPL_RELEASE_INHERITED(HTMLButtonElement, Element)
|
|||
|
||||
// QueryInterface implementation for HTMLButtonElement
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLButtonElement)
|
||||
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
|
||||
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElementWithState)
|
||||
NS_INTERFACE_TABLE_INHERITED2(HTMLButtonElement,
|
||||
nsIDOMHTMLButtonElement,
|
||||
nsIConstraintValidation)
|
||||
|
@ -103,7 +104,7 @@ NS_IMPL_ELEMENT_CLONE(HTMLButtonElement)
|
|||
NS_IMETHODIMP
|
||||
HTMLButtonElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
{
|
||||
return nsGenericHTMLFormElement::GetForm(aForm);
|
||||
return nsGenericHTMLFormElementWithState::GetForm(aForm);
|
||||
}
|
||||
|
||||
NS_IMPL_BOOL_ATTR(HTMLButtonElement, Autofocus, autofocus)
|
||||
|
@ -129,7 +130,7 @@ HTMLButtonElement::TabIndexDefault()
|
|||
bool
|
||||
HTMLButtonElement::IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex)
|
||||
{
|
||||
if (nsGenericHTMLFormElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
|
||||
if (nsGenericHTMLFormElementWithState::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -392,9 +393,9 @@ HTMLButtonElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
nsresult rv =
|
||||
nsGenericHTMLFormElementWithState::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Update our state; we may now be the default submit element
|
||||
|
@ -406,7 +407,7 @@ HTMLButtonElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
void
|
||||
HTMLButtonElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLFormElementWithState::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// Update our state; we may no longer be the default submit element
|
||||
UpdateState(false);
|
||||
|
@ -461,8 +462,10 @@ void
|
|||
HTMLButtonElement::DoneCreatingElement()
|
||||
{
|
||||
if (!mInhibitStateRestoration) {
|
||||
// Restore state as needed.
|
||||
RestoreFormControlState(this, this);
|
||||
nsresult rv = GenerateStateKey();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
RestoreFormControlState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,8 +479,8 @@ HTMLButtonElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
mDisabledChanged = true;
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -494,8 +497,8 @@ HTMLButtonElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
return nsGenericHTMLFormElementWithState::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -528,7 +531,7 @@ HTMLButtonElement::RestoreState(nsPresState* aState)
|
|||
nsEventStates
|
||||
HTMLButtonElement::IntrinsicState() const
|
||||
{
|
||||
nsEventStates state = nsGenericHTMLFormElement::IntrinsicState();
|
||||
nsEventStates state = nsGenericHTMLFormElementWithState::IntrinsicState();
|
||||
|
||||
if (mForm && !mForm->GetValidity() && IsSubmitControl()) {
|
||||
state |= NS_EVENT_STATE_MOZ_SUBMITINVALID;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class HTMLButtonElement MOZ_FINAL : public nsGenericHTMLFormElement,
|
||||
class HTMLButtonElement MOZ_FINAL : public nsGenericHTMLFormElementWithState,
|
||||
public nsIDOMHTMLButtonElement,
|
||||
public nsIConstraintValidation
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ public:
|
|||
virtual ~HTMLButtonElement();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLButtonElement,
|
||||
nsGenericHTMLFormElement)
|
||||
nsGenericHTMLFormElementWithState)
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
|
|
@ -770,7 +770,7 @@ static nsresult FireEventForAccessibility(nsIDOMHTMLInputElement* aTarget,
|
|||
|
||||
HTMLInputElement::HTMLInputElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
: nsGenericHTMLFormElement(aNodeInfo)
|
||||
: nsGenericHTMLFormElementWithState(aNodeInfo)
|
||||
, mType(kInputDefaultType->value)
|
||||
, mDisabledChanged(false)
|
||||
, mValueChanged(false)
|
||||
|
@ -843,7 +843,7 @@ HTMLInputElement::GetEditorState() const
|
|||
// nsISupports
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLInputElement,
|
||||
nsGenericHTMLFormElement)
|
||||
nsGenericHTMLFormElementWithState)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControllers)
|
||||
if (tmp->IsSingleLineTextControl(false)) {
|
||||
|
@ -854,7 +854,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLInputElement,
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLInputElement,
|
||||
nsGenericHTMLFormElement)
|
||||
nsGenericHTMLFormElementWithState)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFiles)
|
||||
|
@ -873,7 +873,7 @@ NS_IMPL_RELEASE_INHERITED(HTMLInputElement, Element)
|
|||
|
||||
// QueryInterface implementation for HTMLInputElement
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLInputElement)
|
||||
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
|
||||
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElementWithState)
|
||||
NS_INTERFACE_TABLE_INHERITED8(HTMLInputElement,
|
||||
nsIDOMHTMLInputElement,
|
||||
nsITextControlElement,
|
||||
|
@ -975,8 +975,8 @@ HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1120,8 +1120,8 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
UpdateState(aNotify);
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
return nsGenericHTMLFormElementWithState::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
// nsIDOMHTMLInputElement
|
||||
|
@ -1129,7 +1129,7 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
NS_IMETHODIMP
|
||||
HTMLInputElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
{
|
||||
return nsGenericHTMLFormElement::GetForm(aForm);
|
||||
return nsGenericHTMLFormElementWithState::GetForm(aForm);
|
||||
}
|
||||
|
||||
NS_IMPL_STRING_ATTR(HTMLInputElement, DefaultValue, value)
|
||||
|
@ -2254,9 +2254,9 @@ HTMLInputElement::SetValueInternal(const nsAString& aValue,
|
|||
}
|
||||
|
||||
// Treat value == defaultValue for other input elements.
|
||||
return nsGenericHTMLFormElement::SetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::value, aValue,
|
||||
true);
|
||||
return nsGenericHTMLFormElementWithState::SetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::value, aValue,
|
||||
true);
|
||||
|
||||
case VALUE_MODE_FILENAME:
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -2765,7 +2765,7 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
if (mType == NS_FORM_INPUT_RANGE &&
|
||||
(aVisitor.mEvent->message == NS_FOCUS_CONTENT ||
|
||||
aVisitor.mEvent->message == NS_BLUR_CONTENT)) {
|
||||
// Just as nsGenericHTMLFormElement::PreHandleEvent calls
|
||||
// Just as nsGenericHTMLFormElementWithState::PreHandleEvent calls
|
||||
// nsIFormControlFrame::SetFocus, we handle focus here.
|
||||
nsIFrame* frame = GetPrimaryFrame();
|
||||
if (frame) {
|
||||
|
@ -2773,7 +2773,7 @@ HTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::PreHandleEvent(aVisitor);
|
||||
return nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3451,9 +3451,9 @@ HTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
nsresult rv = nsGenericHTMLFormElementWithState::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
|
@ -3500,7 +3500,7 @@ void
|
|||
HTMLInputElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
// If we have a form and are unbound from it,
|
||||
// nsGenericHTMLFormElement::UnbindFromTree() will unset the form and
|
||||
// nsGenericHTMLFormElementWithState::UnbindFromTree() will unset the form and
|
||||
// that takes care of form's WillRemove so we just have to take care
|
||||
// of the case where we're removing from the document and we don't
|
||||
// have a form
|
||||
|
@ -3509,7 +3509,7 @@ HTMLInputElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||
}
|
||||
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLFormElementWithState::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// GetCurrentDoc is returning nullptr so we can update the value
|
||||
// missing validity state to reflect we are no longer into a doc.
|
||||
|
@ -4025,14 +4025,14 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::type);
|
||||
if (value && value->Type() == nsAttrValue::eEnum &&
|
||||
value->GetEnumValue() == NS_FORM_INPUT_IMAGE) {
|
||||
nsGenericHTMLFormElement::MapImageBorderAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElement::MapImageMarginAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElement::MapImageSizeAttributesInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapImageBorderAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapImageMarginAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapImageSizeAttributesInto(aAttributes, aData);
|
||||
// Images treat align as "float"
|
||||
nsGenericHTMLFormElement::MapImageAlignAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapImageAlignAttributeInto(aAttributes, aData);
|
||||
}
|
||||
|
||||
nsGenericHTMLFormElement::MapCommonAttributesInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapCommonAttributesInto(aAttributes, aData);
|
||||
}
|
||||
|
||||
nsChangeHint
|
||||
|
@ -4040,7 +4040,7 @@ HTMLInputElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
|||
int32_t aModType) const
|
||||
{
|
||||
nsChangeHint retval =
|
||||
nsGenericHTMLFormElement::GetAttributeChangeHint(aAttribute, aModType);
|
||||
nsGenericHTMLFormElementWithState::GetAttributeChangeHint(aAttribute, aModType);
|
||||
if (aAttribute == nsGkAtoms::type) {
|
||||
NS_UpdateHint(retval, NS_STYLE_HINT_FRAMECHANGE);
|
||||
} else if (mType == NS_FORM_INPUT_IMAGE &&
|
||||
|
@ -4699,7 +4699,7 @@ HTMLInputElement::DoneCreatingElement()
|
|||
// types.
|
||||
//
|
||||
bool restoredCheckedState =
|
||||
!mInhibitRestoration && RestoreFormControlState(this, this);
|
||||
!mInhibitRestoration && NS_SUCCEEDED(GenerateStateKey()) && RestoreFormControlState();
|
||||
|
||||
//
|
||||
// If restore does not occur, we initialize .checked using the CHECKED
|
||||
|
@ -4726,7 +4726,7 @@ HTMLInputElement::IntrinsicState() const
|
|||
// If you add states here, and they're type-dependent, you need to add them
|
||||
// to the type case in AfterSetAttr.
|
||||
|
||||
nsEventStates state = nsGenericHTMLFormElement::IntrinsicState();
|
||||
nsEventStates state = nsGenericHTMLFormElementWithState::IntrinsicState();
|
||||
if (mType == NS_FORM_INPUT_CHECKBOX || mType == NS_FORM_INPUT_RADIO) {
|
||||
// Check current checked state (:checked)
|
||||
if (mChecked) {
|
||||
|
@ -4933,7 +4933,9 @@ HTMLInputElement::WillRemoveFromRadioGroup()
|
|||
bool
|
||||
HTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable, int32_t* aTabIndex)
|
||||
{
|
||||
if (nsGenericHTMLFormElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
|
||||
if (nsGenericHTMLFormElementWithState::IsHTMLFocusable(aWithMouse, aIsFocusable,
|
||||
aTabIndex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5972,7 +5974,7 @@ HTMLInputElement::FieldSetDisabledChanged(bool aNotify)
|
|||
UpdateValueMissingValidityState();
|
||||
UpdateBarredFromConstraintValidation();
|
||||
|
||||
nsGenericHTMLFormElement::FieldSetDisabledChanged(aNotify);
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
};
|
||||
};
|
||||
|
||||
class HTMLInputElement MOZ_FINAL : public nsGenericHTMLFormElement,
|
||||
class HTMLInputElement MOZ_FINAL : public nsGenericHTMLFormElementWithState,
|
||||
public nsImageLoadingContent,
|
||||
public nsIDOMHTMLInputElement,
|
||||
public nsITextControlElement,
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
using nsIConstraintValidation::CheckValidity;
|
||||
using nsIConstraintValidation::WillValidate;
|
||||
using nsIConstraintValidation::Validity;
|
||||
using nsGenericHTMLFormElement::GetForm;
|
||||
using nsGenericHTMLFormElementWithState::GetForm;
|
||||
|
||||
HTMLInputElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
mozilla::dom::FromParser aFromParser);
|
||||
|
@ -226,7 +226,7 @@ public:
|
|||
NS_IMETHOD FireAsyncClickHandler();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLInputElement,
|
||||
nsGenericHTMLFormElement)
|
||||
nsGenericHTMLFormElementWithState)
|
||||
|
||||
static UploadLastDir* gUploadLastDir;
|
||||
// create and destroy the static UploadLastDir object for remembering
|
||||
|
@ -665,7 +665,7 @@ protected:
|
|||
|
||||
// Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden
|
||||
// by the nsITextControlElement version.
|
||||
using nsGenericHTMLFormElement::IsSingleLineTextControl;
|
||||
using nsGenericHTMLFormElementWithState::IsSingleLineTextControl;
|
||||
|
||||
/**
|
||||
* The ValueModeType specifies how the value IDL attribute should behave.
|
||||
|
|
|
@ -103,7 +103,7 @@ SafeOptionListMutation::~SafeOptionListMutation()
|
|||
|
||||
HTMLSelectElement::HTMLSelectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
: nsGenericHTMLFormElement(aNodeInfo),
|
||||
: nsGenericHTMLFormElementWithState(aNodeInfo),
|
||||
mOptions(new HTMLOptionsCollection(MOZ_THIS_IN_INITIALIZER_LIST())),
|
||||
mIsDoneAddingChildren(!aFromParser),
|
||||
mDisabledChanged(false),
|
||||
|
@ -134,12 +134,12 @@ HTMLSelectElement::~HTMLSelectElement()
|
|||
// ISupports
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLSelectElement,
|
||||
nsGenericHTMLFormElement)
|
||||
nsGenericHTMLFormElementWithState)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOptions)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLSelectElement,
|
||||
nsGenericHTMLFormElement)
|
||||
nsGenericHTMLFormElementWithState)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
@ -148,7 +148,7 @@ NS_IMPL_RELEASE_INHERITED(HTMLSelectElement, Element)
|
|||
|
||||
// QueryInterface implementation for HTMLSelectElement
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLSelectElement)
|
||||
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
|
||||
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElementWithState)
|
||||
NS_INTERFACE_TABLE_INHERITED2(HTMLSelectElement,
|
||||
nsIDOMHTMLSelectElement,
|
||||
nsIConstraintValidation)
|
||||
|
@ -177,7 +177,7 @@ HTMLSelectElement::SetCustomValidity(const nsAString& aError)
|
|||
NS_IMETHODIMP
|
||||
HTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
{
|
||||
return nsGenericHTMLFormElement::GetForm(aForm);
|
||||
return nsGenericHTMLFormElementWithState::GetForm(aForm);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -186,7 +186,8 @@ HTMLSelectElement::InsertChildAt(nsIContent* aKid,
|
|||
bool aNotify)
|
||||
{
|
||||
SafeOptionListMutation safeMutation(this, this, aKid, aIndex, aNotify);
|
||||
nsresult rv = nsGenericHTMLFormElement::InsertChildAt(aKid, aIndex, aNotify);
|
||||
nsresult rv = nsGenericHTMLFormElementWithState::InsertChildAt(aKid, aIndex,
|
||||
aNotify);
|
||||
if (NS_FAILED(rv)) {
|
||||
safeMutation.MutationFailed();
|
||||
}
|
||||
|
@ -197,7 +198,7 @@ void
|
|||
HTMLSelectElement::RemoveChildAt(uint32_t aIndex, bool aNotify)
|
||||
{
|
||||
SafeOptionListMutation safeMutation(this, this, nullptr, aIndex, aNotify);
|
||||
nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify);
|
||||
nsGenericHTMLFormElementWithState::RemoveChildAt(aIndex, aNotify);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1174,7 +1175,9 @@ bool
|
|||
HTMLSelectElement::IsHTMLFocusable(bool aWithMouse,
|
||||
bool* aIsFocusable, int32_t* aTabIndex)
|
||||
{
|
||||
if (nsGenericHTMLFormElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
|
||||
if (nsGenericHTMLFormElementWithState::IsHTMLFocusable(aWithMouse, aIsFocusable,
|
||||
aTabIndex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1239,9 +1242,9 @@ HTMLSelectElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
nsresult rv = nsGenericHTMLFormElementWithState::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If there is a disabled fieldset in the parent chain, the element is now
|
||||
|
@ -1259,7 +1262,7 @@ HTMLSelectElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
void
|
||||
HTMLSelectElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLFormElementWithState::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// We might be no longer disabled because our parent chain changed.
|
||||
// XXXbz is this still needed now that fieldset changes always call
|
||||
|
@ -1280,8 +1283,8 @@ HTMLSelectElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
mDisabledChanged = true;
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1298,8 +1301,8 @@ HTMLSelectElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
UpdateState(aNotify);
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
return nsGenericHTMLFormElementWithState::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1319,8 +1322,8 @@ HTMLSelectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|||
}
|
||||
}
|
||||
|
||||
nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID, aAttribute,
|
||||
aNotify);
|
||||
nsresult rv = nsGenericHTMLFormElementWithState::UnsetAttr(aNameSpaceID, aAttribute,
|
||||
aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aNotify && aNameSpaceID == kNameSpaceID_None &&
|
||||
|
@ -1352,9 +1355,11 @@ HTMLSelectElement::DoneAddingChildren(bool aHaveNotified)
|
|||
selectFrame->DoneAddingChildren(true);
|
||||
}
|
||||
|
||||
// Restore state
|
||||
if (!mInhibitStateRestoration) {
|
||||
RestoreFormControlState(this, this);
|
||||
nsresult rv = GenerateStateKey();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
RestoreFormControlState();
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we're done, select something (if it's a single select something
|
||||
|
@ -1389,8 +1394,8 @@ static void
|
|||
MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData)
|
||||
{
|
||||
nsGenericHTMLFormElement::MapImageAlignAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElement::MapCommonAttributesInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapImageAlignAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapCommonAttributesInto(aAttributes, aData);
|
||||
}
|
||||
|
||||
nsChangeHint
|
||||
|
@ -1398,7 +1403,7 @@ HTMLSelectElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
|||
int32_t aModType) const
|
||||
{
|
||||
nsChangeHint retval =
|
||||
nsGenericHTMLFormElement::GetAttributeChangeHint(aAttribute, aModType);
|
||||
nsGenericHTMLFormElementWithState::GetAttributeChangeHint(aAttribute, aModType);
|
||||
if (aAttribute == nsGkAtoms::multiple ||
|
||||
aAttribute == nsGkAtoms::size) {
|
||||
NS_UpdateHint(retval, NS_STYLE_HINT_FRAMECHANGE);
|
||||
|
@ -1442,7 +1447,7 @@ HTMLSelectElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::PreHandleEvent(aVisitor);
|
||||
return nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1466,13 +1471,13 @@ HTMLSelectElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
|||
UpdateState(true);
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::PostHandleEvent(aVisitor);
|
||||
return nsGenericHTMLFormElementWithState::PostHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
HTMLSelectElement::IntrinsicState() const
|
||||
{
|
||||
nsEventStates state = nsGenericHTMLFormElement::IntrinsicState();
|
||||
nsEventStates state = nsGenericHTMLFormElementWithState::IntrinsicState();
|
||||
|
||||
if (IsCandidateForConstraintValidation()) {
|
||||
if (IsValid()) {
|
||||
|
@ -1833,7 +1838,7 @@ HTMLSelectElement::FieldSetDisabledChanged(bool aNotify)
|
|||
{
|
||||
UpdateBarredFromConstraintValidation();
|
||||
|
||||
nsGenericHTMLFormElement::FieldSetDisabledChanged(aNotify);
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -103,7 +103,7 @@ private:
|
|||
/**
|
||||
* Implementation of <select>
|
||||
*/
|
||||
class HTMLSelectElement MOZ_FINAL : public nsGenericHTMLFormElement,
|
||||
class HTMLSelectElement MOZ_FINAL : public nsGenericHTMLFormElementWithState,
|
||||
public nsIDOMHTMLSelectElement,
|
||||
public nsIConstraintValidation
|
||||
{
|
||||
|
@ -152,7 +152,7 @@ public:
|
|||
}
|
||||
HTMLFormElement* GetForm() const
|
||||
{
|
||||
return nsGenericHTMLFormElement::GetForm();
|
||||
return nsGenericHTMLFormElementWithState::GetForm();
|
||||
}
|
||||
bool Multiple() const
|
||||
{
|
||||
|
@ -369,7 +369,7 @@ public:
|
|||
virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLSelectElement,
|
||||
nsGenericHTMLFormElement)
|
||||
nsGenericHTMLFormElementWithState)
|
||||
|
||||
HTMLOptionsCollection* GetOptions()
|
||||
{
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace dom {
|
|||
|
||||
HTMLTextAreaElement::HTMLTextAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
: nsGenericHTMLFormElement(aNodeInfo),
|
||||
: nsGenericHTMLFormElementWithState(aNodeInfo),
|
||||
mValueChanged(false),
|
||||
mHandlingSelect(false),
|
||||
mDoneAddingChildren(!aFromParser),
|
||||
|
@ -73,7 +73,8 @@ HTMLTextAreaElement::HTMLTextAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo
|
|||
}
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(HTMLTextAreaElement, nsGenericHTMLFormElement,
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(HTMLTextAreaElement,
|
||||
nsGenericHTMLFormElementWithState,
|
||||
mValidity,
|
||||
mControllers,
|
||||
mState)
|
||||
|
@ -84,7 +85,7 @@ NS_IMPL_RELEASE_INHERITED(HTMLTextAreaElement, Element)
|
|||
|
||||
// QueryInterface implementation for HTMLTextAreaElement
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLTextAreaElement)
|
||||
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElement)
|
||||
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLFormElementWithState)
|
||||
NS_INTERFACE_TABLE_INHERITED5(HTMLTextAreaElement,
|
||||
nsIDOMHTMLTextAreaElement,
|
||||
nsITextControlElement,
|
||||
|
@ -107,7 +108,7 @@ NS_IMPL_NSICONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY(HTMLTextAreaElement)
|
|||
NS_IMETHODIMP
|
||||
HTMLTextAreaElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
{
|
||||
return nsGenericHTMLFormElement::GetForm(aForm);
|
||||
return nsGenericHTMLFormElementWithState::GetForm(aForm);
|
||||
}
|
||||
|
||||
|
||||
|
@ -175,7 +176,9 @@ bool
|
|||
HTMLTextAreaElement::IsHTMLFocusable(bool aWithMouse,
|
||||
bool *aIsFocusable, int32_t *aTabIndex)
|
||||
{
|
||||
if (nsGenericHTMLFormElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
|
||||
if (nsGenericHTMLFormElementWithState::IsHTMLFocusable(aWithMouse, aIsFocusable,
|
||||
aTabIndex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -402,8 +405,8 @@ static void
|
|||
MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData)
|
||||
{
|
||||
nsGenericHTMLFormElement::MapDivAlignAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElement::MapCommonAttributesInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapDivAlignAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLFormElementWithState::MapCommonAttributesInto(aAttributes, aData);
|
||||
}
|
||||
|
||||
nsChangeHint
|
||||
|
@ -411,7 +414,7 @@ HTMLTextAreaElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
|||
int32_t aModType) const
|
||||
{
|
||||
nsChangeHint retval =
|
||||
nsGenericHTMLFormElement::GetAttributeChangeHint(aAttribute, aModType);
|
||||
nsGenericHTMLFormElementWithState::GetAttributeChangeHint(aAttribute, aModType);
|
||||
if (aAttribute == nsGkAtoms::rows ||
|
||||
aAttribute == nsGkAtoms::cols) {
|
||||
NS_UpdateHint(retval, NS_STYLE_HINT_REFLOW);
|
||||
|
@ -486,7 +489,7 @@ HTMLTextAreaElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
FireChangeEventIfNeeded();
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::PreHandleEvent(aVisitor);
|
||||
return nsGenericHTMLFormElementWithState::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -549,8 +552,12 @@ HTMLTextAreaElement::DoneAddingChildren(bool aHaveNotified)
|
|||
// sneak some text in without calling AppendChildTo.
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (!mInhibitStateRestoration) {
|
||||
RestoreFormControlState(this, this);
|
||||
nsresult rv = GenerateStateKey();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
RestoreFormControlState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1003,7 +1010,7 @@ HTMLTextAreaElement::RestoreState(nsPresState* aState)
|
|||
nsEventStates
|
||||
HTMLTextAreaElement::IntrinsicState() const
|
||||
{
|
||||
nsEventStates state = nsGenericHTMLFormElement::IntrinsicState();
|
||||
nsEventStates state = nsGenericHTMLFormElementWithState::IntrinsicState();
|
||||
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
|
||||
state |= NS_EVENT_STATE_REQUIRED;
|
||||
|
@ -1050,9 +1057,9 @@ HTMLTextAreaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
nsresult rv = nsGenericHTMLFormElementWithState::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If there is a disabled fieldset in the parent chain, the element is now
|
||||
|
@ -1069,7 +1076,7 @@ HTMLTextAreaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
void
|
||||
HTMLTextAreaElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLFormElementWithState::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// We might be no longer disabled because of parent chain changed.
|
||||
UpdateValueMissingValidityState();
|
||||
|
@ -1089,7 +1096,7 @@ HTMLTextAreaElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
mDisabledChanged = true;
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::BeforeSetAttr(aNameSpaceID, aName,
|
||||
return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
|
@ -1161,14 +1168,14 @@ HTMLTextAreaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
UpdateState(aNotify);
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||
aNotify);
|
||||
}
|
||||
return nsGenericHTMLFormElementWithState::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLTextAreaElement::CopyInnerTo(Element* aDest)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLFormElement::CopyInnerTo(aDest);
|
||||
nsresult rv = nsGenericHTMLFormElementWithState::CopyInnerTo(aDest);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aDest->OwnerDoc()->IsStaticDocument()) {
|
||||
|
@ -1422,7 +1429,7 @@ HTMLTextAreaElement::FieldSetDisabledChanged(bool aNotify)
|
|||
UpdateValueMissingValidityState();
|
||||
UpdateBarredFromConstraintValidation();
|
||||
|
||||
nsGenericHTMLFormElement::FieldSetDisabledChanged(aNotify);
|
||||
nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
|
|
@ -30,7 +30,7 @@ class nsPresState;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class HTMLTextAreaElement MOZ_FINAL : public nsGenericHTMLFormElement,
|
||||
class HTMLTextAreaElement MOZ_FINAL : public nsGenericHTMLFormElementWithState,
|
||||
public nsIDOMHTMLTextAreaElement,
|
||||
public nsITextControlElement,
|
||||
public nsIDOMNSEditableElement,
|
||||
|
@ -147,7 +147,7 @@ public:
|
|||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTextAreaElement,
|
||||
nsGenericHTMLFormElement)
|
||||
nsGenericHTMLFormElementWithState)
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
|
||||
|
||||
|
@ -189,8 +189,8 @@ public:
|
|||
{
|
||||
SetHTMLBoolAttr(nsGkAtoms::disabled, aDisabled, aError);
|
||||
}
|
||||
// nsGenericHTMLFormElement::GetForm is fine
|
||||
using nsGenericHTMLFormElement::GetForm;
|
||||
// nsGenericHTMLFormElementWithState::GetForm is fine
|
||||
using nsGenericHTMLFormElementWithState::GetForm;
|
||||
int32_t MaxLength()
|
||||
{
|
||||
return GetIntAttr(nsGkAtoms::maxlength, -1);
|
||||
|
@ -272,7 +272,8 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
using nsGenericHTMLFormElement::IsSingleLineTextControl; // get rid of the compiler warning
|
||||
// get rid of the compiler warning
|
||||
using nsGenericHTMLFormElementWithState::IsSingleLineTextControl;
|
||||
|
||||
virtual JSObject* WrapNode(JSContext *aCx,
|
||||
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
|
|
|
@ -1175,90 +1175,6 @@ nsGenericHTMLElement::GetFormControlFrame(bool aFlushFrames)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsPresState*
|
||||
nsGenericHTMLElement::GetPrimaryPresState()
|
||||
{
|
||||
nsAutoCString key;
|
||||
nsCOMPtr<nsILayoutHistoryState> history = GetLayoutHistoryAndKey(this, false, key);
|
||||
if (!history) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get the pres state for this key, if it doesn't exist, create one
|
||||
nsPresState* presState = history->GetState(key);
|
||||
if (!presState) {
|
||||
presState = new nsPresState();
|
||||
history->AddState(key, presState);
|
||||
}
|
||||
return presState;
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<nsILayoutHistoryState>
|
||||
nsGenericHTMLElement::GetLayoutHistoryAndKey(nsGenericHTMLElement* aContent,
|
||||
bool aRead,
|
||||
nsACString& aKey)
|
||||
{
|
||||
//
|
||||
// Get the pres shell
|
||||
//
|
||||
nsCOMPtr<nsIDocument> doc = aContent->GetDocument();
|
||||
if (!doc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the history (don't bother with the key if the history is not there)
|
||||
//
|
||||
nsCOMPtr<nsILayoutHistoryState> history = doc->GetLayoutHistoryState();
|
||||
if (!history) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aRead && !history->HasStates()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the state key
|
||||
//
|
||||
nsresult rv = nsContentUtils::GenerateStateKey(aContent, doc, aKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If the state key is blank, this is anonymous content or for
|
||||
// whatever reason we are not supposed to save/restore state.
|
||||
if (aKey.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Add something unique to content so layout doesn't muck us up
|
||||
aKey += "-C";
|
||||
|
||||
return history.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
nsGenericHTMLElement::RestoreFormControlState(nsGenericHTMLElement* aContent,
|
||||
nsIFormControl* aControl)
|
||||
{
|
||||
nsAutoCString key;
|
||||
nsCOMPtr<nsILayoutHistoryState> history = GetLayoutHistoryAndKey(aContent, true, key);
|
||||
if (!history) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsPresState* state = history->GetState(key);
|
||||
if (state) {
|
||||
bool result = aControl->RestoreState(state);
|
||||
history->RemoveState(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX This creates a dependency between content and frames
|
||||
nsPresContext*
|
||||
nsGenericHTMLElement::GetPresContext()
|
||||
|
@ -3114,6 +3030,124 @@ nsGenericHTMLElement::ChangeEditableState(int32_t aChange)
|
|||
MakeContentDescendantsEditable(this, document);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsGenericHTMLFormElementWithState::nsGenericHTMLFormElementWithState(
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo
|
||||
)
|
||||
: nsGenericHTMLFormElement(aNodeInfo)
|
||||
{
|
||||
mStateKey.SetIsVoid(true);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLFormElementWithState::GenerateStateKey()
|
||||
{
|
||||
// Keep the key if already computed
|
||||
if (!mStateKey.IsVoid()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetDocument();
|
||||
if (!doc) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Generate the state key
|
||||
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
|
||||
// reason we are not supposed to save/restore state: keep it as such.
|
||||
if (!mStateKey.IsEmpty()) {
|
||||
// Add something unique to content so layout doesn't muck us up.
|
||||
mStateKey += "-C";
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPresState*
|
||||
nsGenericHTMLFormElementWithState::GetPrimaryPresState()
|
||||
{
|
||||
if (mStateKey.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILayoutHistoryState> history = GetLayoutHistory(false);
|
||||
|
||||
if (!history) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get the pres state for this key, if it doesn't exist, create one.
|
||||
nsPresState* result = history->GetState(mStateKey);
|
||||
if (!result) {
|
||||
result = new nsPresState();
|
||||
history->AddState(mStateKey, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
already_AddRefed<nsILayoutHistoryState>
|
||||
nsGenericHTMLFormElementWithState::GetLayoutHistory(bool aRead)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
if (!doc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the history
|
||||
//
|
||||
nsCOMPtr<nsILayoutHistoryState> history = doc->GetLayoutHistoryState();
|
||||
if (!history) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aRead && !history->HasStates()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return history.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
nsGenericHTMLFormElementWithState::RestoreFormControlState()
|
||||
{
|
||||
if (mStateKey.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILayoutHistoryState> history =
|
||||
GetLayoutHistory(true);
|
||||
if (!history) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsPresState *state;
|
||||
// Get the pres state for this key
|
||||
state = history->GetState(mStateKey);
|
||||
if (state) {
|
||||
bool result = RestoreState(state);
|
||||
history->RemoveState(mStateKey);
|
||||
return result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElementWithState::NodeInfoChanged(nsINodeInfo* aOldNodeInfo)
|
||||
{
|
||||
mStateKey.SetIsVoid(true);
|
||||
}
|
||||
|
||||
JS::Value
|
||||
nsGenericHTMLElement::GetItemValue(JSContext* aCx, JSObject* aScope,
|
||||
ErrorResult& aError)
|
||||
|
|
|
@ -624,39 +624,6 @@ public:
|
|||
*/
|
||||
static void MapScrollingAttributeInto(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData);
|
||||
/**
|
||||
* Get the presentation state for this, or create it if it does not exist.
|
||||
* Generally used by SaveState().
|
||||
*
|
||||
* @return the presentation state (out param)
|
||||
*/
|
||||
nsPresState* GetPrimaryPresState();
|
||||
/**
|
||||
* Get the layout history object *and* generate the key for a particular
|
||||
* piece of content.
|
||||
*
|
||||
* @param aContent the content to generate the key for
|
||||
* @param aRead if true, won't return a layout history state (and won't
|
||||
* generate a key) if the layout history state is empty.
|
||||
* @param aState the history state object (out param)
|
||||
* @param aKey the key (out param)
|
||||
*/
|
||||
static already_AddRefed<nsILayoutHistoryState>
|
||||
GetLayoutHistoryAndKey(nsGenericHTMLElement* aContent,
|
||||
bool aRead,
|
||||
nsACString& aKey);
|
||||
/**
|
||||
* Restore the state for a form control. Ends up calling
|
||||
* nsIFormControl::RestoreState().
|
||||
*
|
||||
* @param aContent an nsGenericHTMLElement* pointing to the form control
|
||||
* @param aControl an nsIFormControl* pointing to the form control
|
||||
* @return false if RestoreState() was not called, the return
|
||||
* value of RestoreState() otherwise.
|
||||
*/
|
||||
static bool RestoreFormControlState(nsGenericHTMLElement* aContent,
|
||||
nsIFormControl* aControl);
|
||||
|
||||
/**
|
||||
* Get the presentation context for this content node.
|
||||
* @return the presentation context
|
||||
|
@ -1235,6 +1202,52 @@ protected:
|
|||
mozilla::dom::HTMLFieldSetElement* mFieldSet;
|
||||
};
|
||||
|
||||
class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement
|
||||
{
|
||||
public:
|
||||
nsGenericHTMLFormElementWithState(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
||||
/**
|
||||
* Get the presentation state for a piece of content, or create it if it does
|
||||
* not exist. Generally used by SaveState().
|
||||
*/
|
||||
nsPresState* GetPrimaryPresState();
|
||||
|
||||
/**
|
||||
* Get the layout history object for a particular piece of content.
|
||||
*
|
||||
* @param aRead if true, won't return a layout history state if the
|
||||
* layout history state is empty.
|
||||
* @return the history state object
|
||||
*/
|
||||
already_AddRefed<nsILayoutHistoryState>
|
||||
GetLayoutHistory(bool aRead);
|
||||
|
||||
/**
|
||||
* Restore the state for a form control. Ends up calling
|
||||
* nsIFormControl::RestoreState().
|
||||
*
|
||||
* @return false if RestoreState() was not called, the return
|
||||
* value of RestoreState() otherwise.
|
||||
*/
|
||||
bool RestoreFormControlState();
|
||||
|
||||
/**
|
||||
* Called when we have been cloned and adopted, and the information of the
|
||||
* node has been changed.
|
||||
*/
|
||||
virtual void NodeInfoChanged(nsINodeInfo* aOldNodeInfo) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
/* 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
|
||||
GenerateStateKey has been used */
|
||||
nsCString mStateKey;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
|
|
@ -66,6 +66,7 @@ MOCHITEST_FILES = \
|
|||
test_input_color_picker_update.html \
|
||||
test_input_color_picker_popup.html \
|
||||
test_input_color_input_change_events.html \
|
||||
test_restore_form_elements.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=737851
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Test for Bug 737851</title>
|
||||
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=737851">Mozilla Bug 737851</a>
|
||||
|
||||
<p id="display"></p>
|
||||
|
||||
|
||||
<div id="content">
|
||||
|
||||
<iframe id="frame" width="800px" height="600px" src='data:text/html,
|
||||
<html>
|
||||
<body style="display:none;">
|
||||
|
||||
<h3>Checking persistence of inputs through js inserts and moves</h3>
|
||||
<div id="test">
|
||||
<input id="a"/>
|
||||
<input id="b"/>
|
||||
<form id="form1">
|
||||
<input id="c"/>
|
||||
<input id="d"/>
|
||||
</form>
|
||||
<form id="form2">
|
||||
<input id="radio1" type="radio" name="radio"/>
|
||||
<input type="radio" name="radio"/>
|
||||
<input type="radio" name="radio"/>
|
||||
<input type="radio" name="radio"/>
|
||||
</form>
|
||||
<input id="e"/>
|
||||
</div>
|
||||
|
||||
<h3>Bug 728798: checking persistence of inputs when forward-using @form</h3>
|
||||
<div>
|
||||
<input id="728798-a" form="728798-form" name="a"/>
|
||||
<form id="728798-form">
|
||||
<input id="728798-b" form="728798-form" name="b"/>
|
||||
<input id="728798-c" name="c"/>
|
||||
</form>
|
||||
<input id="728798-d" form="728798-form" name="d"/>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
'></iframe>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
|
||||
var frameElement = document.getElementById("frame");
|
||||
var frame = frameElement.contentWindow;
|
||||
|
||||
|
||||
/* -- Main test run -- */
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
shuffle();
|
||||
fill();
|
||||
frameElement.addEventListener("load", function() {
|
||||
shuffle();
|
||||
checkAllFields();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
frame.location.reload();
|
||||
})
|
||||
|
||||
|
||||
/* -- Input fields js changes and moves -- */
|
||||
|
||||
function shuffle() {
|
||||
var framedoc = frame.document;
|
||||
|
||||
// Insert a button (toplevel)
|
||||
var btn = framedoc.createElement("button");
|
||||
var testdiv = framedoc.getElementById("test");
|
||||
testdiv.insertBefore(btn, framedoc.getElementById("b"));
|
||||
|
||||
// Insert a dynamically generated input (in a form)
|
||||
var newInput = framedoc.createElement("input");
|
||||
newInput.setAttribute("id","c0");
|
||||
var form1 = framedoc.getElementById("form1");
|
||||
form1.insertBefore(newInput, form1.firstChild);
|
||||
|
||||
// Move an input around
|
||||
var inputD = framedoc.getElementById("d");
|
||||
var form2 = framedoc.getElementById("form2");
|
||||
form2.insertBefore(inputD, form2.firstChild)
|
||||
|
||||
// Clone an existing input
|
||||
var inputE2 = framedoc.getElementById("e").cloneNode();
|
||||
inputE2.setAttribute("id","e2");
|
||||
testdiv.appendChild(inputE2);
|
||||
}
|
||||
|
||||
|
||||
/* -- Input fields fill & check -- */
|
||||
|
||||
/* Values entered in the input fields (by id) */
|
||||
|
||||
var fieldValues = {
|
||||
'a':'simple input',
|
||||
'b':'moved by inserting a button before (no form)',
|
||||
'c0':'dynamically generated input',
|
||||
'c':'moved by inserting an input before (in a form)',
|
||||
'd':'moved from a form to another',
|
||||
'e':'the original',
|
||||
'e2':'the clone',
|
||||
'728798-a':'before the form',
|
||||
'728798-b':'from within the form',
|
||||
'728798-c':'no form attribute in the form',
|
||||
'728798-d':'after the form'
|
||||
}
|
||||
|
||||
/* Fields for which the input is changed, and corresponding value
|
||||
(clone and creation, same behaviour as webkit) */
|
||||
|
||||
var changedFields = {
|
||||
// dynamically generated input field not preserved
|
||||
'c0':'',
|
||||
// cloned input field is restored with the value of the original
|
||||
'e2':fieldValues.e
|
||||
}
|
||||
|
||||
/* Simulate user input by entering the values */
|
||||
|
||||
function fill() {
|
||||
for (id in fieldValues) {
|
||||
frame.document.getElementById(id).value = fieldValues[id];
|
||||
}
|
||||
// an input is inserted before the radios (that may move the selected one by 1)
|
||||
frame.document.getElementById('radio1').checked = true;
|
||||
}
|
||||
|
||||
/* Check that all the fields are as they have been entered */
|
||||
|
||||
function checkAllFields() {
|
||||
|
||||
for (id in fieldValues) {
|
||||
var fieldValue = frame.document.getElementById(id).value;
|
||||
if (changedFields[id] === undefined) {
|
||||
is(fieldValue, fieldValues[id],
|
||||
"Field "+id+" should be restored after reload");
|
||||
} else {
|
||||
is(fieldValue, changedFields[id],
|
||||
"Field "+id+" normally gets a different value after reload");
|
||||
}
|
||||
}
|
||||
|
||||
ok(frame.document.getElementById('radio1').checked,
|
||||
"Radio button radio1 should be restored after reload")
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче