Bug 737851 - Generate form state key at page load instead of page unload. r=bz

This commit is contained in:
Mina Almasry 2013-08-01 21:21:31 -04:00
Родитель 341f7bc310
Коммит a5fb99687b
12 изменённых файлов: 464 добавлений и 224 удалений

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

@ -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 &lt;select&gt;
*/
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>