Bug 566879 - Make innerHTML-inserted from controls not restore their state from history. r=Olli.Pettay.

This commit is contained in:
Henri Sivonen 2010-06-09 09:45:32 +03:00
Родитель 0573fefc2e
Коммит 792c8ee52a
6 изменённых файлов: 85 добавлений и 4 удалений

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

@ -109,6 +109,7 @@
#include "mozAutoDocUpdate.h"
#include "nsHTMLFormElement.h"
#include "nsContentCreatorFunctions.h"
#include "nsTextEditRules.h"
@ -133,6 +134,7 @@ static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
#define BF_IN_INTERNAL_ACTIVATE 8
#define BF_CHECKED_IS_TOGGLED 9
#define BF_INDETERMINATE 10
#define BF_INHIBIT_RESTORATION 11
#define GET_BOOLBIT(bitfield, field) (((bitfield) & (0x01 << (field))) \
? PR_TRUE : PR_FALSE)
@ -554,6 +556,8 @@ nsHTMLInputElement::nsHTMLInputElement(nsINodeInfo *aNodeInfo,
mBitField(0)
{
SET_BOOLBIT(mBitField, BF_PARSER_CREATING, aFromParser);
SET_BOOLBIT(mBitField, BF_INHIBIT_RESTORATION,
aFromParser & NS_FROM_PARSER_FRAGMENT);
mInputData.mState = new nsTextEditorState(this);
NS_ADDREF(mInputData.mState);
}
@ -2965,7 +2969,10 @@ nsHTMLInputElement::DoneCreatingElement()
// Restore state as needed. Note that disabled state applies to all control
// types.
//
PRBool restoredCheckedState = RestoreFormControlState(this, this);
PRBool restoredCheckedState =
GET_BOOLBIT(mBitField, BF_INHIBIT_RESTORATION) ?
PR_FALSE :
RestoreFormControlState(this, this);
//
// If restore does not occur, we initialize .checked using the CHECKED

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

@ -47,6 +47,7 @@
#include "nsIForm.h"
#include "nsFormSubmission.h"
#include "nsIFormProcessor.h"
#include "nsContentCreatorFunctions.h"
#include "nsIDOMHTMLOptGroupElement.h"
#include "nsIOptionElement.h"
@ -140,6 +141,7 @@ nsHTMLSelectElement::nsHTMLSelectElement(nsINodeInfo *aNodeInfo,
mIsDoneAddingChildren(!aFromParser),
mDisabledChanged(PR_FALSE),
mMutating(PR_FALSE),
mInhibitStateRestoration(!!(aFromParser & NS_FROM_PARSER_FRAGMENT)),
mNonOptionChildren(0),
mOptGroupCount(0),
mSelectedIndex(-1)
@ -1353,7 +1355,9 @@ nsHTMLSelectElement::DoneAddingChildren(PRBool aHaveNotified)
}
// Restore state
RestoreFormControlState(this, this);
if (!mInhibitStateRestoration) {
RestoreFormControlState(this, this);
}
// Now that we're done, select something (if it's a single select something
// must be selected)

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

@ -491,6 +491,10 @@ protected:
* Used by nsSafeOptionListMutation.
*/
PRPackedBool mMutating;
/**
* True if DoneAddingChildren will get called but shouldn't restore state.
*/
PRPackedBool mInhibitStateRestoration;
/** The number of non-options as children of the select */
PRUint32 mNonOptionChildren;
/** The number of optgroups anywhere under the select */

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

@ -76,6 +76,7 @@
#include "nsDOMError.h"
#include "mozAutoDocUpdate.h"
#include "nsISupportsPrimitives.h"
#include "nsContentCreatorFunctions.h"
#include "nsTextEditorState.h"
@ -204,6 +205,8 @@ protected:
/** Whether or not we are done adding children (always PR_TRUE if not
created by a parser */
PRPackedBool mDoneAddingChildren;
/** Whether state restoration should be inhibited in DoneAddingChildren. */
PRPackedBool mInhibitStateRestoration;
/** Whether our disabled state has changed from the default **/
PRPackedBool mDisabledChanged;
/** The state of the text editor (selection controller and the editor) **/
@ -249,6 +252,7 @@ nsHTMLTextAreaElement::nsHTMLTextAreaElement(nsINodeInfo *aNodeInfo,
mValueChanged(PR_FALSE),
mHandlingSelect(PR_FALSE),
mDoneAddingChildren(!aFromParser),
mInhibitStateRestoration(!!(aFromParser & NS_FROM_PARSER_FRAGMENT)),
mDisabledChanged(PR_FALSE),
mState(new nsTextEditorState(this))
{
@ -676,8 +680,9 @@ nsHTMLTextAreaElement::DoneAddingChildren(PRBool aHaveNotified)
// sneak some text in without calling AppendChildTo.
Reset();
}
RestoreFormControlState(this, this);
if (!mInhibitStateRestoration) {
RestoreFormControlState(this, this);
}
}
mDoneAddingChildren = PR_TRUE;

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

@ -59,6 +59,7 @@ _TEST_FILES = parser_datreader.js \
test_bug460437.xhtml \
test_bug502091.html \
bug_502091_iframe.html \
test_bug566879.html \
test_compatmode.html \
invalidchar.xml \
$(NULL)

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

@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=566879
-->
<head>
<title>Test for Bug 566879</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload='runTest();'>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=566879">Mozilla Bug 566879</a>
<p id="display"></p>
<div id="content" style="display: none">
<form>
<input type=text id=textfield name=textfield>
<input type=checkbox id=checkbox name=checkbox>
<input type=radio id=radio1 name=radio>
<input type=radio id=radio2 name=radio>
<textarea name=textarea id=textarea></textarea>
<select name=select id=select>
<option value=foo>Foo</option>
<option value=bar selected>Bar</option>
</select>
</form>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
function runTest() {
initialState = document.getElementById('content').innerHTML;
document.getElementById('textfield').value = "foo";
document.getElementById('checkbox').checked = true;
document.getElementById('radio2').checked = true;
document.getElementById('textarea').value = "foo";
document.getElementById('select').value = "foo";
setTimeout(continuation1, 1);
}
function continuation1() {
document.getElementById('content').innerHTML = initialState;
setTimeout(continuation2, 1);
}
function continuation2() {
is(document.getElementById('textfield').value, "", "The text field should have gone back to its initial state.");
ok(!document.getElementById('checkbox').checked, "The checkbox should have gone back to its initial state.");
ok(!document.getElementById('radio2').checked, "The second radio button should have gone back to its initial state.");
is(document.getElementById('textarea').value, "", "The text area should have gone back to its initial state.");
is(document.getElementById('select').value, "bar", "The select should have gone back to its initial state.");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>