@@ -2878,4 +2878,328 @@ public void cssMatchingUpdatesWhenTypeChangesFromSubmitToButton() throws Excepti
28782878
28792879 loadPageVerifyTitle2 (html );
28802880 }
2881+
2882+ /**
2883+ * A textarea with no 'required' and no custom validity issue
2884+ * matches :valid and not :invalid.
2885+ * @throws Exception if the test fails
2886+ */
2887+ @ Test
2888+ @ Alerts ({"true" , "false" })
2889+ public void cssValidMatchesTextareaWithNoError () throws Exception {
2890+ final String html = DOCTYPE_HTML
2891+ + "<html><head>\n "
2892+ + "<script>\n "
2893+ + LOG_TITLE_FUNCTION
2894+ + " function test() {\n "
2895+ + " var t = document.getElementById('t');\n "
2896+ + " log(t.matches(':valid'));\n "
2897+ + " log(t.matches(':invalid'));\n "
2898+ + " }\n "
2899+ + "</script></head>\n "
2900+ + "<body onload='test()'>\n "
2901+ + " <form>\n "
2902+ + " <textarea id='t'>content</textarea>\n "
2903+ + " </form>\n "
2904+ + "</body></html>" ;
2905+
2906+ loadPageVerifyTitle2 (html );
2907+ }
2908+
2909+ /**
2910+ * A textarea with a custom validity message matches :invalid and not
2911+ * :valid.
2912+ * @throws Exception if the test fails
2913+ */
2914+ @ Test
2915+ @ Alerts ({"false" , "true" })
2916+ public void cssInvalidMatchesTextareaWithCustomValidity () throws Exception {
2917+ final String html = DOCTYPE_HTML
2918+ + "<html><head>\n "
2919+ + "<script>\n "
2920+ + LOG_TITLE_FUNCTION
2921+ + " function test() {\n "
2922+ + " var t = document.getElementById('t');\n "
2923+ + " t.setCustomValidity('some error');\n "
2924+ + " log(t.matches(':valid'));\n "
2925+ + " log(t.matches(':invalid'));\n "
2926+ + " }\n "
2927+ + "</script></head>\n "
2928+ + "<body onload='test()'>\n "
2929+ + " <form>\n "
2930+ + " <textarea id='t'>content</textarea>\n "
2931+ + " </form>\n "
2932+ + "</body></html>" ;
2933+
2934+ loadPageVerifyTitle2 (html );
2935+ }
2936+
2937+ /**
2938+ * A required, empty textarea matches :invalid (valueMissing).
2939+ * @throws Exception if the test fails
2940+ */
2941+ @ Test
2942+ @ Alerts ({"false" , "true" })
2943+ public void cssInvalidMatchesRequiredEmptyTextarea () throws Exception {
2944+ final String html = DOCTYPE_HTML
2945+ + "<html><head>\n "
2946+ + "<script>\n "
2947+ + LOG_TITLE_FUNCTION
2948+ + " function test() {\n "
2949+ + " var t = document.getElementById('t');\n "
2950+ + " log(t.matches(':valid'));\n "
2951+ + " log(t.matches(':invalid'));\n "
2952+ + " }\n "
2953+ + "</script></head>\n "
2954+ + "<body onload='test()'>\n "
2955+ + " <form>\n "
2956+ + " <textarea id='t' required></textarea>\n "
2957+ + " </form>\n "
2958+ + "</body></html>" ;
2959+
2960+ loadPageVerifyTitle2 (html );
2961+ }
2962+
2963+ /**
2964+ * A required, non-empty textarea matches :valid.
2965+ * @throws Exception if the test fails
2966+ */
2967+ @ Test
2968+ @ Alerts ({"true" , "false" })
2969+ public void cssValidMatchesRequiredNonEmptyTextarea () throws Exception {
2970+ final String html = DOCTYPE_HTML
2971+ + "<html><head>\n "
2972+ + "<script>\n "
2973+ + LOG_TITLE_FUNCTION
2974+ + " function test() {\n "
2975+ + " var t = document.getElementById('t');\n "
2976+ + " log(t.matches(':valid'));\n "
2977+ + " log(t.matches(':invalid'));\n "
2978+ + " }\n "
2979+ + "</script></head>\n "
2980+ + "<body onload='test()'>\n "
2981+ + " <form>\n "
2982+ + " <textarea id='t' required>content</textarea>\n "
2983+ + " </form>\n "
2984+ + "</body></html>" ;
2985+
2986+ loadPageVerifyTitle2 (html );
2987+ }
2988+
2989+ /**
2990+ * A DISABLED, required,
2991+ * empty textarea must match NEITHER :valid NOR :invalid -- disabled bars it
2992+ * from constraint validation entirely, regardless of the would-be
2993+ * valueMissing violation.
2994+ * @throws Exception if the test fails
2995+ */
2996+ @ Test
2997+ @ Alerts ({"false" , "false" })
2998+ public void cssNeitherMatchesDisabledRequiredEmptyTextarea () throws Exception {
2999+ final String html = DOCTYPE_HTML
3000+ + "<html><head>\n "
3001+ + "<script>\n "
3002+ + LOG_TITLE_FUNCTION
3003+ + " function test() {\n "
3004+ + " var t = document.getElementById('t');\n "
3005+ + " log(t.matches(':valid'));\n "
3006+ + " log(t.matches(':invalid'));\n "
3007+ + " }\n "
3008+ + "</script></head>\n "
3009+ + "<body onload='test()'>\n "
3010+ + " <form>\n "
3011+ + " <textarea id='t' required disabled></textarea>\n "
3012+ + " </form>\n "
3013+ + "</body></html>" ;
3014+
3015+ loadPageVerifyTitle2 (html );
3016+ }
3017+
3018+ /**
3019+ * A READONLY, required, empty textarea. Per spec, readonly bars an element
3020+ * from constraint validation the same way disabled does.
3021+ * @throws Exception if the test fails
3022+ */
3023+ @ Test
3024+ @ Alerts ({"false" , "false" })
3025+ public void cssNeitherMatchesReadonlyRequiredEmptyTextarea () throws Exception {
3026+ final String html = DOCTYPE_HTML
3027+ + "<html><head>\n "
3028+ + "<script>\n "
3029+ + LOG_TITLE_FUNCTION
3030+ + " function test() {\n "
3031+ + " var t = document.getElementById('t');\n "
3032+ + " log(t.matches(':valid'));\n "
3033+ + " log(t.matches(':invalid'));\n "
3034+ + " }\n "
3035+ + "</script></head>\n "
3036+ + "<body onload='test()'>\n "
3037+ + " <form>\n "
3038+ + " <textarea id='t' required readonly></textarea>\n "
3039+ + " </form>\n "
3040+ + "</body></html>" ;
3041+
3042+ loadPageVerifyTitle2 (html );
3043+ }
3044+
3045+ /**
3046+ * Same as above but with a custom validity message set as well -- readonly
3047+ * barring must take priority over the custom error too, same as disabled
3048+ * does.
3049+ * @throws Exception if the test fails
3050+ */
3051+ @ Test
3052+ @ Alerts ({"false" , "false" })
3053+ public void cssNeitherMatchesReadonlyTextareaEvenWithCustomValidity () throws Exception {
3054+ final String html = DOCTYPE_HTML
3055+ + "<html><head>\n "
3056+ + "<script>\n "
3057+ + LOG_TITLE_FUNCTION
3058+ + " function test() {\n "
3059+ + " var t = document.getElementById('t');\n "
3060+ + " t.setCustomValidity('some error');\n "
3061+ + " log(t.matches(':valid'));\n "
3062+ + " log(t.matches(':invalid'));\n "
3063+ + " }\n "
3064+ + "</script></head>\n "
3065+ + "<body onload='test()'>\n "
3066+ + " <form>\n "
3067+ + " <textarea id='t' readonly>content</textarea>\n "
3068+ + " </form>\n "
3069+ + "</body></html>" ;
3070+
3071+ loadPageVerifyTitle2 (html );
3072+ }
3073+
3074+ /**
3075+ * Redundant-barring sanity check: disabled AND readonly AND required AND a
3076+ * custom validity message, all at once -- still neither pseudo-class should
3077+ * match.
3078+ * @throws Exception if the test fails
3079+ */
3080+ @ Test
3081+ @ Alerts ({"false" , "false" })
3082+ public void cssNeitherMatchesDisabledAndReadonlyTextarea () throws Exception {
3083+ final String html = DOCTYPE_HTML
3084+ + "<html><head>\n "
3085+ + "<script>\n "
3086+ + LOG_TITLE_FUNCTION
3087+ + " function test() {\n "
3088+ + " var t = document.getElementById('t');\n "
3089+ + " t.setCustomValidity('some error');\n "
3090+ + " log(t.matches(':valid'));\n "
3091+ + " log(t.matches(':invalid'));\n "
3092+ + " }\n "
3093+ + "</script></head>\n "
3094+ + "<body onload='test()'>\n "
3095+ + " <form>\n "
3096+ + " <textarea id='t' required disabled readonly></textarea>\n "
3097+ + " </form>\n "
3098+ + "</body></html>" ;
3099+
3100+ loadPageVerifyTitle2 (html );
3101+ }
3102+
3103+ /**
3104+ * Dynamic transition: a required, empty textarea starts out correctly
3105+ * :invalid, then is made readonly at runtime -- must stop matching
3106+ * :invalid (or :valid) once barred, confirming the barred state is
3107+ * evaluated fresh rather than cached from page load.
3108+ * @throws Exception if the test fails
3109+ */
3110+ @ Test
3111+ @ Alerts ({"false" , "true" , "false" , "false" , "false" , "true" })
3112+ public void cssMatchingUpdatesWhenReadonlyToggledAtRuntime () throws Exception {
3113+ final String html = DOCTYPE_HTML
3114+ + "<html><head>\n "
3115+ + "<script>\n "
3116+ + LOG_TITLE_FUNCTION
3117+ + " function test() {\n "
3118+ + " var t = document.getElementById('t');\n "
3119+ + " log(t.matches(':valid'));\n "
3120+ + " log(t.matches(':invalid'));\n "
3121+
3122+ + " t.readOnly = true;\n "
3123+ + " log(t.matches(':valid'));\n "
3124+ + " log(t.matches(':invalid'));\n "
3125+
3126+ + " t.readOnly = false;\n "
3127+ + " log(t.matches(':valid'));\n "
3128+ + " log(t.matches(':invalid'));\n "
3129+ + " }\n "
3130+ + "</script></head>\n "
3131+ + "<body onload='test()'>\n "
3132+ + " <form>\n "
3133+ + " <textarea id='t' required></textarea>\n "
3134+ + " </form>\n "
3135+ + "</body></html>" ;
3136+
3137+ loadPageVerifyTitle2 (html );
3138+ }
3139+
3140+ /**
3141+ * Dynamic transition, disabled variant: same idea as above but toggling
3142+ * disabled instead of readonly.
3143+ * @throws Exception if the test fails
3144+ */
3145+ @ Test
3146+ @ Alerts ({"false" , "true" , "false" , "false" , "false" , "true" })
3147+ public void cssMatchingUpdatesWhenDisabledToggledAtRuntime () throws Exception {
3148+ final String html = DOCTYPE_HTML
3149+ + "<html><head>\n "
3150+ + "<script>\n "
3151+ + LOG_TITLE_FUNCTION
3152+ + " function test() {\n "
3153+ + " var t = document.getElementById('t');\n "
3154+ + " log(t.matches(':valid'));\n "
3155+ + " log(t.matches(':invalid'));\n "
3156+
3157+ + " t.disabled = true;\n "
3158+ + " log(t.matches(':valid'));\n "
3159+ + " log(t.matches(':invalid'));\n "
3160+
3161+ + " t.disabled = false;\n "
3162+ + " log(t.matches(':valid'));\n "
3163+ + " log(t.matches(':invalid'));\n "
3164+ + " }\n "
3165+ + "</script></head>\n "
3166+ + "<body onload='test()'>\n "
3167+ + " <form>\n "
3168+ + " <textarea id='t' required></textarea>\n "
3169+ + " </form>\n "
3170+ + "</body></html>" ;
3171+
3172+ loadPageVerifyTitle2 (html );
3173+ }
3174+
3175+ /**
3176+ * Disabled propagated via an enclosing <fieldset disabled> must bar
3177+ * the textarea from validation the same way an own 'disabled' attribute
3178+ * does -- exercises the isDisabled() parent-chain walk in combination with
3179+ * CSS matching, not just the element's own attribute.
3180+ * @throws Exception if the test fails
3181+ */
3182+ @ Test
3183+ @ Alerts ({"false" , "false" })
3184+ public void cssNeitherMatchesTextareaInDisabledFieldset () throws Exception {
3185+ final String html = DOCTYPE_HTML
3186+ + "<html><head>\n "
3187+ + "<script>\n "
3188+ + LOG_TITLE_FUNCTION
3189+ + " function test() {\n "
3190+ + " var t = document.getElementById('t');\n "
3191+ + " log(t.matches(':valid'));\n "
3192+ + " log(t.matches(':invalid'));\n "
3193+ + " }\n "
3194+ + "</script></head>\n "
3195+ + "<body onload='test()'>\n "
3196+ + " <form>\n "
3197+ + " <fieldset disabled>\n "
3198+ + " <textarea id='t' required></textarea>\n "
3199+ + " </fieldset>\n "
3200+ + " </form>\n "
3201+ + "</body></html>" ;
3202+
3203+ loadPageVerifyTitle2 (html );
3204+ }
28813205}
0 commit comments