Bug 590353 - Do not try to reset the default value if the element value isn't different from the value attribute. r=smaug a2.0=blocking

This commit is contained in:
Mounir Lamouri 2010-09-08 19:42:35 +02:00
parent 9454ae60b8
commit ddfdded1b7
5 changed files with 164 additions and 53 deletions

View File

@ -817,10 +817,12 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
}
// If @value is changed and BF_VALUE_CHANGED is false, @value is the value
// of the element so we call |Reset| which is getting the default value and
// sets it to the current value.
// of the element so, if the value of the element is different than @value,
// we have to re-set it. This is only the case when GetValueMode() returns
// VALUE_MODE_VALUE.
if (aName == nsGkAtoms::value &&
!GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)) {
!GET_BOOLBIT(mBitField, BF_VALUE_CHANGED) &&
GetValueMode() == VALUE_MODE_VALUE) {
SetDefaultValueAsValue();
}
@ -2873,65 +2875,39 @@ FireEventForAccessibility(nsIDOMHTMLInputElement* aTarget,
nsresult
nsHTMLInputElement::SetDefaultValueAsValue()
{
switch (mType) {
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
{
PRBool resetVal;
GetDefaultChecked(&resetVal);
return DoSetChecked(resetVal, PR_TRUE, PR_FALSE);
}
case NS_FORM_INPUT_SEARCH:
case NS_FORM_INPUT_PASSWORD:
case NS_FORM_INPUT_EMAIL:
case NS_FORM_INPUT_TEXT:
case NS_FORM_INPUT_TEL:
case NS_FORM_INPUT_URL:
{
nsAutoString resetVal;
GetDefaultValue(resetVal);
// SetValueInternal is going to sanitize the value.
return SetValueInternal(resetVal, PR_FALSE, PR_FALSE);
}
case NS_FORM_INPUT_FILE:
{
// Resetting it to blank should not perform security check
ClearFiles();
break;
}
// Value is the same as defaultValue for hidden inputs
case NS_FORM_INPUT_HIDDEN:
default:
break;
}
NS_ASSERTION(GetValueMode() == VALUE_MODE_VALUE,
"GetValueMode() should return VALUE_MODE_VALUE!");
return NS_OK;
// The element has a content attribute value different from it's value when
// it's in the value mode value.
nsAutoString resetVal;
GetDefaultValue(resetVal);
// SetValueInternal is going to sanitize the value.
return SetValueInternal(resetVal, PR_FALSE, PR_FALSE);
}
NS_IMETHODIMP
nsHTMLInputElement::Reset()
{
nsresult rv = SetDefaultValueAsValue();
NS_ENSURE_SUCCESS(rv, rv);
// We should be able to reset all dirty flags regardless of the type.
SetCheckedChanged(PR_FALSE);
SetValueChanged(PR_FALSE);
switch (mType) {
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
SetCheckedChanged(PR_FALSE);
break;
case NS_FORM_INPUT_SEARCH:
case NS_FORM_INPUT_PASSWORD:
case NS_FORM_INPUT_EMAIL:
case NS_FORM_INPUT_TEXT:
case NS_FORM_INPUT_TEL:
case NS_FORM_INPUT_URL:
SetValueChanged(PR_FALSE);
break;
switch (GetValueMode()) {
case VALUE_MODE_VALUE:
return SetDefaultValueAsValue();
case VALUE_MODE_DEFAULT_ON:
PRBool resetVal;
GetDefaultChecked(&resetVal);
return DoSetChecked(resetVal, PR_TRUE, PR_FALSE);
case VALUE_MODE_FILENAME:
ClearFiles();
return NS_OK;
case VALUE_MODE_DEFAULT:
default:
break;
return NS_OK;
}
return NS_OK;
}
NS_IMETHODIMP

View File

@ -512,6 +512,8 @@ protected:
/**
* Set the current default value to the value of the input element.
* @note You should not call this method if GetValueMode() doesn't return
* VALUE_MODE_VALUE.
*/
nsresult SetDefaultValueAsValue();

View File

@ -209,6 +209,8 @@ _TEST_FILES = \
test_bug588683-2.html \
test_bug588683-3.html \
test_bug588683-4.html \
test_bug590353-1.html \
test_bug590353-2.html \
$(NULL)
libs:: $(_TEST_FILES)

View File

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=590353
-->
<head>
<title>Test for Bug 590353</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<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=590353">Mozilla Bug 590353</a>
<p id="display"></p>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 590353 **/
var testData = ['checkbox', 'radio'];
for each(var data in testData) {
var e = document.createElement('input');
e.type = data;
e.checked = true;
e.value = "foo";
is(e.value, "foo", "foo should be the new " + data + "value");
is(e.getAttribute('value'), "foo", "foo should be the new " + data +
" value attribute value");
ok(e.checked, data + " should still be checked");
}
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,94 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=590353
-->
<head>
<title>Test for Bug 590353</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<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=590353">Mozilla Bug 590353</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 590353 **/
var testData = [
[ "text", "foo", "" ],
[ "email", "foo@bar.com", "" ],
[ "url", "http:///foo.com", "" ],
[ "tel", "555 555 555 555", "" ],
[ "search", "foo", "" ],
[ "password", "secret", "" ],
[ "hidden", "foo", "foo" ],
[ "button", "foo", "foo" ],
[ "reset", "foo", "foo" ],
[ "submit", "foo", "foo" ],
[ "checkbox", true, false ],
[ "radio", true, false ],
[ "file", "590353_file", "" ],
];
function createFileWithData(fileName, fileData) {
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
testFile.append(fileName);
var outStream = Components.
classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();
return testFile;
}
var content = document.getElementById('content');
var form = document.createElement('form');
content.appendChild(form);
for each (var data in testData) {
var e = document.createElement('input');
e.type = data[0];
if (data[0] == 'checkbox' || data[0] == 'radio') {
e.checked = data[1];
} else if (data[0] == 'file') {
// Need privileges to set a filename with .value and create a file.
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var file = createFileWithData(data[1], "file content");
e.value = file.path;
} else {
e.value = data[1];
}
form.appendChild(e);
}
form.reset();
var size = form.elements.length;
for (var i=0; i<size; ++i) {
var e = form.elements[i];
if (e.type == 'radio' || e.type == 'checkbox') {
is(e.checked, testData[i][2],
"the element checked value should be " + testData[i][2]);
} else {
is(e.value, testData[i][2],
"the element value should be " + testData[i][2]);
}
}
</script>
</pre>
</body>
</html>