innertext-with-white-spaces.html (19121B)
1 <!doctype html> 2 <html> 3 <meta charset="utf-8"> 4 <meta name="variant" content="?white-space=normal"> 5 <meta name="variant" content="?white-space=pre"> 6 <meta name="variant" content="?white-space=pre-line"> 7 <meta name="variant" content="?white-space=pre-wrap"> 8 <meta name="variant" content="?white-space=normal&contenteditable=true"> 9 <meta name="variant" content="?white-space=pre&contenteditable=true"> 10 <meta name="variant" content="?white-space=pre-line&contenteditable=true"> 11 <meta name="variant" content="?white-space=pre-wrap&contenteditable=true"> 12 <meta name="variant" content="?white-space=normal&contenteditable=plaintext-only"> 13 <meta name="variant" content="?white-space=pre&contenteditable=plaintext-only"> 14 <meta name="variant" content="?white-space=pre-line&contenteditable=plaintext-only"> 15 <meta name="variant" content="?white-space=pre-wrap&contenteditable=plaintext-only"> 16 <title>Test invisible white-spaces do not appear in the result of `.innerText`</title> 17 <link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute"> 18 <link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#rendered-text-collection-steps"><!-- Especially, this tests the step 4 --> 19 <link rel="help" href="https://drafts.csswg.org/css-text/#white-space-processing"> 20 <script src="/resources/testharness.js"></script> 21 <script src="/resources/testharnessreport.js"></script> 22 <script> 23 "use strict"; 24 25 const searchParams = new URLSearchParams(document.location.search); 26 const whiteSpace = searchParams.get("white-space"); 27 const isWhiteSpacesCollapsible = whiteSpace == "normal" || whiteSpace == "pre-line"; 28 const isNewLineCollapsible = whiteSpace == "normal"; 29 const contenteditable = searchParams.get("contenteditable"); 30 31 addEventListener("DOMContentLoaded", () => { 32 const div = document.querySelector("div"); 33 div.style.whiteSpace = whiteSpace; 34 if (contenteditable) { 35 div.setAttribute("contenteditable", contenteditable); 36 } 37 for (const data of [ 38 // Leading white-spaces are invisible if they are collapsible. 39 { 40 desc: "Leading white-space should not appear if white-spaces are collapsible", 41 innerHTML: " abc", 42 expected: isWhiteSpacesCollapsible ? "abc" : " abc", 43 }, 44 { 45 desc: "Leading white-spaces should not appear if white-spaces are collapsible", 46 innerHTML: " abc", 47 expected: isWhiteSpacesCollapsible ? "abc" : " abc", 48 }, 49 { 50 desc: "Leading tab should not appear if white-spaces are collapsible", 51 innerHTML: "\tabc", 52 expected: isWhiteSpacesCollapsible ? "abc" : "\tabc", 53 }, 54 { 55 desc: "Leading tabs should not appear if white-spaces are collapsible", 56 innerHTML: "\t\tabc", 57 expected: isWhiteSpacesCollapsible ? "abc" : "\t\tabc", 58 }, 59 { 60 desc: "Leading linefeed should not appear if it's collapsible", 61 innerHTML: "\nabc", 62 expected: isNewLineCollapsible ? "abc" : "\nabc", 63 }, 64 { 65 desc: "Leading linefeeds should not appear if they are collapsible", 66 innerHTML: "\n\nabc", 67 expected: isNewLineCollapsible ? "abc" : "\n\nabc", 68 }, 69 { 70 desc: "Leading mixed white-spaces should not appear if they are collapsible", 71 innerHTML: " \n\t abc", 72 expected: isNewLineCollapsible 73 ? "abc" 74 : (isWhiteSpacesCollapsible 75 // Surrounding collapsible white-spaces of preformatted line break should be invisible. 76 ? "\nabc" 77 : " \n\t abc"), 78 }, 79 { 80 desc: "Leading CR should be normalized to LF and should not appear if linefeeds are collapsible", 81 innerHTML: "\rabc", 82 expected: isNewLineCollapsible ? "abc" : "\nabc", 83 }, 84 { 85 desc: "Leading CRs should be normalized to LFs and should not appear if linefeeds are collapsible", 86 innerHTML: "\r\rabc", 87 expected: isNewLineCollapsible ? "abc" : "\n\nabc", 88 }, 89 // Trailing white-spaces are invisible if they are collapsible. 90 { 91 desc: "Trailing white-space should not appear if white-spaces are collapsible", 92 innerHTML: "abc ", 93 expected: isWhiteSpacesCollapsible ? "abc" : "abc ", 94 }, 95 { 96 desc: "Trailing white-spaces should not appear if white-spaces are collapsible", 97 innerHTML: "abc ", 98 expected: isWhiteSpacesCollapsible ? "abc" : "abc ", 99 }, 100 { 101 desc: "Trailing tab should not appear if white-spaces are collapsible", 102 innerHTML: "abc\t", 103 expected: isWhiteSpacesCollapsible ? "abc" : "abc\t", 104 }, 105 { 106 desc: "Trailing tabs should not appear if white-spaces are collapsible", 107 innerHTML: "abc\t\t", 108 expected: isWhiteSpacesCollapsible ? "abc" : "abc\t\t", 109 }, 110 { 111 desc: "Trailing linefeed should not appear if it's collapsible", 112 innerHTML: "abc\n", 113 expected: isNewLineCollapsible ? "abc" : "abc\n", 114 }, 115 { 116 desc: "Trailing linefeeds should not appear if they are collapsible", 117 innerHTML: "abc\n\n", 118 expected: isNewLineCollapsible ? "abc" : "abc\n\n", 119 }, 120 { 121 desc: "Trailing mixed white-spaces should not appear if they are collapsible", 122 innerHTML: "abc\t \n ", 123 expected: isNewLineCollapsible 124 ? "abc" 125 : (isWhiteSpacesCollapsible 126 // Surrounding collapsible white-spaces of preformatted line break should be invisible. 127 ? "abc\n" 128 : "abc\t \n "), 129 }, 130 { 131 desc: "Trailing CR should be normalized to LF and should not appear if linefeeds are collapsible", 132 innerHTML: "abc\r", 133 expected: isNewLineCollapsible ? "abc" : "abc\n", 134 }, 135 { 136 desc: "Trailing CRs should be normalized to LFs and should not appear if linefeeds are collapsible", 137 innerHTML: "abc\r\r", 138 expected: isNewLineCollapsible ? "abc" : "abc\n\n", 139 }, 140 // Only white-spaces. 141 { 142 desc: "Only single collapsible space should be invisible", 143 innerHTML: " ", 144 expected: isWhiteSpacesCollapsible ? "" : " ", 145 }, 146 { 147 desc: "Only single collapsible tab should be invisible", 148 innerHTML: "\t", 149 expected: isWhiteSpacesCollapsible ? "" : "\t", 150 }, 151 { 152 desc: "Only single collapsible linefeed should be invisible", 153 innerHTML: "\n", 154 expected: isNewLineCollapsible ? "" : "\n", 155 }, 156 { 157 desc: "Only single collapsible CR should be invisible", 158 innerHTML: "\r", 159 expected: isNewLineCollapsible ? "" : "\n", 160 }, 161 { 162 desc: "Only multiple collapsible spaces should be invisible", 163 innerHTML: " ", 164 expected: isWhiteSpacesCollapsible ? "" : " ", 165 }, 166 { 167 desc: "Only multiple collapsible tabs should be invisible", 168 innerHTML: "\t\t\t", 169 expected: isWhiteSpacesCollapsible ? "" : "\t\t\t", 170 }, 171 { 172 desc: "Only multiple collapsible linefeeds should be invisible", 173 innerHTML: "\n\n\n", 174 expected: isNewLineCollapsible ? "" : "\n\n\n", 175 }, 176 { 177 desc: "Only multiple collapsible CRs should be invisible", 178 innerHTML: "\r\r\r", 179 expected: isNewLineCollapsible ? "" : "\n\n\n", 180 }, 181 // Between words. 182 { 183 desc: "Single collapsible tab should be converted to an ASCII space", 184 innerHTML: "abc\tdef", 185 expected: isWhiteSpacesCollapsible ? "abc def" : "abc\tdef", 186 }, 187 { 188 desc: "Single collapsible linefeed should be converted to an ASCII space", 189 innerHTML: "abc\ndef", 190 expected: isNewLineCollapsible ? "abc def" : "abc\ndef", 191 }, 192 { 193 desc: "Single collapsible CR should be converted to an ASCII space, or otherwise, a linefeed", 194 innerHTML: "abc\rdef", 195 expected: isNewLineCollapsible ? "abc def" : "abc\ndef", 196 }, 197 { 198 desc: "Multiple white-spaces between words may be invisible if they are collapsible", 199 innerHTML: "abc def", 200 expected: isWhiteSpacesCollapsible ? "abc def" : "abc def", 201 }, 202 { 203 desc: "Multiple mixed white-spaces between words may be invisible if they are collapsible #1", 204 innerHTML: "abc\t def", 205 expected: isWhiteSpacesCollapsible ? "abc def" : "abc\t def", 206 }, 207 { 208 desc: "Multiple mixed white-spaces between words may be invisible if they are collapsible #2", 209 innerHTML: "abc \tdef", 210 expected: isWhiteSpacesCollapsible ? "abc def" : "abc \tdef", 211 }, 212 { 213 desc: "Multiple mixed white-spaces between words may be invisible if they are collapsible #3", 214 innerHTML: "abc\n def", 215 expected: isNewLineCollapsible 216 ? "abc def" 217 : (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n def"), 218 }, 219 { 220 desc: "Multiple mixed white-spaces between words may be invisible if they are collapsible #4", 221 innerHTML: "abc \ndef", 222 expected: isNewLineCollapsible 223 ? "abc def" 224 : (isWhiteSpacesCollapsible ? "abc\ndef" : "abc \ndef"), 225 }, 226 // Before <br> 227 { 228 desc: "white-space before <br> should be invisible if it's collapsible", 229 innerHTML: "abc <br>def", 230 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc \ndef", 231 }, 232 { 233 desc: "white-spaces before <br> should be invisible if they are collapsible", 234 innerHTML: "abc <br>def", 235 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc \ndef", 236 }, 237 { 238 desc: "tab before <br> should be invisible if it's collapsible", 239 innerHTML: "abc\t<br>def", 240 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\t\ndef", 241 }, 242 { 243 desc: "linefeed before <br> should be invisible if it's collapsible", 244 innerHTML: "abc\n<br>def", 245 expected: isNewLineCollapsible 246 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 247 : "abc\n\ndef", 248 }, 249 { 250 desc: "CR before <br> should be invisible if it's collapsible", 251 innerHTML: "abc\r<br>def", 252 expected: isNewLineCollapsible 253 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 254 : "abc\n\ndef", 255 }, 256 // After <br> 257 { 258 desc: "white-space after <br> should be invisible if it's collapsible", 259 innerHTML: "abc<br> def", 260 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n def", 261 }, 262 { 263 desc: "white-spaces after <br> should be invisible if they are collapsible", 264 innerHTML: "abc<br> def", 265 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n def", 266 }, 267 { 268 desc: "tab after <br> should be invisible if it's collapsible", 269 innerHTML: "abc<br>\tdef", 270 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\tdef", 271 }, 272 { 273 desc: "linefeed after <br> should be invisible if it's collapsible", 274 innerHTML: "abc<br>\ndef", 275 expected: isNewLineCollapsible 276 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 277 : "abc\n\ndef", 278 }, 279 { 280 desc: "CR after <br> should be invisible if it's collapsible", 281 innerHTML: "abc<br>\rdef", 282 expected: isNewLineCollapsible 283 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 284 : "abc\n\ndef", 285 }, 286 // Between <br>s 287 { 288 desc: "white-space between <br>s should be invisible if it's collapsible", 289 innerHTML: "abc<br> <br>def", 290 expected: isWhiteSpacesCollapsible ? "abc\n\ndef" : "abc\n \ndef", 291 }, 292 { 293 desc: "white-spaces between <br>s should be invisible if they are collapsible", 294 innerHTML: "abc<br> <br>def", 295 expected: isWhiteSpacesCollapsible ? "abc\n\ndef" : "abc\n \ndef", 296 }, 297 { 298 desc: "tab between <br>s should be invisible if it's collapsible", 299 innerHTML: "abc<br>\t<br>def", 300 expected: isWhiteSpacesCollapsible ? "abc\n\ndef" : "abc\n\t\ndef", 301 }, 302 { 303 desc: "linefeed between <br>s should be invisible if it's collapsible", 304 innerHTML: "abc<br>\n<br>def", 305 expected: isNewLineCollapsible 306 ? (isWhiteSpacesCollapsible ? "abc\n\ndef" : "abc\n\n\ndef") 307 : "abc\n\n\ndef", 308 }, 309 { 310 desc: "CR between <br>s should be invisible if it's collapsible", 311 innerHTML: "abc<br>\r<br>def", 312 expected: isNewLineCollapsible 313 ? (isWhiteSpacesCollapsible ? "abc\n\ndef" : "abc\n\n\ndef") 314 : "abc\n\n\ndef", 315 }, 316 // Before <hr> 317 { 318 desc: "white-space before <hr> should be invisible if it's collapsible", 319 innerHTML: "abc <hr>def", 320 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc \ndef", 321 }, 322 { 323 desc: "white-spaces before <hr> should be invisible if they are collapsible", 324 innerHTML: "abc <hr>def", 325 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc \ndef", 326 }, 327 { 328 desc: "tab before <hr> should be invisible if it's collapsible", 329 innerHTML: "abc\t<hr>def", 330 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\t\ndef", 331 }, 332 { 333 desc: "linefeed before <hr> should be invisible if it's collapsible", 334 innerHTML: "abc\n<hr>def", 335 expected: isNewLineCollapsible 336 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 337 : "abc\n\ndef", 338 }, 339 { 340 desc: "CR before <hr> should be invisible if it's collapsible", 341 innerHTML: "abc\r<hr>def", 342 expected: isNewLineCollapsible 343 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 344 : "abc\n\ndef", 345 }, 346 // After <hr> 347 { 348 desc: "white-space after <hr> should be invisible if it's collapsible", 349 innerHTML: "abc<hr> def", 350 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n def", 351 }, 352 { 353 desc: "white-spaces after <hr> should be invisible if they are collapsible", 354 innerHTML: "abc<hr> def", 355 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n def", 356 }, 357 { 358 desc: "tab after <hr> should be invisible if it's collapsible", 359 innerHTML: "abc<hr>\tdef", 360 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\tdef", 361 }, 362 { 363 desc: "linefeed after <hr> should be invisible if it's collapsible", 364 innerHTML: "abc<hr>\ndef", 365 expected: isNewLineCollapsible 366 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 367 : "abc\n\ndef", 368 }, 369 { 370 desc: "CR after <hr> should be invisible if it's collapsible", 371 innerHTML: "abc<hr>\rdef", 372 expected: isNewLineCollapsible 373 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 374 : "abc\n\ndef", 375 }, 376 // Between <hr>s 377 { 378 desc: "white-space between <hr>s should be invisible if it's collapsible", 379 innerHTML: "abc<hr> <hr>def", 380 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n \ndef", 381 }, 382 { 383 desc: "white-spaces between <hr>s should be invisible if they are collapsible", 384 innerHTML: "abc<hr> <hr>def", 385 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n \ndef", 386 }, 387 { 388 desc: "tab between <hr>s should be invisible if it's collapsible", 389 innerHTML: "abc<hr>\t<hr>def", 390 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\t\ndef", 391 }, 392 { 393 desc: "linefeed between <hr>s should be invisible if it's collapsible", 394 innerHTML: "abc<hr>\n<hr>def", 395 expected: isNewLineCollapsible 396 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\n\ndef") 397 : "abc\n\n\ndef", 398 }, 399 { 400 desc: "CR between <hr>s should be invisible if it's collapsible", 401 innerHTML: "abc<hr>\r<hr>def", 402 expected: isNewLineCollapsible 403 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\n\ndef") 404 : "abc\n\n\ndef", 405 }, 406 // Before <div> 407 { 408 desc: "white-space before <div> should be invisible if it's collapsible", 409 innerHTML: "abc <div></div>def", 410 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc \ndef", 411 }, 412 { 413 desc: "white-spaces before <div> should be invisible if they are collapsible", 414 innerHTML: "abc <div></div>def", 415 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc \ndef", 416 }, 417 { 418 desc: "tab before <div> should be invisible if it's collapsible", 419 innerHTML: "abc\t<div></div>def", 420 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\t\ndef", 421 }, 422 { 423 desc: "linefeed before <div> should be invisible if it's collapsible", 424 innerHTML: "abc\n<div></div>def", 425 expected: isNewLineCollapsible 426 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 427 : "abc\n\ndef", 428 }, 429 { 430 desc: "CR before <div> should be invisible if it's collapsible", 431 innerHTML: "abc\r<div></div>def", 432 expected: isNewLineCollapsible 433 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 434 : "abc\n\ndef", 435 }, 436 // After <div> 437 { 438 desc: "white-space after <div> should be invisible if it's collapsible", 439 innerHTML: "abc<div></div> def", 440 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n def", 441 }, 442 { 443 desc: "white-spaces after <div> should be invisible if they are collapsible", 444 innerHTML: "abc<div></div> def", 445 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n def", 446 }, 447 { 448 desc: "tab after <div> should be invisible if it's collapsible", 449 innerHTML: "abc<div></div>\tdef", 450 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\tdef", 451 }, 452 { 453 desc: "linefeed after <div> should be invisible if it's collapsible", 454 innerHTML: "abc<div></div>\ndef", 455 expected: isNewLineCollapsible 456 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 457 : "abc\n\ndef", 458 }, 459 { 460 desc: "CR after <div> should be invisible if it's collapsible", 461 innerHTML: "abc<div></div>\rdef", 462 expected: isNewLineCollapsible 463 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\ndef") 464 : "abc\n\ndef", 465 }, 466 // Between <div>s 467 { 468 desc: "white-space between <div>s should be invisible if it's collapsible", 469 innerHTML: "abc<div></div> <div></div>def", 470 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n \ndef", 471 }, 472 { 473 desc: "white-spaces between <div>s should be invisible if they are collapsible", 474 innerHTML: "abc<div></div> <div></div>def", 475 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n \ndef", 476 }, 477 { 478 desc: "tab between <div>s should be invisible if it's collapsible", 479 innerHTML: "abc<div></div>\t<div></div>def", 480 expected: isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\t\ndef", 481 }, 482 { 483 desc: "linefeed between <div>s should be invisible if it's collapsible", 484 innerHTML: "abc<div></div>\n<div></div>def", 485 expected: isNewLineCollapsible 486 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\n\ndef") 487 : "abc\n\n\ndef", 488 }, 489 { 490 desc: "CR between <div>s should be invisible if it's collapsible", 491 innerHTML: "abc<div></div>\r<div></div>def", 492 expected: isNewLineCollapsible 493 ? (isWhiteSpacesCollapsible ? "abc\ndef" : "abc\n\n\ndef") 494 : "abc\n\n\ndef", 495 }, 496 ]) { 497 test(() => { 498 div.innerHTML = data.innerHTML; 499 assert_equals(div.innerText, data.expected); 500 }, data.desc); 501 } 502 }, {once: true}); 503 </script> 504 </head> 505 <body> 506 <div></div> 507 </body> 508 </html>