test_pattern_attribute.html (9435B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=345512 5 --> 6 <head> 7 <title>Test for Bug 345512</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 10 <style> 11 input { background-color: rgb(0,0,0) !important; } 12 input:valid { background-color: rgb(0,255,0) !important; } 13 input:invalid { background-color: rgb(255,0,0) !important; } 14 </style> 15 </head> 16 <body> 17 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=345512">Mozilla Bug 345512</a> 18 <p id="display"></p> 19 <div id="content" style="display: none"> 20 <input id='i' pattern="tulip" oninvalid="invalidEventHandler(event);"> 21 </div> 22 <pre id="test"> 23 <script type="application/javascript"> 24 25 /** Test for Bug 345512 */ 26 27 var gInvalid = false; 28 29 function invalidEventHandler(e) 30 { 31 is(e.type, "invalid", "Invalid event type should be invalid"); 32 gInvalid = true; 33 } 34 35 function completeValidityCheck(element, alwaysValid, isBarred) 36 { 37 // Check when pattern matches. 38 if (element.type == 'email') { 39 element.pattern = ".*@bar.com"; 40 element.value = "foo@bar.com"; 41 } else if (element.type == 'url') { 42 element.pattern = "http://.*\\.com$"; 43 element.value = "http://mozilla.com"; 44 } else if (element.type == 'file') { 45 element.pattern = "foo"; 46 SpecialPowers.wrap(element).mozSetFileArray([new File(["foo"], "foo")]); 47 } else { 48 element.pattern = "foo"; 49 element.value = "foo"; 50 } 51 52 checkValidPattern(element, true, isBarred); 53 54 // Check when pattern does not match. 55 56 if (element.type == 'email') { 57 element.pattern = ".*@bar.com"; 58 element.value = "foo@foo.com"; 59 } else if (element.type == 'url') { 60 element.pattern = "http://.*\\.com$"; 61 element.value = "http://mozilla.org"; 62 } else if (element.type == 'file') { 63 element.pattern = "foo"; 64 SpecialPowers.wrap(element).mozSetFileArray([new File(["bar"], "bar")]); 65 } else { 66 element.pattern = "foo"; 67 element.value = "bar"; 68 } 69 70 if (!alwaysValid) { 71 checkInvalidPattern(element, true); 72 } else { 73 checkValidPattern(element, true, isBarred); 74 } 75 } 76 77 function checkValidPattern(element, completeCheck, isBarred) 78 { 79 if (completeCheck) { 80 gInvalid = false; 81 82 ok(!element.validity.patternMismatch, 83 "Element should not suffer from pattern mismatch"); 84 ok(element.validity.valid, "Element should be valid"); 85 ok(element.checkValidity(), "Element should be valid"); 86 ok(!gInvalid, "Invalid event shouldn't have been thrown"); 87 is(element.validationMessage, '', 88 "Validation message should be the empty string"); 89 if (element.type != 'radio' && element.type != 'checkbox') { 90 is(window.getComputedStyle(element).getPropertyValue('background-color'), 91 isBarred ? "rgb(0, 0, 0)" : "rgb(0, 255, 0)", 92 "The pseudo-class is not correctly applied"); 93 } 94 } else { 95 ok(!element.validity.patternMismatch, 96 "Element should not suffer from pattern mismatch"); 97 } 98 } 99 100 function checkInvalidPattern(element, completeCheck) 101 { 102 if (completeCheck) { 103 gInvalid = false; 104 105 ok(element.validity.patternMismatch, 106 "Element should suffer from pattern mismatch"); 107 ok(!element.validity.valid, "Element should not be valid"); 108 ok(!element.checkValidity(), "Element should not be valid"); 109 ok(gInvalid, "Invalid event should have been thrown"); 110 is(element.validationMessage, 111 "Please match the requested format.", 112 "Validation message is not valid"); 113 } else { 114 ok(element.validity.patternMismatch, 115 "Element should suffer from pattern mismatch"); 116 } 117 118 if (element.type != 'radio' && element.type != 'checkbox') { 119 is(window.getComputedStyle(element).getPropertyValue('background-color'), 120 "rgb(255, 0, 0)", ":invalid pseudo-class should apply"); 121 } 122 } 123 124 function checkSyntaxError(element) 125 { 126 ok(!element.validity.patternMismatch, 127 "On SyntaxError, element should not suffer"); 128 } 129 130 function checkPatternValidity(element) 131 { 132 element.pattern = "foo"; 133 134 element.value = ''; 135 checkValidPattern(element); 136 137 element.value = "foo"; 138 checkValidPattern(element); 139 140 element.value = "bar"; 141 checkInvalidPattern(element); 142 143 element.value = "foobar"; 144 checkInvalidPattern(element); 145 146 element.value = "foofoo"; 147 checkInvalidPattern(element); 148 149 element.pattern = "foo\"bar"; 150 element.value = "foo\"bar"; 151 checkValidPattern(element); 152 153 element.value = 'foo"bar'; 154 checkValidPattern(element); 155 156 element.pattern = "foo'bar"; 157 element.value = "foo\'bar"; 158 checkValidPattern(element); 159 160 element.pattern = "foo\\(bar"; 161 element.value = "foo(bar"; 162 checkValidPattern(element); 163 164 element.value = "foo"; 165 checkInvalidPattern(element); 166 167 element.pattern = "foo\\)bar"; 168 element.value = "foo)bar"; 169 checkValidPattern(element); 170 171 element.value = "foo"; 172 checkInvalidPattern(element); 173 174 // Check for 'i' flag disabled. Should be case sensitive. 175 element.value = "Foo"; 176 checkInvalidPattern(element); 177 178 // We can't check for the 'g' flag because we only test, we don't execute. 179 // We can't check for the 'm' flag because .value shouldn't contain line breaks. 180 181 // We need '\\\\' because '\\' will produce '\\' and we want to escape the '\' 182 // for the regexp. 183 element.pattern = "foo\\\\bar"; 184 element.value = "foo\\bar"; 185 checkValidPattern(element); 186 187 // We may want to escape the ' in the pattern, but this is a SyntaxError 188 // when unicode flag is set. 189 element.pattern = "foo\\'bar"; 190 element.value = "foo'bar"; 191 checkSyntaxError(element); 192 element.value = "baz"; 193 checkSyntaxError(element); 194 195 // We should check the pattern attribute do not pollute |RegExp.lastParen|. 196 is(RegExp.lastParen, "", "RegExp.lastParen should be the empty string"); 197 198 element.pattern = "(foo)"; 199 element.value = "foo"; 200 checkValidPattern(element); 201 is(RegExp.lastParen, "", "RegExp.lastParen should be the empty string"); 202 203 // That may sound weird but the empty string is a valid pattern value. 204 element.pattern = ""; 205 element.value = ""; 206 checkValidPattern(element); 207 208 element.value = "foo"; 209 checkInvalidPattern(element); 210 211 // Checking some complex patterns. As we are using js regexp mechanism, these 212 // tests doesn't aim to test the regexp mechanism. 213 element.pattern = "\\d{2}\\s\\d{2}\\s\\d{4}" 214 element.value = "01 01 2010" 215 checkValidPattern(element); 216 217 element.value = "01/01/2010" 218 checkInvalidPattern(element); 219 220 element.pattern = "[0-9a-zA-Z]([\\-.\\w]*[0-9a-zA-Z_+])*@([0-9a-zA-Z][\\-\\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9}"; 221 element.value = "foo@bar.com"; 222 checkValidPattern(element); 223 224 element.value = "...@bar.com"; 225 checkInvalidPattern(element); 226 227 element.pattern = "^(?:\\w{3,})$"; 228 element.value = "foo"; 229 checkValidPattern(element); 230 231 element.value = "f"; 232 checkInvalidPattern(element); 233 234 // If @title is specified, it should be added in the validation message. 235 if (element.type == 'email') { 236 element.pattern = "foo@bar.com" 237 element.value = "bar@foo.com"; 238 } else if (element.type == 'url') { 239 element.pattern = "http://mozilla.com"; 240 element.value = "http://mozilla.org"; 241 } else { 242 element.pattern = "foo"; 243 element.value = "bar"; 244 } 245 element.title = "this is an explanation of the regexp"; 246 is(element.validationMessage, 247 "Please match the requested format: " + element.title + ".", 248 "Validation message is not valid"); 249 element.title = ""; 250 is(element.validationMessage, 251 "Please match the requested format.", 252 "Validation message is not valid"); 253 254 element.pattern = "foo"; 255 if (element.type == 'email') { 256 element.value = "bar@foo.com"; 257 } else if (element.type == 'url') { 258 element.value = "http://mozilla.org"; 259 } else { 260 element.value = "bar"; 261 } 262 checkInvalidPattern(element); 263 264 element.removeAttribute('pattern'); 265 checkValidPattern(element, true); 266 267 // Unicode pattern 268 for (var pattern of ["\\u{1F438}{2}", "\u{1F438}{2}", 269 "\\uD83D\\uDC38{2}", "\uD83D\uDC38{2}", 270 "\u{D83D}\u{DC38}{2}"]) { 271 element.pattern = pattern; 272 273 element.value = "\u{1F438}\u{1F438}"; 274 checkValidPattern(element); 275 276 element.value = "\uD83D\uDC38\uD83D\uDC38"; 277 checkValidPattern(element); 278 279 element.value = "\uD83D\uDC38\uDC38"; 280 checkInvalidPattern(element); 281 } 282 283 element.pattern = "\\u{D83D}\\u{DC38}{2}"; 284 285 element.value = "\u{1F438}\u{1F438}"; 286 checkInvalidPattern(element); 287 288 element.value = "\uD83D\uDC38\uD83D\uDC38"; 289 checkInvalidPattern(element); 290 291 element.value = "\uD83D\uDC38\uDC38"; 292 checkInvalidPattern(element); 293 } 294 295 var input = document.getElementById('i'); 296 297 // |validTypes| are the types which accept @pattern 298 // and |invalidTypes| are the ones which do not accept it. 299 var validTypes = Array('text', 'password', 'search', 'tel', 'email', 'url'); 300 var barredTypes = Array('hidden', 'reset', 'button'); 301 var invalidTypes = Array('checkbox', 'radio', 'file', 'number', 'range', 'date', 302 'time', 'color', 'submit', 'image', 'month', 'week', 303 'datetime-local'); 304 305 for (type of validTypes) { 306 input.type = type; 307 completeValidityCheck(input, false); 308 checkPatternValidity(input); 309 } 310 311 for (type of barredTypes) { 312 input.type = type; 313 completeValidityCheck(input, true, true); 314 } 315 316 for (type of invalidTypes) { 317 input.type = type; 318 completeValidityCheck(input, true); 319 } 320 321 </script> 322 </pre> 323 </body> 324 </html>