@@ -2612,4 +2612,270 @@ public void buttonTypeInvalid() throws Exception {
26122612
26132613 loadPageVerifyTitle2 (html );
26142614 }
2615+
2616+ /**
2617+ * Baseline: a default (type='submit') button with no custom validity issue
2618+ * matches :valid and not :invalid.
2619+ * @throws Exception if the test fails
2620+ */
2621+ @ Test
2622+ @ Alerts ({"true" , "false" })
2623+ public void cssValidMatchesSubmitButtonWithNoError () throws Exception {
2624+ final String html = DOCTYPE_HTML
2625+ + "<html><head>\n "
2626+ + "<script>\n "
2627+ + LOG_TITLE_FUNCTION
2628+ + " function test() {\n "
2629+ + " var b = document.getElementById('b');\n "
2630+ + " log(b.matches(':valid'));\n "
2631+ + " log(b.matches(':invalid'));\n "
2632+ + " }\n "
2633+ + "</script></head>\n "
2634+ + "<body onload='test()'>\n "
2635+ + " <form>\n "
2636+ + " <button id='b' type='submit'>btn</button>\n "
2637+ + " </form>\n "
2638+ + "</body></html>" ;
2639+
2640+ loadPageVerifyTitle2 (html );
2641+ }
2642+
2643+ /**
2644+ * A default (type='submit') button with a custom validity message matches
2645+ * :invalid and not :valid.
2646+ * @throws Exception if the test fails
2647+ */
2648+ @ Test
2649+ @ Alerts ({"false" , "true" })
2650+ public void cssInvalidMatchesSubmitButtonWithCustomValidity () throws Exception {
2651+ final String html = DOCTYPE_HTML
2652+ + "<html><head>\n "
2653+ + "<script>\n "
2654+ + LOG_TITLE_FUNCTION
2655+ + " function test() {\n "
2656+ + " var b = document.getElementById('b');\n "
2657+ + " b.setCustomValidity('some error');\n "
2658+ + " log(b.matches(':valid'));\n "
2659+ + " log(b.matches(':invalid'));\n "
2660+ + " }\n "
2661+ + "</script></head>\n "
2662+ + "<body onload='test()'>\n "
2663+ + " <form>\n "
2664+ + " <button id='b' type='submit'>btn</button>\n "
2665+ + " </form>\n "
2666+ + "</body></html>" ;
2667+
2668+ loadPageVerifyTitle2 (html );
2669+ }
2670+
2671+ /**
2672+ * A type='button' element is barred from constraint validation --
2673+ * it must match NEITHER :valid NOR :invalid, even with no custom validity
2674+ * issue at all.
2675+ * @throws Exception if the test fails
2676+ */
2677+ @ Test
2678+ @ Alerts ({"false" , "false" })
2679+ public void cssNeitherMatchesPlainButtonType () throws Exception {
2680+ final String html = DOCTYPE_HTML
2681+ + "<html><head>\n "
2682+ + "<script>\n "
2683+ + LOG_TITLE_FUNCTION
2684+ + " function test() {\n "
2685+ + " var b = document.getElementById('b');\n "
2686+ + " log(b.matches(':valid'));\n "
2687+ + " log(b.matches(':invalid'));\n "
2688+ + " }\n "
2689+ + "</script></head>\n "
2690+ + "<body onload='test()'>\n "
2691+ + " <form>\n "
2692+ + " <button id='b' type='button'>btn</button>\n "
2693+ + " </form>\n "
2694+ + "</body></html>" ;
2695+
2696+ loadPageVerifyTitle2 (html );
2697+ }
2698+
2699+ /**
2700+ * Same as above, but ALSO with a custom validity message set -- the barring
2701+ * must take priority over the (otherwise would-be-invalid) custom error;
2702+ * neither pseudo-class should match.
2703+ * @throws Exception if the test fails
2704+ */
2705+ @ Test
2706+ @ Alerts ({"false" , "false" })
2707+ public void cssNeitherMatchesPlainButtonTypeEvenWithCustomValidity () throws Exception {
2708+ final String html = DOCTYPE_HTML
2709+ + "<html><head>\n "
2710+ + "<script>\n "
2711+ + LOG_TITLE_FUNCTION
2712+ + " function test() {\n "
2713+ + " var b = document.getElementById('b');\n "
2714+ + " b.setCustomValidity('some error');\n "
2715+ + " log(b.matches(':valid'));\n "
2716+ + " log(b.matches(':invalid'));\n "
2717+ + " }\n "
2718+ + "</script></head>\n "
2719+ + "<body onload='test()'>\n "
2720+ + " <form>\n "
2721+ + " <button id='b' type='button'>btn</button>\n "
2722+ + " </form>\n "
2723+ + "</body></html>" ;
2724+
2725+ loadPageVerifyTitle2 (html );
2726+ }
2727+
2728+ /**
2729+ * A type='reset' is barred the same way as type='button' -- neither
2730+ * pseudo-class should match, custom validity or not.
2731+ * @throws Exception if the test fails
2732+ */
2733+ @ Test
2734+ @ Alerts ({"false" , "false" })
2735+ public void cssNeitherMatchesResetButtonType () throws Exception {
2736+ final String html = DOCTYPE_HTML
2737+ + "<html><head>\n "
2738+ + "<script>\n "
2739+ + LOG_TITLE_FUNCTION
2740+ + " function test() {\n "
2741+ + " var b = document.getElementById('b');\n "
2742+ + " b.setCustomValidity('some error');\n "
2743+ + " log(b.matches(':valid'));\n "
2744+ + " log(b.matches(':invalid'));\n "
2745+ + " }\n "
2746+ + "</script></head>\n "
2747+ + "<body onload='test()'>\n "
2748+ + " <form>\n "
2749+ + " <button id='b' type='reset'>btn</button>\n "
2750+ + " </form>\n "
2751+ + "</body></html>" ;
2752+
2753+ loadPageVerifyTitle2 (html );
2754+ }
2755+
2756+ /**
2757+ * A DISABLED submit button is also barred from constraint
2758+ * validation -- neither pseudo-class should match, even with a custom
2759+ * validity message set.
2760+ * @throws Exception if the test fails
2761+ */
2762+ @ Test
2763+ @ Alerts ({"false" , "false" })
2764+ public void cssNeitherMatchesDisabledSubmitButton () throws Exception {
2765+ final String html = DOCTYPE_HTML
2766+ + "<html><head>\n "
2767+ + "<script>\n "
2768+ + LOG_TITLE_FUNCTION
2769+ + " function test() {\n "
2770+ + " var b = document.getElementById('b');\n "
2771+ + " b.setCustomValidity('some error');\n "
2772+ + " log(b.matches(':valid'));\n "
2773+ + " log(b.matches(':invalid'));\n "
2774+ + " }\n "
2775+ + "</script></head>\n "
2776+ + "<body onload='test()'>\n "
2777+ + " <form>\n "
2778+ + " <button id='b' type='submit' disabled>btn</button>\n "
2779+ + " </form>\n "
2780+ + "</body></html>" ;
2781+
2782+ loadPageVerifyTitle2 (html );
2783+ }
2784+
2785+ /**
2786+ * Redundant-barring sanity check: type='button' AND disabled AND a custom
2787+ * validity message all at once -- still neither pseudo-class should match.
2788+ * @throws Exception if the test fails
2789+ */
2790+ @ Test
2791+ @ Alerts ({"false" , "false" })
2792+ public void cssNeitherMatchesDisabledPlainButtonWithCustomValidity () throws Exception {
2793+ final String html = DOCTYPE_HTML
2794+ + "<html><head>\n "
2795+ + "<script>\n "
2796+ + LOG_TITLE_FUNCTION
2797+ + " function test() {\n "
2798+ + " var b = document.getElementById('b');\n "
2799+ + " b.setCustomValidity('some error');\n "
2800+ + " log(b.matches(':valid'));\n "
2801+ + " log(b.matches(':invalid'));\n "
2802+ + " }\n "
2803+ + "</script></head>\n "
2804+ + "<body onload='test()'>\n "
2805+ + " <form>\n "
2806+ + " <button id='b' type='button' disabled>btn</button>\n "
2807+ + " </form>\n "
2808+ + "</body></html>" ;
2809+
2810+ loadPageVerifyTitle2 (html );
2811+ }
2812+
2813+ /**
2814+ * Dynamic transition: a button barred via type='button' (with a leftover
2815+ * custom validity message set while barred) is switched to type='submit' at
2816+ * runtime. It must now correctly participate in validation and show
2817+ * :invalid -- confirms the barred/not-barred state is evaluated fresh each
2818+ * time, not cached from whatever it was when setCustomValidity() was
2819+ * originally called.
2820+ * @throws Exception if the test fails
2821+ */
2822+ @ Test
2823+ @ Alerts ({"false" , "false" , "false" , "true" })
2824+ public void cssMatchingUpdatesWhenTypeChangesFromButtonToSubmit () throws Exception {
2825+ final String html = DOCTYPE_HTML
2826+ + "<html><head>\n "
2827+ + "<script>\n "
2828+ + LOG_TITLE_FUNCTION
2829+ + " function test() {\n "
2830+ + " var b = document.getElementById('b');\n "
2831+ + " b.setCustomValidity('some error');\n "
2832+ + " log(b.matches(':valid'));\n "
2833+ + " log(b.matches(':invalid'));\n "
2834+
2835+ + " b.type = 'submit';\n "
2836+ + " log(b.matches(':valid'));\n "
2837+ + " log(b.matches(':invalid'));\n "
2838+ + " }\n "
2839+ + "</script></head>\n "
2840+ + "<body onload='test()'>\n "
2841+ + " <form>\n "
2842+ + " <button id='b' type='button'>btn</button>\n "
2843+ + " </form>\n "
2844+ + "</body></html>" ;
2845+
2846+ loadPageVerifyTitle2 (html );
2847+ }
2848+
2849+ /**
2850+ * Dynamic transition, the other direction: an initially-valid submit button
2851+ * is switched to type='button' at runtime -- it must stop matching :valid
2852+ * (or :invalid) entirely once barred, even though it was clean before the
2853+ * change.
2854+ * @throws Exception if the test fails
2855+ */
2856+ @ Test
2857+ @ Alerts ({"true" , "false" , "false" , "false" })
2858+ public void cssMatchingUpdatesWhenTypeChangesFromSubmitToButton () throws Exception {
2859+ final String html = DOCTYPE_HTML
2860+ + "<html><head>\n "
2861+ + "<script>\n "
2862+ + LOG_TITLE_FUNCTION
2863+ + " function test() {\n "
2864+ + " var b = document.getElementById('b');\n "
2865+ + " log(b.matches(':valid'));\n "
2866+ + " log(b.matches(':invalid'));\n "
2867+
2868+ + " b.type = 'button';\n "
2869+ + " log(b.matches(':valid'));\n "
2870+ + " log(b.matches(':invalid'));\n "
2871+ + " }\n "
2872+ + "</script></head>\n "
2873+ + "<body onload='test()'>\n "
2874+ + " <form>\n "
2875+ + " <button id='b' type='submit'>btn</button>\n "
2876+ + " </form>\n "
2877+ + "</body></html>" ;
2878+
2879+ loadPageVerifyTitle2 (html );
2880+ }
26152881}
0 commit comments