diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index f0b80f83182..11c2467f28c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -8,6 +8,12 @@
+
+ Implementation of CSS pseudo classes :invalid and :valid improved.
+
+
+ Form.isValid() checks all form elements.
+
WebClient documentation enhanced.
diff --git a/src/main/java/org/htmlunit/css/CssStyleSheet.java b/src/main/java/org/htmlunit/css/CssStyleSheet.java
index 860fda89088..aa90bc88c19 100644
--- a/src/main/java/org/htmlunit/css/CssStyleSheet.java
+++ b/src/main/java/org/htmlunit/css/CssStyleSheet.java
@@ -97,6 +97,7 @@
import org.htmlunit.html.DomText;
import org.htmlunit.html.HtmlCheckBoxInput;
import org.htmlunit.html.HtmlElement;
+import org.htmlunit.html.HtmlForm;
import org.htmlunit.html.HtmlInput;
import org.htmlunit.html.HtmlLink;
import org.htmlunit.html.HtmlOption;
@@ -104,6 +105,7 @@
import org.htmlunit.html.HtmlRadioButtonInput;
import org.htmlunit.html.HtmlStyle;
import org.htmlunit.html.HtmlTextArea;
+import org.htmlunit.html.ValidatableElement;
import org.htmlunit.javascript.host.css.MediaList;
import org.htmlunit.javascript.host.dom.Document;
import org.htmlunit.javascript.host.html.HTMLDocument;
@@ -870,10 +872,16 @@ private static boolean selectsPseudoClass(final BrowserVersion browserVersion,
return true;
case "valid":
- return element instanceof HtmlElement && ((HtmlElement) element).isValid();
+ if (element instanceof HtmlForm || element instanceof ValidatableElement) {
+ return ((HtmlElement) element).isValid();
+ }
+ return false;
case "invalid":
- return element instanceof HtmlElement && !((HtmlElement) element).isValid();
+ if (element instanceof HtmlForm || element instanceof ValidatableElement) {
+ return !((HtmlElement) element).isValid();
+ }
+ return false;
case "empty":
return isEmpty(element);
diff --git a/src/main/java/org/htmlunit/html/HtmlForm.java b/src/main/java/org/htmlunit/html/HtmlForm.java
index f5ac7bcb800..cf8278b7869 100644
--- a/src/main/java/org/htmlunit/html/HtmlForm.java
+++ b/src/main/java/org/htmlunit/html/HtmlForm.java
@@ -458,6 +458,19 @@ public Page reset() {
return htmlPage;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isValid() {
+ for (final HtmlElement element : getElements()) {
+ if (!element.isValid()) {
+ return false;
+ }
+ }
+ return super.isValid();
+ }
+
/**
* Returns a collection of elements that represent all the "submittable" elements in this form,
* assuming that the specified element is used to submit the form.
diff --git a/src/test/java/org/htmlunit/javascript/host/css/CSSSelectorTest.java b/src/test/java/org/htmlunit/javascript/host/css/CSSSelectorTest.java
index 98e41224fce..c97f2f534e7 100644
--- a/src/test/java/org/htmlunit/javascript/host/css/CSSSelectorTest.java
+++ b/src/test/java/org/htmlunit/javascript/host/css/CSSSelectorTest.java
@@ -1058,10 +1058,7 @@ public void pseudoRadioChecked() throws Exception {
@Test
@Alerts(DEFAULT = {"theform", "id3"},
IE = "id3") //minLength and maxLength not supported in IE
- @HtmlUnitNYI(CHROME = "id3",
- EDGE = "id3",
- FF = "id3",
- FF_ESR = "id3")
+ @HtmlUnitNYI(IE = {"theform", "id3"})
public void pseudoInvalid() throws Exception {
final String html = "\n"
+ "