Bug 610415 - Make :-moz-ui-invalid and :-moz-ui-valid not applying when the form element has novalidate attribute set. r+a=sicking
This commit is contained in:
@@ -708,8 +708,17 @@ nsHTMLButtonElement::IntrinsicState() const
|
||||
nsEventStates state = nsGenericHTMLFormElement::IntrinsicState();
|
||||
|
||||
if (IsCandidateForConstraintValidation()) {
|
||||
state |= IsValid() ? NS_EVENT_STATE_VALID | NS_EVENT_STATE_MOZ_UI_VALID
|
||||
: NS_EVENT_STATE_INVALID | NS_EVENT_STATE_MOZ_UI_INVALID;
|
||||
if (IsValid()) {
|
||||
state |= NS_EVENT_STATE_VALID;
|
||||
if (!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
state |= NS_EVENT_STATE_MOZ_UI_VALID;
|
||||
}
|
||||
} else {
|
||||
state |= NS_EVENT_STATE_INVALID;
|
||||
if (!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
state |= NS_EVENT_STATE_MOZ_UI_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mForm && !mForm->GetValidity() && IsSubmitControl()) {
|
||||
|
||||
@@ -376,6 +376,36 @@ nsHTMLFormElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFormElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aName == nsGkAtoms::novalidate && aNameSpaceID == kNameSpaceID_None) {
|
||||
// Update all form elements states because they might be [no longer]
|
||||
// affected by :-moz-ui-valid or :-moz-ui-invalid.
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
|
||||
for (PRUint32 i = 0, length = mControls->mElements.Length();
|
||||
i < length; ++i) {
|
||||
doc->ContentStatesChanged(mControls->mElements[i], nsnull,
|
||||
NS_EVENT_STATE_MOZ_UI_VALID |
|
||||
NS_EVENT_STATE_MOZ_UI_INVALID);
|
||||
}
|
||||
|
||||
for (PRUint32 i = 0, length = mControls->mNotInElements.Length();
|
||||
i < length; ++i) {
|
||||
doc->ContentStatesChanged(mControls->mNotInElements[i], nsnull,
|
||||
NS_EVENT_STATE_MOZ_UI_VALID |
|
||||
NS_EVENT_STATE_MOZ_UI_INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, aNotify);
|
||||
}
|
||||
|
||||
NS_IMPL_STRING_ATTR(nsHTMLFormElement, AcceptCharset, acceptcharset)
|
||||
NS_IMPL_ACTION_ATTR(nsHTMLFormElement, Action, action)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLFormElement, Autocomplete, autocomplete,
|
||||
|
||||
@@ -172,6 +172,8 @@ public:
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
/**
|
||||
* Forget all information about the current submission (and the fact that we
|
||||
|
||||
@@ -560,6 +560,8 @@ protected:
|
||||
"element is valid!");
|
||||
|
||||
/**
|
||||
* Never show the invalid UI if the form has the novalidate attribute set.
|
||||
*
|
||||
* 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;
|
||||
@@ -567,8 +569,16 @@ protected:
|
||||
*
|
||||
* Otherwise, show the invalid UI if the element's value has been changed.
|
||||
*/
|
||||
if ((mForm && mForm->HasEverTriedInvalidSubmit()) ||
|
||||
GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
|
||||
if (mForm) {
|
||||
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
return false;
|
||||
}
|
||||
if (mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -593,9 +603,14 @@ protected:
|
||||
* @note This doesn't take into account the validity of the element.
|
||||
*/
|
||||
bool ShouldShowValidUI() const {
|
||||
if (mForm && mForm->HasEverTriedInvalidSubmit()) {
|
||||
if (mForm) {
|
||||
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
return false;
|
||||
}
|
||||
if (mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
switch (GetValueMode()) {
|
||||
case VALUE_MODE_DEFAULT:
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "nsIConstraintValidation.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
|
||||
|
||||
class nsHTMLOutputElement : public nsGenericHTMLFormElement,
|
||||
@@ -206,8 +207,17 @@ nsHTMLOutputElement::IntrinsicState() const
|
||||
|
||||
// We don't have to call IsCandidateForConstraintValidation()
|
||||
// because <output> can't be barred from constraint validation.
|
||||
states |= IsValid() ? NS_EVENT_STATE_VALID | NS_EVENT_STATE_MOZ_UI_VALID
|
||||
: NS_EVENT_STATE_INVALID | NS_EVENT_STATE_MOZ_UI_INVALID;
|
||||
if (IsValid()) {
|
||||
states |= NS_EVENT_STATE_VALID;
|
||||
if (!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
states |= NS_EVENT_STATE_MOZ_UI_VALID;
|
||||
}
|
||||
} else {
|
||||
states |= NS_EVENT_STATE_INVALID;
|
||||
if (!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
states |= NS_EVENT_STATE_MOZ_UI_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
@@ -527,15 +527,28 @@ protected:
|
||||
"element is valid!");
|
||||
|
||||
/**
|
||||
* Never show the invalid UI if the form has the novalidate attribute set.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
return mSelectionHasChanged ||
|
||||
(mForm && mForm->HasEverTriedInvalidSubmit()) ||
|
||||
GetValidityState(VALIDITY_STATE_CUSTOM_ERROR);
|
||||
if (mForm) {
|
||||
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
return false;
|
||||
}
|
||||
if (mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return mSelectionHasChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -545,9 +558,18 @@ protected:
|
||||
* @note This doesn't take into account the validity of the element.
|
||||
*/
|
||||
bool ShouldShowValidUI() const {
|
||||
return mSelectionHasChanged ||
|
||||
(mForm && mForm->HasEverTriedInvalidSubmit());
|
||||
if (mForm) {
|
||||
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
return false;
|
||||
}
|
||||
if (mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return mSelectionHasChanged;
|
||||
}
|
||||
|
||||
/** The options[] array */
|
||||
nsRefPtr<nsHTMLOptionCollection> mOptions;
|
||||
/** false if the parser is in the middle of adding children. */
|
||||
|
||||
@@ -287,6 +287,8 @@ protected:
|
||||
"element is valid!");
|
||||
|
||||
/**
|
||||
* Never show the invalid UI if the form has the novalidate attribute set.
|
||||
*
|
||||
* 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;
|
||||
@@ -294,8 +296,20 @@ protected:
|
||||
* Otherwise, show the invalid UI if the element's value has been changed.
|
||||
*/
|
||||
|
||||
return (mForm && mForm->HasEverTriedInvalidSubmit()) ||
|
||||
mValueChanged || GetValidityState(VALIDITY_STATE_CUSTOM_ERROR);
|
||||
if (mForm) {
|
||||
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
return false;
|
||||
}
|
||||
if (mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return mValueChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,7 +319,16 @@ protected:
|
||||
* @note This doesn't take into account the validity of the element.
|
||||
*/
|
||||
bool ShouldShowValidUI() const {
|
||||
return (mForm && mForm->HasEverTriedInvalidSubmit()) || mValueChanged;
|
||||
if (mForm) {
|
||||
if (mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) {
|
||||
return false;
|
||||
}
|
||||
if (mForm->HasEverTriedInvalidSubmit()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return mValueChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
10
layout/reftests/css-ui-invalid/button/button-novalidate.html
Normal file
10
layout/reftests/css-ui-invalid/button/button-novalidate.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('b').setCustomValidity('foo');
|
||||
document.documentElement.className = '';">
|
||||
<form novalidate>
|
||||
<button id='b' class='notinvalid'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -10,3 +10,4 @@
|
||||
== button-disabled-fieldset-1.html button-fieldset-ref.html
|
||||
== button-disabled-fieldset-2.html button-fieldset-ref.html
|
||||
== button-fieldset-legend.html button-fieldset-legend-ref.html
|
||||
== button-novalidate.html button-ref.html
|
||||
|
||||
11
layout/reftests/css-ui-invalid/input/input-novalidate.html
Normal file
11
layout/reftests/css-ui-invalid/input/input-novalidate.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- When the form has @novalidate, :-moz-ui-invalid doesn't apply. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value = '';
|
||||
document.documentElement.className = '';">
|
||||
<form novalidate>
|
||||
<input id='i' class='notinvalid' required>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -41,4 +41,5 @@
|
||||
== input-radio-dyn-valid-2.html success-ref.html
|
||||
== input-radio-nogroup-required-valid.html success-ref.html
|
||||
== input-radio-nogroup-required-invalid.html success-ref.html
|
||||
== input-novalidate.html input-ref.html
|
||||
# input type='hidden' shouldn't show
|
||||
|
||||
10
layout/reftests/css-ui-invalid/output/output-novalidate.html
Normal file
10
layout/reftests/css-ui-invalid/output/output-novalidate.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('o').setCustomValidity('foo');
|
||||
document.documentElement.className = '';">
|
||||
<form novalidate>
|
||||
<output id='o' class='notinvalid'>foo</output>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,2 +1,3 @@
|
||||
== output-valid.html output-ref.html
|
||||
== output-invalid.html output-ref.html
|
||||
== output-novalidate.html output-ref.html
|
||||
|
||||
@@ -15,3 +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
|
||||
|
||||
10
layout/reftests/css-ui-invalid/select/select-novalidate.html
Normal file
10
layout/reftests/css-ui-invalid/select/select-novalidate.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('s').setCustomValidity('foo');
|
||||
document.documentElement.className = '';">
|
||||
<form novalidate>
|
||||
<select id='s' class='notinvalid'></select>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,3 +15,4 @@
|
||||
== textarea-required-invalid-changed.html textarea-ref.html
|
||||
== textarea-disabled-fieldset-1.html textarea-fieldset-ref.html
|
||||
== textarea-disabled-fieldset-2.html textarea-fieldset-ref.html
|
||||
== textarea-novalidate.html textarea-ref.html
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('t').value = '';
|
||||
document.documentElement.className = '';">
|
||||
<form novalidate>
|
||||
<textarea id='t' required class='notinvalid'></textarea>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<form novalidate>
|
||||
<button class='notvalid'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -10,3 +10,4 @@
|
||||
== button-disabled-fieldset-1.html button-fieldset-ref.html
|
||||
== button-disabled-fieldset-2.html button-fieldset-ref.html
|
||||
== button-fieldset-legend.html button-fieldset-legend-ref.html
|
||||
== button-novalidate.html button-ref.html
|
||||
|
||||
11
layout/reftests/css-ui-valid/input/input-novalidate.html
Normal file
11
layout/reftests/css-ui-valid/input/input-novalidate.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- When the form has @novalidate, :-moz-ui-invalid doesn't apply. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').value = 'foo';
|
||||
document.documentElement.className = '';">
|
||||
<form novalidate>
|
||||
<input id='i' class='notvalid' required>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -40,4 +40,5 @@
|
||||
== input-radio-dyn-valid-2.html success-ref.html
|
||||
== input-radio-nogroup-required-valid.html success-ref.html
|
||||
== input-radio-nogroup-required-invalid.html success-ref.html
|
||||
== input-novalidate.html input-withtext-ref.html
|
||||
# input type='hidden' shouldn't show
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body>
|
||||
<form novalidate>
|
||||
<output class='notvalid'>foo</output>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,2 +1,3 @@
|
||||
== output-valid.html output-ref.html
|
||||
== output-invalid.html output-ref.html
|
||||
== output-novalidate.html output-ref.html
|
||||
|
||||
@@ -15,3 +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-required-ref.html
|
||||
|
||||
12
layout/reftests/css-ui-valid/select/select-novalidate.html
Normal file
12
layout/reftests/css-ui-valid/select/select-novalidate.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('s').selectedIndex = 0;
|
||||
document.documentElement.className = '';">
|
||||
<form novalidate>
|
||||
<select id='s' class='notvalid'>
|
||||
<option>foo</option>
|
||||
</select>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -17,3 +17,4 @@
|
||||
== textarea-disabled-fieldset-1.html textarea-fieldset-ref.html
|
||||
== textarea-disabled-fieldset-2.html textarea-fieldset-ref.html
|
||||
== textarea-fieldset-legend.html textarea-fieldset-legend-ref.html
|
||||
== textarea-novalidate.html textarea-withtext-ref.html
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('t').value = 'foo';
|
||||
document.documentElement.className = '';">
|
||||
<form novalidate>
|
||||
<textarea id='t' required class='notvalid'></textarea>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user