<!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=345822 --> <head> <title>Test for Bug 345822</title> <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=345822">Mozilla Bug 345822</a> <p id="display"></p> <div id="content"> <form> </form> </div> <pre id="test"> <script type="application/javascript"> /** Test for Bug 345822 **/ function checkNotSufferingFromBeingMissing(element, doNotApply) { ok(!element.validity.valueMissing, "Element should not suffer from value missing"); ok(element.validity.valid, "Element should be valid"); ok(element.checkValidity(), "Element should be valid"); is(element.validationMessage, "", "Validation message should be the empty string"); if (doNotApply) { ok(!element.matches(':valid'), ":valid should not apply"); ok(!element.matches(':invalid'), ":invalid should not apply"); ok(!element.matches(':-moz-ui-valid'), ":-moz-ui-valid should not apply"); ok(!element.matches(':-moz-ui-invalid'), ":-moz-ui-invalid should not apply"); } else { ok(element.matches(':valid'), ":valid should apply"); ok(!element.matches(':invalid'), ":invalid should not apply"); ok(element.matches(':-moz-ui-valid'), ":-moz-ui-valid should apply"); ok(!element.matches(':-moz-ui-invalid'), ":-moz-ui-invalid should not apply"); } } function checkSufferingFromBeingMissing(element, hasMozUIInvalid) { ok(element.validity.valueMissing, "Element should suffer from value missing"); ok(!element.validity.valid, "Element should not be valid"); ok(!element.checkValidity(), "Element should not be valid"); if (element.type == 'checkbox') { is(element.validationMessage, "Please check this box if you want to proceed.", "Validation message is wrong"); } else if (element.type == 'radio') { is(element.validationMessage, "Please select one of these options.", "Validation message is wrong"); } else if (element.type == 'file') { is(element.validationMessage, "Please select a file.", "Validation message is wrong"); } else if (element.type == 'number') { is(element.validationMessage, "Please enter a number.", "Validation message is wrong"); } else // text fields { is(element.validationMessage, "Please fill out this field.", "Validation message is wrong"); } ok(!element.matches(':valid'), ":valid should apply"); ok(element.matches(':invalid'), ":invalid should not apply"); ok(!element.matches(':-moz-ui-valid'), ":-moz-ui-valid should not apply"); is(element.matches(':-moz-ui-invalid'), hasMozUIInvalid, ":-moz-ui-invalid expected state is " + hasMozUIInvalid); } function checkTextareaRequiredValidity() { var element = document.createElement('textarea'); document.forms[0].appendChild(element); SpecialPowers.wrap(element).value = ''; element.required = false; checkNotSufferingFromBeingMissing(element); element.required = true; checkSufferingFromBeingMissing(element, true); element.readOnly = true; checkNotSufferingFromBeingMissing(element, true); element.readOnly = false; checkSufferingFromBeingMissing(element, true); SpecialPowers.wrap(element).value = 'foo'; checkNotSufferingFromBeingMissing(element); SpecialPowers.wrap(element).value = ''; checkSufferingFromBeingMissing(element, true); element.required = false; checkNotSufferingFromBeingMissing(element); element.focus(); element.required = true; SpecialPowers.wrap(element).value = 'foobar'; element.blur(); element.form.reset(); checkSufferingFromBeingMissing(element, false); // TODO: for the moment, a textarea outside of a document is mutable. SpecialPowers.wrap(element).value = ''; // To make -moz-ui-valid apply. element.required = false; document.forms[0].removeChild(element); checkNotSufferingFromBeingMissing(element); } function checkInputRequiredNotApply(type, isBarred) { var element = document.createElement('input'); element.type = type; document.forms[0].appendChild(element); SpecialPowers.wrap(element).value = ''; element.required = false; checkNotSufferingFromBeingMissing(element, isBarred); element.required = true; checkNotSufferingFromBeingMissing(element, isBarred); element.required = false; document.forms[0].removeChild(element); checkNotSufferingFromBeingMissing(element, isBarred); } function checkInputRequiredValidity(type) { var element = document.createElement('input'); element.type = type; document.forms[0].appendChild(element); SpecialPowers.wrap(element).value = ''; element.required = false; checkNotSufferingFromBeingMissing(element); element.required = true; checkSufferingFromBeingMissing(element, true); element.readOnly = true; checkNotSufferingFromBeingMissing(element, true); element.readOnly = false; checkSufferingFromBeingMissing(element, true); if (element.type == 'email') { SpecialPowers.wrap(element).value = 'foo@bar.com'; } else if (element.type == 'url') { SpecialPowers.wrap(element).value = 'http://mozilla.org/'; } else if (element.type == 'number') { SpecialPowers.wrap(element).value = '42'; } else if (element.type == 'date') { SpecialPowers.wrap(element).value = '2010-10-10'; } else if (element.type == 'time') { SpecialPowers.wrap(element).value = '21:21'; } else if (element.type = 'month') { SpecialPowers.wrap(element).value = '2010-10'; } else { SpecialPowers.wrap(element).value = 'foo'; } checkNotSufferingFromBeingMissing(element); SpecialPowers.wrap(element).value = ''; checkSufferingFromBeingMissing(element, true); element.focus(); element.required = true; SpecialPowers.wrap(element).value = 'foobar'; element.blur(); element.form.reset(); checkSufferingFromBeingMissing(element, false); element.required = true; SpecialPowers.wrap(element).value = ''; // To make :-moz-ui-valid apply. checkSufferingFromBeingMissing(element, true); document.forms[0].removeChild(element); // Removing the child changes nothing about whether it's valid checkSufferingFromBeingMissing(element, true); } function checkInputRequiredValidityForCheckbox() { var element = document.createElement('input'); element.type = 'checkbox'; document.forms[0].appendChild(element); element.checked = false; element.required = false; checkNotSufferingFromBeingMissing(element); element.required = true; checkSufferingFromBeingMissing(element, true); element.checked = true; checkNotSufferingFromBeingMissing(element); element.checked = false; checkSufferingFromBeingMissing(element, true); element.required = false; checkNotSufferingFromBeingMissing(element); element.focus(); element.required = true; element.checked = true; element.blur(); element.form.reset(); checkSufferingFromBeingMissing(element, false); element.required = true; element.checked = false; document.forms[0].removeChild(element); checkSufferingFromBeingMissing(element, true); } function checkInputRequiredValidityForRadio() { var element = document.createElement('input'); element.type = 'radio'; element.name = 'test' document.forms[0].appendChild(element); element.checked = false; element.required = false; checkNotSufferingFromBeingMissing(element); element.required = true; checkSufferingFromBeingMissing(element, true); element.checked = true; checkNotSufferingFromBeingMissing(element); element.checked = false; checkSufferingFromBeingMissing(element, true); // A required radio button should not suffer from value missing if another // radio button from the same group is checked. var element2 = document.createElement('input'); element2.type = 'radio'; element2.name = 'test'; element2.checked = true; element2.required = false; document.forms[0].appendChild(element2); // Adding a checked radio should make required radio in the group not // suffering from being missing. checkNotSufferingFromBeingMissing(element); element.checked = false; element2.checked = false; checkSufferingFromBeingMissing(element, true); // The other radio button should not be disabled. // A disabled checked radio button in the radio group // is enough to not suffer from value missing. element2.checked = true; element2.disabled = true; 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 suffer from value // missing. element2.disabled = false; element2.checked = false; element.required = false; element2.required = true; checkSufferingFromBeingMissing(element, true); checkSufferingFromBeingMissing(element2, true); element.checked = true; checkNotSufferingFromBeingMissing(element2); // The checked radio is not in the group anymore, element2 should be invalid. element.form.removeChild(element); checkNotSufferingFromBeingMissing(element); checkSufferingFromBeingMissing(element2, true); element2.focus(); element2.required = true; element2.checked = true; element2.blur(); element2.form.reset(); checkSufferingFromBeingMissing(element2, false); element2.required = true; element2.checked = false; document.forms[0].removeChild(element2); checkSufferingFromBeingMissing(element2, true); } function checkInputRequiredValidityForFile() { var element = document.createElement('input'); element.type = 'file' document.forms[0].appendChild(element); var file = new File([""], "345822_file"); SpecialPowers.wrap(element).value = ""; element.required = false; checkNotSufferingFromBeingMissing(element); element.required = true; checkSufferingFromBeingMissing(element, true); SpecialPowers.wrap(element).mozSetFileArray([file]); checkNotSufferingFromBeingMissing(element); SpecialPowers.wrap(element).value = ""; checkSufferingFromBeingMissing(element, true); element.required = false; checkNotSufferingFromBeingMissing(element); element.focus(); SpecialPowers.wrap(element).mozSetFileArray([file]); element.required = true; element.blur(); element.form.reset(); checkSufferingFromBeingMissing(element, false); element.required = true; SpecialPowers.wrap(element).value = ''; document.forms[0].removeChild(element); checkSufferingFromBeingMissing(element, true); } checkTextareaRequiredValidity(); // The require attribute behavior depend of the input type. // First of all, checks for types that make the element barred from // constraint validation. var typeBarredFromConstraintValidation = ["hidden", "button", "reset"]; for (type of typeBarredFromConstraintValidation) { checkInputRequiredNotApply(type, true); } // Then, checks for the types which do not use the required attribute. var typeRequireNotApply = ['range', 'color', 'submit', 'image']; for (type of typeRequireNotApply) { checkInputRequiredNotApply(type, false); } // Now, checking for all types which accept the required attribute. var typeRequireApply = ["text", "password", "search", "tel", "email", "url", "number", "date", "time", "month", "week", "datetime-local"]; for (type of typeRequireApply) { checkInputRequiredValidity(type); } checkInputRequiredValidityForCheckbox(); checkInputRequiredValidityForRadio(); checkInputRequiredValidityForFile(); </script> </pre> </body> </html>