зеркало из https://github.com/mozilla/gecko-dev.git
Bug 610687 - Make all the radio button group suffering from being missing instead of only radio's with the required attribute. r+a=sicking
--HG-- extra : rebase_source : 804f50ebb47feeac9328a47e86fa387fc07ab32d
This commit is contained in:
Родитель
1df3f9208d
Коммит
3807d4f866
|
@ -76,8 +76,6 @@ public:
|
|||
|
||||
NS_IMETHOD GetValidationMessage(nsAString& aValidationMessage);
|
||||
|
||||
protected:
|
||||
|
||||
enum ValidityStateType
|
||||
{
|
||||
VALIDITY_STATE_VALUE_MISSING = 0x01, // 0b00000001
|
||||
|
@ -90,6 +88,11 @@ protected:
|
|||
VALIDITY_STATE_CUSTOM_ERROR = 0x80 // 0b10000000
|
||||
};
|
||||
|
||||
void SetValidityState(ValidityStateType mState,
|
||||
PRBool mValue);
|
||||
|
||||
protected:
|
||||
|
||||
// You can't instantiate an object from that class.
|
||||
nsIConstraintValidation();
|
||||
|
||||
|
@ -101,9 +104,6 @@ protected:
|
|||
return mValidityBitField & mState;
|
||||
}
|
||||
|
||||
void SetValidityState(ValidityStateType mState,
|
||||
PRBool mValue);
|
||||
|
||||
void SetBarredFromConstraintValidation(PRBool aBarred);
|
||||
|
||||
virtual nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "nsISupports.h"
|
||||
class nsIFormControl;
|
||||
class nsIDocument;
|
||||
|
||||
// IID for the nsIRadioControl interface
|
||||
#define NS_IRADIOVISITOR_IID \
|
||||
|
@ -104,4 +105,30 @@ NS_GetRadioGetCheckedChangedVisitor(PRBool* aCheckedChanged,
|
|||
nsIRadioVisitor*
|
||||
NS_GetRadioUpdateValueMissingVisitor();
|
||||
|
||||
/**
|
||||
* This visitor will return (via aRequired) if an element of the group has the
|
||||
* required attribute set.
|
||||
*
|
||||
* @param aExcludeElement an element to exclude (for optimization purpose), can be null
|
||||
* @param aRequired whether there is a radio in the group with the required attribute [OUT]
|
||||
* @return the visitor
|
||||
*/
|
||||
nsIRadioVisitor*
|
||||
NS_GetRadioGroupRequiredVisitor(nsIFormControl* aExcludeElement,
|
||||
bool* aRequired);
|
||||
|
||||
/**
|
||||
* This visitor will update the validity states of all radio in the group and
|
||||
* call ContentStatesChanged if needed.
|
||||
*
|
||||
* @param aExcludeElement an element to exclude (for optimization purpose), can be null
|
||||
* @param aDocument the document owning the group
|
||||
* @param aNotify whether we should call ContentStatesChanged
|
||||
* @return the visitor
|
||||
*/
|
||||
nsIRadioVisitor*
|
||||
NS_SetRadioValueMissingState(nsIFormControl* aExcludeElement,
|
||||
nsIDocument* aDocument,
|
||||
bool aValidity, bool aNotify);
|
||||
|
||||
#endif // nsIRadioVisitor_h___
|
||||
|
|
|
@ -3506,14 +3506,8 @@ nsHTMLInputElement::WillRemoveFromRadioGroup()
|
|||
if (container) {
|
||||
container->SetCurrentRadioButton(name, nsnull);
|
||||
}
|
||||
|
||||
// Removing a checked radio from the group can change the validity state.
|
||||
// Let's ask other radio to update their value missing validity state.
|
||||
nsCOMPtr<nsIRadioVisitor> visitor =
|
||||
NS_GetRadioUpdateValueMissingVisitor();
|
||||
VisitGroup(visitor, PR_FALSE);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Remove this radio from its group in the container
|
||||
//
|
||||
|
@ -3526,6 +3520,9 @@ nsHTMLInputElement::WillRemoveFromRadioGroup()
|
|||
}
|
||||
gotName = PR_TRUE;
|
||||
}
|
||||
|
||||
UpdateValueMissingValidityStateForRadio(true);
|
||||
|
||||
container->RemoveFromRadioGroup(name,
|
||||
static_cast<nsIFormControl*>(this));
|
||||
}
|
||||
|
@ -3808,11 +3805,6 @@ nsHTMLInputElement::IsValueMissing()
|
|||
{
|
||||
case NS_FORM_INPUT_CHECKBOX:
|
||||
return !GetChecked();
|
||||
case NS_FORM_INPUT_RADIO:
|
||||
{
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selected = GetSelectedRadioButton();
|
||||
return !selected;
|
||||
}
|
||||
case NS_FORM_INPUT_FILE:
|
||||
{
|
||||
const nsCOMArray<nsIDOMFile>& files = GetFiles();
|
||||
|
@ -3895,9 +3887,44 @@ nsHTMLInputElement::UpdateTooLongValidityState()
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
|
||||
{
|
||||
PRBool notify = !GET_BOOLBIT(mBitField, BF_PARSER_CREATING);
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selection = GetSelectedRadioButton();
|
||||
// If there is no selection, that might mean the radio is not in a group.
|
||||
// In that case, we can look for the checked state of the radio.
|
||||
bool selected = selection ? true
|
||||
: aIgnoreSelf ? false : GetChecked();
|
||||
bool required = aIgnoreSelf ? false
|
||||
: HasAttr(kNameSpaceID_None, nsGkAtoms::required);
|
||||
bool valueMissing = false;
|
||||
|
||||
// If the current radio is required, don't check the entire group.
|
||||
if (!required) {
|
||||
nsCOMPtr<nsIRadioVisitor> visitor =
|
||||
NS_GetRadioGroupRequiredVisitor(this, &required);
|
||||
VisitGroup(visitor, notify);
|
||||
}
|
||||
|
||||
valueMissing = required && !selected;
|
||||
|
||||
SetValidityState(VALIDITY_STATE_VALUE_MISSING, valueMissing);
|
||||
|
||||
nsCOMPtr<nsIRadioVisitor> visitor =
|
||||
NS_SetRadioValueMissingState(this, GetCurrentDoc(), valueMissing,
|
||||
notify);
|
||||
VisitGroup(visitor, notify);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLInputElement::UpdateValueMissingValidityState()
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_RADIO) {
|
||||
UpdateValueMissingValidityStateForRadio(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SetValidityState(VALIDITY_STATE_VALUE_MISSING, IsValueMissing());
|
||||
}
|
||||
|
||||
|
@ -4256,6 +4283,74 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class nsRadioGroupRequiredVisitor : public nsRadioVisitor {
|
||||
public:
|
||||
nsRadioGroupRequiredVisitor(nsIFormControl* aExcludeElement, bool* aRequired)
|
||||
: mRequired(aRequired)
|
||||
, mExcludeElement(aExcludeElement)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop)
|
||||
{
|
||||
if (aRadio == mExcludeElement) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*mRequired = static_cast<nsHTMLInputElement*>(aRadio)
|
||||
->HasAttr(kNameSpaceID_None, nsGkAtoms::required);
|
||||
|
||||
if (*mRequired) {
|
||||
*aStop = PR_TRUE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool* mRequired;
|
||||
nsIFormControl* mExcludeElement;
|
||||
};
|
||||
|
||||
class nsRadioSetValueMissingState : public nsRadioVisitor {
|
||||
public:
|
||||
nsRadioSetValueMissingState(nsIFormControl* aExcludeElement,
|
||||
nsIDocument* aDocument, bool aValidity,
|
||||
bool aNotify)
|
||||
: mExcludeElement(aExcludeElement)
|
||||
, mDocument(aDocument)
|
||||
, mValidity(aValidity)
|
||||
, mNotify(aNotify)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop)
|
||||
{
|
||||
if (aRadio == mExcludeElement) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsHTMLInputElement* input = static_cast<nsHTMLInputElement*>(aRadio);
|
||||
|
||||
input->SetValidityState(nsIConstraintValidation::VALIDITY_STATE_VALUE_MISSING,
|
||||
mValidity);
|
||||
|
||||
if (mNotify && mDocument) {
|
||||
mDocument->ContentStatesChanged(input, nsnull,
|
||||
NS_EVENT_STATE_VALID |
|
||||
NS_EVENT_STATE_INVALID |
|
||||
NS_EVENT_STATE_MOZ_UI_VALID |
|
||||
NS_EVENT_STATE_MOZ_UI_INVALID);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsIFormControl* mExcludeElement;
|
||||
nsIDocument* mDocument;
|
||||
bool mValidity;
|
||||
bool mNotify;
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_GetRadioSetCheckedChangedVisitor(PRBool aCheckedChanged,
|
||||
nsIRadioVisitor** aVisitor)
|
||||
|
@ -4342,6 +4437,22 @@ NS_GetRadioUpdateValueMissingVisitor()
|
|||
return new nsRadioUpdateValueMissingVisitor();
|
||||
}
|
||||
|
||||
nsIRadioVisitor*
|
||||
NS_GetRadioGroupRequiredVisitor(nsIFormControl* aExcludeElement,
|
||||
bool* aRequired)
|
||||
{
|
||||
return new nsRadioGroupRequiredVisitor(aExcludeElement, aRequired);
|
||||
}
|
||||
|
||||
nsIRadioVisitor*
|
||||
NS_SetRadioValueMissingState(nsIFormControl* aExcludeElement,
|
||||
nsIDocument* aDocument,
|
||||
bool aValidity, bool aNotify)
|
||||
{
|
||||
return new nsRadioSetValueMissingState(aExcludeElement, aDocument, aValidity,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsHTMLInputElement::IsSingleLineTextControl() const
|
||||
{
|
||||
|
|
|
@ -110,7 +110,6 @@ private:
|
|||
PRBool mInPrivateBrowsing;
|
||||
};
|
||||
|
||||
class nsIRadioGroupContainer;
|
||||
class nsIRadioVisitor;
|
||||
|
||||
class nsHTMLInputElement : public nsGenericHTMLFormElement,
|
||||
|
@ -283,6 +282,15 @@ public:
|
|||
void UpdateBarredFromConstraintValidation();
|
||||
nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidityStateType aType);
|
||||
/**
|
||||
* Update the value missing validity state for radio elements when they have
|
||||
* a group.
|
||||
*
|
||||
* @param aIgnoreSelf Whether the required attribute and the checked state
|
||||
* of the current radio should be ignored.
|
||||
* @note This method shouldn't be called if the radio elemnet hasn't a group.
|
||||
*/
|
||||
void UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf);
|
||||
|
||||
/**
|
||||
* Returns the filter which should be used for the file picker according to
|
||||
|
|
|
@ -248,6 +248,7 @@ _TEST_FILES = \
|
|||
test_bug613979.html \
|
||||
test_bug615833.html \
|
||||
test_bug601030.html \
|
||||
test_bug610687.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -258,13 +258,13 @@ function checkInputRequiredValidityForRadio()
|
|||
checkNotSufferingFromBeingMissing(element);
|
||||
|
||||
// If a radio button is not required but another radio button is required in
|
||||
// the same group, the not required radio button should not suffer from value
|
||||
// the same group, the not required radio button should suffer from value
|
||||
// missing.
|
||||
element2.disabled = false;
|
||||
element2.checked = false;
|
||||
element.required = false;
|
||||
element2.required = true;
|
||||
checkNotSufferingFromBeingMissing(element);
|
||||
checkSufferingFromBeingMissing(element);
|
||||
checkSufferingFromBeingMissing(element2);
|
||||
|
||||
element.checked = true;
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=610687
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 610687</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=610687">Mozilla Bug 610687</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<form>
|
||||
<input type='radio' name='a'>
|
||||
<input type='radio' name='a'>
|
||||
<input type='radio' name='b'>
|
||||
</form>
|
||||
<input type='radio' name='a'>
|
||||
<input type='radio' name='a'>
|
||||
<input type='radio' name='b'>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 610687 **/
|
||||
|
||||
function checkPseudoClasses(aElement, aValid, aValidUI, aInvalidUI)
|
||||
{
|
||||
if (aValid) {
|
||||
ok(aElement.mozMatchesSelector(":valid"), ":valid should apply");
|
||||
} else {
|
||||
ok(aElement.mozMatchesSelector(":invalid"), ":invalid should apply");
|
||||
}
|
||||
|
||||
is(aElement.mozMatchesSelector(":-moz-ui-valid"), aValidUI,
|
||||
aValid ? ":-moz-ui-valid should apply" : ":-moz-ui-valid should not apply");
|
||||
|
||||
is(aElement.mozMatchesSelector(":-moz-ui-invalid"), aInvalidUI,
|
||||
aInvalidUI ? ":-moz-ui-invalid should apply" : ":-moz-ui-invalid should not apply");
|
||||
|
||||
if (aInvalidUI && (aValid || aValidUI)) {
|
||||
ok(false, ":invalid can't apply with :valid or :-moz-valid-ui");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* r1 and r2 should be in the same group.
|
||||
* r3 should be in another group.
|
||||
* form can be null.
|
||||
*/
|
||||
function checkRadios(r1, r2, r3, form)
|
||||
{
|
||||
// Default state.
|
||||
checkPseudoClasses(r1, true, false, false);
|
||||
checkPseudoClasses(r2, true, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Suffering from being missing (without ui-invalid).
|
||||
r1.required = true;
|
||||
checkPseudoClasses(r1, false, false, false);
|
||||
checkPseudoClasses(r2, false, false, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Suffering from being missing (with ui-invalid).
|
||||
r1.checked = false;
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Do not suffer from being missing (with ui-valid).
|
||||
r1.checked = true;
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Do not suffer from being missing (with ui-valid).
|
||||
r1.checked = false;
|
||||
r1.required = false;
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Suffering from being missing (with ui-invalid) with required set on one radio
|
||||
// and the checked state changed on another.
|
||||
r1.required = true;
|
||||
r2.checked = false;
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// Do not suffer from being missing (with ui-valid) by checking the radio which
|
||||
// hasn't the required attribute.
|
||||
r2.checked = true;
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r3, true, false, false);
|
||||
|
||||
// .setCustomValidity() should not affect the entire group.
|
||||
r1.checked = r2.checked = r3.checked = false;
|
||||
r1.required = false;
|
||||
r1.setCustomValidity('foo');
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r3, true, true, false);
|
||||
|
||||
r1.setCustomValidity('');
|
||||
r2.setCustomValidity('foo');
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
checkPseudoClasses(r3, true, true, false);
|
||||
|
||||
r2.setCustomValidity('');
|
||||
r3.setCustomValidity('foo');
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, true, true, false);
|
||||
checkPseudoClasses(r3, false, false, true);
|
||||
|
||||
// Removing the radio with the required attribute should make the entire
|
||||
// group invalid.
|
||||
r1.setCustomValidity('');
|
||||
r2.setCustomValidity('');
|
||||
r1.required = false;
|
||||
r2.required = true;
|
||||
r1.checked = r2.checked = false;
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
|
||||
var p = r2.parentNode;
|
||||
p.removeChild(r2);
|
||||
checkPseudoClasses(r1, true, true, false);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
|
||||
p.appendChild(r2);
|
||||
checkPseudoClasses(r1, false, false, true);
|
||||
checkPseudoClasses(r2, false, false, true);
|
||||
}
|
||||
|
||||
var r1 = document.getElementsByTagName('input')[0];
|
||||
var r2 = document.getElementsByTagName('input')[1];
|
||||
var r3 = document.getElementsByTagName('input')[2];
|
||||
checkRadios(r1, r2, r3);
|
||||
|
||||
r1 = document.getElementsByTagName('input')[3];
|
||||
r2 = document.getElementsByTagName('input')[4];
|
||||
r3 = document.getElementsByTagName('input')[5];
|
||||
checkRadios(r1, r2, r3);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if one radio in a group is suffering from a custom error, the other
|
||||
radio should not be invalid. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').setCustomValidity('foo');
|
||||
if (!document.getElementById('i1').mozMatchesSelector(':invalid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio'>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when there are no radio suffering from being missing in the radio
|
||||
group, all radio should not suffer from being missing. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = true;
|
||||
if (document.getElementById('i1').mozMatchesSelector(':invalid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when there are no radio suffering from being missing in the radio
|
||||
group, all radio should not suffer from being missing. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').required = false;
|
||||
if (document.getElementById('i1').mozMatchesSelector(':invalid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="if (document.getElementById('i').mozMatchesSelector(':invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' checked required>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="if (!document.getElementById('i').mozMatchesSelector(':invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if one radio in a group has the required attribute and no radio is
|
||||
checked, all radio in the group should suffer from being missing. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="if (!document.getElementById('i1').mozMatchesSelector(':invalid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -23,4 +23,10 @@
|
|||
== input-disabled-fieldset-1.html input-fieldset-ref.html
|
||||
== input-disabled-fieldset-2.html input-fieldset-ref.html
|
||||
== input-fieldset-legend.html input-fieldset-legend-ref.html
|
||||
== input-radio-required.html success-ref.html
|
||||
== input-radio-customerror.html success-ref.html
|
||||
== input-radio-dyn-valid-1.html success-ref.html
|
||||
== 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 type='hidden' shouldn't show
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
SUCCESS
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if one radio in a group is suffering from a custom error, the other
|
||||
radio should not be invalid. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = false;
|
||||
document.getElementById('i1').setCustomValidity('foo');
|
||||
if (!document.getElementById('i1').mozMatchesSelector(':-moz-ui-invalid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio'>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when there are no radio suffering from being missing in the radio
|
||||
group, all radio should not suffer from being missing. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = true;
|
||||
if (document.getElementById('i1').mozMatchesSelector(':-moz-ui-invalid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: when there are no radio suffering from being missing in the radio
|
||||
group, all radio should not suffer from being missing. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = true;
|
||||
document.getElementById('i1').required = false;
|
||||
if (document.getElementById('i1').mozMatchesSelector(':-moz-ui-invalid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = true;
|
||||
if (document.getElementById('i').mozMatchesSelector(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = false;
|
||||
if (!document.getElementById('i').mozMatchesSelector(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if one radio in a group has the required attribute and no radio is
|
||||
checked, all radio in the group should have :-moz-ui-invalid
|
||||
pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = false;
|
||||
if (!document.getElementById('i1').mozMatchesSelector(':-moz-ui-invalid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':-moz-ui-invalid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -33,8 +33,12 @@
|
|||
== input-checkbox-required-invalid-default.html success-ref.html
|
||||
== input-radio-required-invalid-changed.html success-ref.html
|
||||
== input-radio-required-invalid-default.html success-ref.html
|
||||
== input-radio-required-invalid-changed-2.html success-ref.html
|
||||
== input-radio-required-invalid-default-2.html success-ref.html
|
||||
== input-file-required-invalid-changed.html input-file-ref.html
|
||||
== input-file-required-invalid-default.html input-file-ref.html
|
||||
== input-radio-required.html success-ref.html
|
||||
== input-radio-customerror.html success-ref.html
|
||||
== input-radio-dyn-valid-1.html success-ref.html
|
||||
== 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 type='hidden' shouldn't show
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
and its checkedness has changed,
|
||||
it should be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i2').checked = false;
|
||||
if (document.getElementById('i1').mozMatchesSelector(':-moz-ui-invalid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':-moz-ui-invalid')) {
|
||||
<body onload="document.getElementById('i1').checked = false;
|
||||
document.getElementById('i1').setCustomValidity('foo');
|
||||
if (document.getElementById('i1').mozMatchesSelector(':-moz-ui-valid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' type='radio'>
|
||||
<input id='i2' type='radio' required>
|
||||
<input id='i1' name='foo' type='radio'>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = true;
|
||||
if (!document.getElementById('i1').mozMatchesSelector(':-moz-ui-valid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = true;
|
||||
document.getElementById('i1').required = false;
|
||||
if (!document.getElementById('i1').mozMatchesSelector(':-moz-ui-valid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = true;
|
||||
if (!document.getElementById('i').mozMatchesSelector(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i').checked = false;
|
||||
if (document.getElementById('i').mozMatchesSelector(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = false;
|
||||
if (document.getElementById('i1').mozMatchesSelector(':-moz-ui-valid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':-moz-ui-valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -32,8 +32,12 @@
|
|||
== input-fieldset-legend.html input-fieldset-legend-ref.html
|
||||
== input-checkbox-valid-changed.html success-ref.html
|
||||
== input-checkbox-valid-default.html success-ref.html
|
||||
== input-radio-valid-changed.html success-ref.html
|
||||
== input-radio-valid-default.html success-ref.html
|
||||
== input-file-valid-changed.html input-file-ref.html
|
||||
== input-file-valid-default.html input-file-ref.html
|
||||
== input-radio-required.html success-ref.html
|
||||
== input-radio-customerror.html success-ref.html
|
||||
== input-radio-dyn-valid-1.html success-ref.html
|
||||
== 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 type='hidden' shouldn't show
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').setCustomValidity('foo');
|
||||
if (document.getElementById('i1').mozMatchesSelector(':valid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio'>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').checked = true;
|
||||
if (!document.getElementById('i1').mozMatchesSelector(':valid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="document.getElementById('i1').required = false;
|
||||
if (!document.getElementById('i1').mozMatchesSelector(':valid') ||
|
||||
!document.getElementById('i2').mozMatchesSelector(':valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="if (!document.getElementById('i').mozMatchesSelector(':valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' checked required>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="if (document.getElementById('i').mozMatchesSelector(':valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i' type='radio' required>
|
||||
</body>
|
||||
</html>
|
|
@ -1,17 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<!-- Test: if input isn't valid nor barred from constraint validation,
|
||||
and its checkedness hasn't changed,
|
||||
it should not be affected by :-moz-ui-invalid pseudo-class. -->
|
||||
<link rel='stylesheet' type='text/css' href='style.css'>
|
||||
<body onload="if (document.getElementById('i1').mozMatchesSelector(':-moz-ui-invalid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':-moz-ui-invalid')) {
|
||||
<body onload="if (document.getElementById('i1').mozMatchesSelector(':valid') ||
|
||||
document.getElementById('i2').mozMatchesSelector(':valid')) {
|
||||
document.body.textContent='FAIL';
|
||||
} else {
|
||||
document.body.textContent='SUCCESS';
|
||||
}
|
||||
document.documentElement.className='';">
|
||||
<input id='i1' type='radio'>
|
||||
<input id='i2' type='radio' required>
|
||||
<input id='i1' name='foo' type='radio' required>
|
||||
<input id='i2' name='foo' type='radio'>
|
||||
</body>
|
||||
</html>
|
|
@ -23,4 +23,10 @@
|
|||
== input-disabled-fieldset-1.html input-fieldset-ref.html
|
||||
== input-disabled-fieldset-2.html input-fieldset-ref.html
|
||||
== input-fieldset-legend.html input-fieldset-legend-ref.html
|
||||
== input-radio-required.html success-ref.html
|
||||
== input-radio-customerror.html success-ref.html
|
||||
== input-radio-dyn-valid-1.html success-ref.html
|
||||
== 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 type='hidden' shouldn't show
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
SUCCESS
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче