Bug 622558 - When .setCustomValidity() is used, :-moz-ui-invalid should always apply. r+a=sicking

This commit is contained in:
Mounir Lamouri 2011-01-20 12:05:29 +01:00
Родитель c9ef6ccde2
Коммит c78e16b293
9 изменённых файлов: 142 добавлений и 153 удалений

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

@ -3310,8 +3310,9 @@ nsHTMLInputElement::IntrinsicState() const
} else {
state |= NS_EVENT_STATE_INVALID;
if (GET_BOOLBIT(mBitField, BF_CAN_SHOW_INVALID_UI) &&
ShouldShowInvalidUI()) {
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
(GET_BOOLBIT(mBitField, BF_CAN_SHOW_INVALID_UI) &&
ShouldShowValidityUI())) {
state |= NS_EVENT_STATE_MOZ_UI_INVALID;
}
}
@ -3322,10 +3323,10 @@ nsHTMLInputElement::IntrinsicState() const
// 2. The element is either valid or isn't allowed to have
// :-moz-ui-invalid applying ;
// 3. The rules to have :-moz-ui-valid applying are fulfilled
// (see ShouldShowValidUI()).
if (GET_BOOLBIT(mBitField, BF_CAN_SHOW_VALID_UI) &&
(IsValid() || !GET_BOOLBIT(mBitField, BF_CAN_SHOW_INVALID_UI)) &&
ShouldShowValidUI()) {
// (see ShouldShowValidityUI()).
if (GET_BOOLBIT(mBitField, BF_CAN_SHOW_VALID_UI) && ShouldShowValidityUI() &&
(IsValid() || (!state.HasState(NS_EVENT_STATE_MOZ_UI_INVALID) &&
!GET_BOOLBIT(mBitField, BF_CAN_SHOW_INVALID_UI)))) {
state |= NS_EVENT_STATE_MOZ_UI_VALID;
}
}
@ -4585,11 +4586,11 @@ nsHTMLInputElement::UpdateValidityUIBits(bool aIsFocused)
// If the invalid UI is shown, we should show it while focusing (and
// update). Otherwise, we should not.
SET_BOOLBIT(mBitField, BF_CAN_SHOW_INVALID_UI,
!IsValid() && ShouldShowInvalidUI());
!IsValid() && ShouldShowValidityUI());
// If neither invalid UI nor valid UI is shown, we shouldn't show the valid
// UI while typing.
SET_BOOLBIT(mBitField, BF_CAN_SHOW_VALID_UI, ShouldShowValidUI());
SET_BOOLBIT(mBitField, BF_CAN_SHOW_VALID_UI, ShouldShowValidityUI());
} else {
SET_BOOLBIT(mBitField, BF_CAN_SHOW_INVALID_UI, PR_TRUE);
SET_BOOLBIT(mBitField, BF_CAN_SHOW_VALID_UI, PR_TRUE);

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

@ -560,25 +560,18 @@ protected:
}
/**
* Return if an invalid element should have a specific UI for being invalid
* (with :-moz-ui-invalid pseudo-class.
* Return if an element should have a specific validity UI
* (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
*
* @return Whether the invalid elemnet should have a UI for being invalid.
* @note The caller has to be sure the element is invalid before calling.
* @return Whether the elemnet should have a validity UI.
*/
bool ShouldShowInvalidUI() const {
NS_ASSERTION(!IsValid(), "You should not call ShouldShowInvalidUI if the "
"element is valid!");
bool ShouldShowValidityUI() const {
/**
* Never show the invalid UI if the form has the novalidate attribute set.
* Never show the validity UI if the form has the novalidate attribute set.
* Always show the validity UI if the form has already tried to be submitted
* but was invalid.
*
* Always show the invalid UI if:
* - the form has already tried to be submitted but was invalid;
* - the element is suffering from a custom error;
* - the element has had its value changed
*
* Otherwise, show the invalid UI if the element's value has been changed.
* Otherwise, show the validity UI if the element's value has been changed.
*/
if (mForm) {
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
@ -589,40 +582,6 @@ protected:
}
}
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
return true;
}
switch (GetValueMode()) {
case VALUE_MODE_DEFAULT:
return true;
case VALUE_MODE_DEFAULT_ON:
return GetCheckedChanged();
case VALUE_MODE_VALUE:
case VALUE_MODE_FILENAME:
return GetValueChanged();
default:
NS_NOTREACHED("We should not be there: there are no other modes.");
return false;
}
}
/**
* Return whether an element should show the valid UI.
*
* @return Whether the valid UI should be shown.
* @note This doesn't take into account the validity of the element.
*/
bool ShouldShowValidUI() const {
if (mForm) {
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
return false;
}
if (mForm->HasEverTriedInvalidSubmit()) {
return true;
}
}
switch (GetValueMode()) {
case VALUE_MODE_DEFAULT:
return true;

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

@ -1572,11 +1572,11 @@ nsHTMLSelectElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
if (aVisitor.mEvent->message == NS_FOCUS_CONTENT) {
// If the invalid UI is shown, we should show it while focused and
// update the invalid/valid UI.
mCanShowInvalidUI = !IsValid() && ShouldShowInvalidUI();
mCanShowInvalidUI = !IsValid() && ShouldShowValidityUI();
// If neither invalid UI nor valid UI is shown, we shouldn't show the valid
// UI while focused.
mCanShowValidUI = ShouldShowValidUI();
mCanShowValidUI = ShouldShowValidityUI();
// We don't have to update NS_EVENT_STATE_MOZ_UI_INVALID nor
// NS_EVENT_STATE_MOZ_UI_VALID given that the states should not change.
@ -1606,7 +1606,8 @@ nsHTMLSelectElement::IntrinsicState() const
} else {
state |= NS_EVENT_STATE_INVALID;
if (mCanShowInvalidUI && ShouldShowInvalidUI()) {
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
(mCanShowInvalidUI && ShouldShowValidityUI())) {
state |= NS_EVENT_STATE_MOZ_UI_INVALID;
}
}
@ -1617,10 +1618,10 @@ nsHTMLSelectElement::IntrinsicState() const
// 2. The element is either valid or isn't allowed to have
// :-moz-ui-invalid applying ;
// 3. The rules to have :-moz-ui-valid applying are fulfilled
// (see ShouldShowValidUI()).
if (mCanShowValidUI &&
(IsValid() || !mCanShowInvalidUI) &&
ShouldShowValidUI()) {
// (see ShouldShowValidityUI()).
if (mCanShowValidUI && ShouldShowValidityUI() &&
(IsValid() || (state.HasState(NS_EVENT_STATE_MOZ_UI_INVALID) &&
!mCanShowInvalidUI))) {
state |= NS_EVENT_STATE_MOZ_UI_VALID;
}
}

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

@ -516,24 +516,18 @@ protected:
void SetSelectionChanged(PRBool aValue, PRBool aNotify);
/**
* Return whether an invalid element should have a specific UI for being invalid
* (with :-moz-ui-invalid pseudo-class).
* Return whether an element should have a validity UI.
* (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
*
* @return Whether the invalid element should have a UI for being invalid.
* @note The caller has to be sure the element is invalid before calling.
* @return Whether the element should have a validity UI.
*/
bool ShouldShowInvalidUI() const {
NS_ASSERTION(!IsValid(), "You should not call ShouldShowInvalidUI if the "
"element is valid!");
bool ShouldShowValidityUI() const {
/**
* Never show the invalid UI if the form has the novalidate attribute set.
* Never show the validity UI if the form has the novalidate attribute set.
* Always show the validity UI if the form has already tried to be submitted
* but was invalid.
*
* Always show the invalid UI if:
* - the form has already tried to be submitted but was invalid;
* - the element is suffering from a custom error;
*
* Otherwise, show the invalid UI if the selection has been changed.
* Otherwise, show the validity UI if the selection has been changed.
*/
if (mForm) {
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
@ -544,29 +538,6 @@ protected:
}
}
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
return true;
}
return mSelectionHasChanged;
}
/**
* Return whether an element should show the valid UI.
*
* @return Whether the valid UI should be shown.
* @note This doesn't take into account the validity of the element.
*/
bool ShouldShowValidUI() const {
if (mForm) {
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
return false;
}
if (mForm->HasEverTriedInvalidSubmit()) {
return true;
}
}
return mSelectionHasChanged;
}

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

@ -276,24 +276,18 @@ protected:
const nsAString* aValue, PRBool aNotify);
/**
* Return if an invalid element should have a specific UI for being invalid
* (with :-moz-ui-invalid pseudo-class.
* Return if an element should have a specific validity UI
* (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes).
*
* @return Whether the invalid elemnet should have a UI for being invalid.
* @note The caller has to be sure the element is invalid before calling.
* @return Whether the elemnet should have a validity UI.
*/
bool ShouldShowInvalidUI() const {
NS_ASSERTION(!IsValid(), "You should not call ShouldShowInvalidUI if the "
"element is valid!");
bool ShouldShowValidityUI() const {
/**
* Never show the invalid UI if the form has the novalidate attribute set.
* Never show the validity UI if the form has the novalidate attribute set.
* Always show the validity UI if the form has already tried to be submitted
* but was invalid.
*
* Always show the invalid UI if:
* - the form has already tried to be submitted but was invalid;
* - the element is suffering from a custom error;
*
* Otherwise, show the invalid UI if the element's value has been changed.
* Otherwise, show the validity UI if the element's value has been changed.
*/
if (mForm) {
@ -305,29 +299,6 @@ protected:
}
}
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
return true;
}
return mValueChanged;
}
/**
* Return whether an element should show the valid UI.
*
* @return Whether the valid UI should be shown.
* @note This doesn't take into account the validity of the element.
*/
bool ShouldShowValidUI() const {
if (mForm) {
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
return false;
}
if (mForm->HasEverTriedInvalidSubmit()) {
return true;
}
}
return mValueChanged;
}
@ -801,11 +772,11 @@ nsHTMLTextAreaElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
if (aVisitor.mEvent->message == NS_FOCUS_CONTENT) {
// If the invalid UI is shown, we should show it while focusing (and
// update). Otherwise, we should not.
mCanShowInvalidUI = !IsValid() && ShouldShowInvalidUI();
mCanShowInvalidUI = !IsValid() && ShouldShowValidityUI();
// If neither invalid UI nor valid UI is shown, we shouldn't show the valid
// UI while typing.
mCanShowValidUI = ShouldShowValidUI();
mCanShowValidUI = ShouldShowValidityUI();
// We don't have to update NS_EVENT_STATE_MOZ_UI_INVALID nor
// NS_EVENT_STATE_MOZ_UI_VALID given that the states should not change.
@ -1105,10 +1076,8 @@ nsHTMLTextAreaElement::IntrinsicState() const
state |= NS_EVENT_STATE_INVALID;
// NS_EVENT_STATE_MOZ_UI_INVALID always apply if the element suffers from
// VALIDITY_STATE_CUSTOM_ERROR.
// Otherwise, it applies if the value has been modified.
// NS_EVENT_STATE_MOZ_UI_INVALID always applies if the form submission has
// been tried while invalid.
if (mCanShowInvalidUI && ShouldShowInvalidUI()) {
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) ||
mCanShowInvalidUI && ShouldShowValidityUI()) {
state |= NS_EVENT_STATE_MOZ_UI_INVALID;
}
}
@ -1119,10 +1088,10 @@ nsHTMLTextAreaElement::IntrinsicState() const
// 2. The element is either valid or isn't allowed to have
// :-moz-ui-invalid applying ;
// 3. The rules to have :-moz-ui-valid applying are fulfilled
// (see ShouldShowValidUI()).
if (mCanShowValidUI &&
(IsValid() || !mCanShowInvalidUI) &&
ShouldShowValidUI()) {
// (see ShouldShowValidityUI()).
if (mCanShowValidUI && ShouldShowValidityUI() &&
(IsValid() || (state.HasState(NS_EVENT_STATE_MOZ_UI_INVALID) &&
!mCanShowInvalidUI))) {
state |= NS_EVENT_STATE_MOZ_UI_VALID;
}
}

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

@ -252,6 +252,7 @@ _TEST_FILES = \
test_bug618948.html \
test_bug623291.html \
test_bug619278.html \
test_bug622558.html \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -0,0 +1,86 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=622558
-->
<head>
<title>Test for Bug 622558</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.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=622558">Mozilla Bug 622558</a>
<p id="display"></p>
<div id="content">
<form>
<input>
<textarea></textarea>
<select><option>foo</option></select>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 622558 **/
function checkSelectors(aElement)
{
ok(aElement.mozMatchesSelector(":-moz-ui-invalid"),
":-moz-ui-invalid should match for " + aElement);
ok(!aElement.mozMatchesSelector(":-moz-ui-valid"),
":-moz-ui-valid should not match for " + aElement);
}
var input = document.getElementsByTagName('input')[0];
var textarea = document.getElementsByTagName('textarea')[0];
var select = document.getElementsByTagName('select')[0];
select.addEventListener("focus", function() {
select.removeEventListener("focus", arguments.callee, false);
SimpleTest.executeSoon(function() {
select.setCustomValidity('foo');
SimpleTest.executeSoon(function() {
checkSelectors(select);
SimpleTest.finish();
});
});
}, false);
textarea.addEventListener("focus", function() {
textarea.removeEventListener("focus", arguments.callee, false);
SimpleTest.executeSoon(function() {
textarea.setCustomValidity('foo');
SimpleTest.executeSoon(function() {
checkSelectors(textarea);
select.focus();
});
});
}, false);
input.addEventListener("focus", function() {
input.removeEventListener("focus", arguments.callee, false);
SimpleTest.executeSoon(function() {
input.setCustomValidity('foo');
SimpleTest.executeSoon(function() {
checkSelectors(input);
textarea.focus();
});
});
}, false);
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
input.focus();
});
</script>
</pre>
</body>
</html>

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

@ -15,4 +15,4 @@
== select-disabled-fieldset-1.html select-fieldset-ref.html
== select-disabled-fieldset-2.html select-fieldset-ref.html
== select-fieldset-legend.html select-fieldset-legend-ref.html
== select-novalidate.html select-ref.html
== select-novalidate.html select-required-ref.html

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

@ -1,10 +1,11 @@
<!DOCTYPE html>
<html class="reftest-wait">
<html>
<link rel='stylesheet' type='text/css' href='style.css'>
<body onload="document.getElementById('s').setCustomValidity('foo');
document.documentElement.className = '';">
<body>
<form novalidate>
<select id='s' class='notinvalid'></select>
<select required id='s' class='notinvalid'>
<option selected value="">foo</option>
</select>
</form>
</body>
</html>