exec-command-with-text-editor.tentative.html (26265B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title>Test that execCommand with <input> or <textarea></title> 4 <meta name="variant" content="?type=text"> 5 <meta name="variant" content="?type=textarea"> 6 <meta name="variant" content="?type=password"> 7 <script src=/resources/testharness.js></script> 8 <script src=/resources/testharnessreport.js></script> 9 <script src="/resources/testdriver.js"></script> 10 <script src='/resources/testdriver-vendor.js'></script> 11 <div id="container"></div> 12 <script> 13 "use strict"; 14 15 setup({explicit_done: true}); 16 const testingType = new URLSearchParams(document.location.search).get("type"); 17 18 /** 19 * This test checks whether document.execCommand() does something expected or 20 * not in <input> and <textarea> with/without contenteditable parent. Although 21 * this is not standardized even by any drafts. So, this test uses expected 22 * values which may be expected by web developers. 23 */ 24 async function runTests() { 25 let container = document.getElementById("container"); 26 switch (testingType) { 27 case "text": 28 case "password": 29 container.innerHTML = `Here <b>is</b> Text: <input id="target" type="${testingType}">`; 30 await runTest(document.getElementById("target"), `In <input type="${testingType}">`); 31 container.setAttribute("contenteditable", "true"); 32 container.innerHTML = `Here <b>is</b> Text: <input id="target" type="${testingType}">`; 33 await runTest(document.getElementById("target"), `In <input type="${testingType}"> in contenteditable`); 34 break; 35 case "textarea": 36 container.innerHTML = "Here <b>is</b> Text: <textarea id=\"target\"></textarea>"; 37 await runTest(document.getElementById("target"), "In <textarea>"); 38 container.setAttribute("contenteditable", "true"); 39 container.innerHTML = "Here <b>is</b> Text: <textarea id=\"target\"></textarea>"; 40 await runTest(document.getElementById("target"), "In <textarea> in contenteditable"); 41 break; 42 } 43 done(); 44 } 45 46 async function runTest(aTarget, aDescription) { 47 const kIsTextArea = testingType == "textarea"; 48 const kTests = [ 49 /** 50 * command: command name of execCommand(). 51 * param: param for the command. i.e., the 3rd param of execCommand(). 52 * value: initial value of <input> or <textarea>. must have a pair of 53 * "[" and "]" for specifying selection range. 54 * expectedValue: expected value of <input> or <textarea> after calling 55 * execCommand() with command and param. must have a 56 * pair of "[" and "]" for specifying selection range. 57 * expectedExecCommandResult: expected bool result of execCommand(). 58 * expectedCommandSupported: expected bool result of queryCommandSupported(). 59 * expectedCommandEnabled: expected bool result of queryCommandEnabled(). 60 * beforeinputExpected: if "beforeinput" event shouldn't be fired, set 61 * null. otherwise, expected inputType value and 62 * target element. 63 * inputExpected: if "input" event shouldn't be fired, set null. 64 * otherwise, expected inputType value and target element. 65 */ 66 {command: "getHTML", param: null, 67 value: "a[b]c", expectedValue: "a[b]c", 68 expectedExecCommandResult: false, 69 expectedCommandSupported: false, 70 expectedCommandEnabled: false, 71 beforeinputExpected: null, inputExpected: null, 72 }, 73 {command: "bold", param: "bold", 74 value: "a[b]c", expectedValue: "a[b]c", 75 expectedExecCommandResult: false, 76 expectedCommandSupported: true, 77 expectedCommandEnabled: false, 78 beforeinputExpected: null, inputExpected: null, 79 }, 80 {command: "italic", param: null, 81 value: "a[b]c", expectedValue: "a[b]c", 82 expectedExecCommandResult: false, 83 expectedCommandSupported: true, 84 expectedCommandEnabled: false, 85 beforeinputExpected: null, inputExpected: null, 86 }, 87 {command: "underline", param: null, 88 value: "a[b]c", expectedValue: "a[b]c", 89 expectedExecCommandResult: false, 90 expectedCommandSupported: true, 91 expectedCommandEnabled: false, 92 beforeinputExpected: null, inputExpected: null, 93 }, 94 {command: "strikethrough", param: null, 95 value: "a[b]c", expectedValue: "a[b]c", 96 expectedExecCommandResult: false, 97 expectedCommandSupported: true, 98 expectedCommandEnabled: false, 99 beforeinputExpected: null, inputExpected: null, 100 }, 101 {command: "superscript", param: null, 102 value: "a[b]c", expectedValue: "a[b]c", 103 expectedExecCommandResult: false, 104 expectedCommandSupported: true, 105 expectedCommandEnabled: false, 106 beforeinputExpected: null, inputExpected: null, 107 }, 108 // Should return true for web apps implementing custom editor. 109 {command: "cut", param: null, 110 value: "ab[]c", expectedValue: "ab[]c", 111 expectedExecCommandResult: false, 112 expectedCommandSupported: true, 113 expectedCommandEnabled: false, 114 beforeinputExpected: null, inputExpected: null, 115 }, 116 {command: "cut", param: null, 117 value: "a[b]c", expectedValue: "a[]c", 118 expectedExecCommandResult: true, 119 expectedCommandSupported: true, 120 expectedCommandEnabled: true, 121 beforeinputExpected: null, 122 inputExpected: { inputType: "deleteByCut", target: aTarget }, 123 }, 124 // Should return true for web apps implementing custom editor. 125 {command: "copy", param: null, 126 value: "abc[]d", expectedValue: "abc[]d", 127 expectedExecCommandResult: false, 128 expectedCommandSupported: true, 129 expectedCommandEnabled: false, 130 beforeinputExpected: null, inputExpected: null, 131 }, 132 {command: "copy", param: null, 133 value: "a[bc]d", expectedValue: "a[bc]d", 134 expectedExecCommandResult: true, 135 expectedCommandSupported: true, 136 expectedCommandEnabled: true, 137 beforeinputExpected: null, inputExpected: null, 138 }, 139 {command: "paste", param: null, 140 value: "a[]c", expectedValue: "abc[]c", 141 expectedExecCommandResult: true, 142 expectedCommandSupported: true, 143 expectedCommandEnabled: true, 144 beforeinputExpected: null, 145 inputExpected: { inputType: "insertFromPaste", target: aTarget }, 146 }, 147 {command: "delete", param: null, 148 value: "ab[]c", expectedValue: "a[]c", 149 expectedExecCommandResult: true, 150 expectedCommandSupported: true, 151 expectedCommandEnabled: true, 152 beforeinputExpected: null, 153 inputExpected: { inputType: "deleteContentBackward", target: aTarget }, 154 }, 155 {command: "delete", param: null, 156 value: "a[b]c", expectedValue: "a[]c", 157 expectedExecCommandResult: true, 158 expectedCommandSupported: true, 159 expectedCommandEnabled: true, 160 beforeinputExpected: null, 161 inputExpected: { inputType: "deleteContentBackward", target: aTarget }, 162 }, 163 {command: "forwarddelete", param: null, 164 value: "a[b]c", expectedValue: "a[]c", 165 expectedExecCommandResult: true, 166 expectedCommandSupported: true, 167 expectedCommandEnabled: true, 168 beforeinputExpected: null, 169 inputExpected: { inputType: "deleteContentForward", target: aTarget }, 170 }, 171 {command: "forwarddelete", param: null, 172 value: "a[]bc", expectedValue: "a[]c", 173 expectedExecCommandResult: true, 174 expectedCommandSupported: true, 175 expectedCommandEnabled: true, 176 beforeinputExpected: null, 177 inputExpected: { inputType: "deleteContentForward", target: aTarget }, 178 }, 179 {command: "selectall", param: null, 180 value: "a[b]c", expectedValue: "[abc]", 181 expectedExecCommandResult: true, 182 expectedCommandSupported: true, 183 expectedCommandEnabled: true, 184 beforeinputExpected: null, inputExpected: null, 185 }, 186 // Setting value should forget any transactions. 187 {command: "undo", param: null, 188 value: "[a]bc", expectedValue: "[a]bc", 189 expectedExecCommandResult: false, 190 expectedCommandSupported: true, 191 expectedCommandEnabled: false, 192 beforeinputExpected: null, inputExpected: null, 193 }, 194 {command: "undo", param: null, 195 value: "a[b]c", expectedValue: "a[b]c", 196 initFunc: () => { 197 document.execCommand("delete", false, null); 198 }, 199 expectedExecCommandResult: true, 200 expectedCommandSupported: true, 201 expectedCommandEnabled: true, 202 beforeinputExpected: null, 203 inputExpected: { inputType: "historyUndo", target: aTarget }, 204 }, 205 // Setting value should forget any transactions. 206 {command: "redo", param: null, 207 value: "[a]bc", expectedValue: "[a]bc", 208 expectedExecCommandResult: false, 209 expectedCommandSupported: true, 210 expectedCommandEnabled: false, 211 beforeinputExpected: null, inputExpected: null, 212 }, 213 {command: "redo", param: null, 214 value: "a[b]c", expectedValue: "a[]c", 215 initFunc: () => { 216 document.execCommand("delete", false, null); 217 document.execCommand("undo", false, null); 218 }, 219 expectedExecCommandResult: true, 220 expectedCommandSupported: true, 221 expectedCommandEnabled: true, 222 beforeinputExpected: null, 223 inputExpected: { inputType: "historyRedo", target: aTarget }, 224 }, 225 {command: "indent", param: null, 226 value: "a[b]c", expectedValue: "a[b]c", 227 expectedExecCommandResult: false, 228 expectedCommandSupported: true, 229 expectedCommandEnabled: false, 230 beforeinputExpected: null, inputExpected: null, 231 }, 232 {command: "outdent", param: null, 233 value: "a[b]c", expectedValue: "a[b]c", 234 expectedExecCommandResult: false, 235 expectedCommandSupported: true, 236 expectedCommandEnabled: false, 237 beforeinputExpected: null, inputExpected: null, 238 }, 239 {command: "backcolor", param: "#000000", 240 value: "a[b]c", expectedValue: "a[b]c", 241 expectedExecCommandResult: false, 242 expectedCommandSupported: true, 243 expectedCommandEnabled: false, 244 beforeinputExpected: null, inputExpected: null, 245 }, 246 {command: "forecolor", param: "#000000", 247 value: "a[b]c", expectedValue: "a[b]c", 248 expectedExecCommandResult: false, 249 expectedCommandSupported: true, 250 expectedCommandEnabled: false, 251 beforeinputExpected: null, inputExpected: null, 252 }, 253 {command: "hilitecolor", param: "#000000", 254 value: "a[b]c", expectedValue: "a[b]c", 255 expectedExecCommandResult: false, 256 expectedCommandSupported: true, 257 expectedCommandEnabled: false, 258 beforeinputExpected: null, inputExpected: null, 259 }, 260 {command: "fontname", param: "DummyFont", 261 value: "a[b]c", expectedValue: "a[b]c", 262 expectedExecCommandResult: false, 263 expectedCommandSupported: true, 264 expectedCommandEnabled: false, 265 beforeinputExpected: null, inputExpected: null, 266 }, 267 {command: "fontsize", param: "5", 268 value: "a[b]c", expectedValue: "a[b]c", 269 expectedExecCommandResult: false, 270 expectedCommandSupported: true, 271 expectedCommandEnabled: false, 272 beforeinputExpected: null, inputExpected: null, 273 }, 274 {command: "increasefontsize", param: null, 275 value: "a[b]c", expectedValue: "a[b]c", 276 expectedExecCommandResult: false, 277 expectedCommandSupported: false, 278 expectedCommandEnabled: false, 279 beforeinputExpected: null, inputExpected: null, 280 }, 281 {command: "decreasefontsize", param: null, 282 value: "a[b]c", expectedValue: "a[b]c", 283 expectedExecCommandResult: false, 284 expectedCommandSupported: false, 285 expectedCommandEnabled: false, 286 beforeinputExpected: null, inputExpected: null, 287 }, 288 {command: "inserthorizontalrule", param: null, 289 value: "a[b]c", expectedValue: "a[b]c", 290 expectedExecCommandResult: false, 291 expectedCommandSupported: true, 292 expectedCommandEnabled: false, 293 beforeinputExpected: null, inputExpected: null, 294 }, 295 {command: "createlink", param: "foo.html", 296 value: "a[b]c", expectedValue: "a[b]c", 297 expectedExecCommandResult: false, 298 expectedCommandSupported: true, 299 expectedCommandEnabled: false, 300 beforeinputExpected: null, inputExpected: null, 301 }, 302 {command: "insertimage", param: "no-image.png", 303 value: "a[b]c", expectedValue: "a[b]c", 304 expectedExecCommandResult: false, 305 expectedCommandSupported: true, 306 expectedCommandEnabled: false, 307 beforeinputExpected: null, inputExpected: null, 308 }, 309 {command: "inserthtml", param: "<b>inserted</b>", 310 value: "a[b]c", expectedValue: "ainserted[]c", 311 expectedExecCommandResult: true, 312 expectedCommandSupported: true, 313 expectedCommandEnabled: true, 314 beforeinputExpected: null, 315 inputExpected: { inputType: "insertText", target: aTarget }, 316 }, 317 {command: "inserttext", param: "**inserted**", 318 value: "a[b]c", expectedValue: "a**inserted**[]c", 319 expectedExecCommandResult: true, 320 expectedCommandSupported: true, 321 expectedCommandEnabled: true, 322 beforeinputExpected: null, 323 inputExpected: { inputType: "insertText", target: aTarget }, 324 }, 325 {command: "inserttext", param: "", 326 value: "a[b]c", expectedValue: "a[]c", 327 expectedExecCommandResult: true, 328 expectedCommandSupported: true, 329 expectedCommandEnabled: true, 330 beforeinputExpected: null, 331 inputExpected: { inputType: "insertText", target: aTarget }, 332 }, 333 {command: "justifyleft", param: null, 334 value: "a[b]c", expectedValue: "a[b]c", 335 expectedExecCommandResult: false, 336 expectedCommandSupported: true, 337 expectedCommandEnabled: false, 338 beforeinputExpected: null, inputExpected: null, 339 }, 340 {command: "justifyright", param: null, 341 value: "a[b]c", expectedValue: "a[b]c", 342 expectedExecCommandResult: false, 343 expectedCommandSupported: true, 344 expectedCommandEnabled: false, 345 beforeinputExpected: null, inputExpected: null, 346 }, 347 {command: "justifycenter", param: null, 348 value: "a[b]c", expectedValue: "a[b]c", 349 expectedExecCommandResult: false, 350 expectedCommandSupported: true, 351 expectedCommandEnabled: false, 352 beforeinputExpected: null, inputExpected: null, 353 }, 354 {command: "justifyfull", param: null, 355 value: "a[b]c", expectedValue: "a[b]c", 356 expectedExecCommandResult: false, 357 expectedCommandSupported: true, 358 expectedCommandEnabled: false, 359 beforeinputExpected: null, inputExpected: null, 360 }, 361 {command: "removeformat", param: null, 362 value: "a[b]c", expectedValue: "a[b]c", 363 expectedExecCommandResult: false, 364 expectedCommandSupported: true, 365 expectedCommandEnabled: false, 366 beforeinputExpected: null, inputExpected: null, 367 }, 368 {command: "unlink", param: null, 369 value: "a[b]c", expectedValue: "a[b]c", 370 expectedExecCommandResult: false, 371 expectedCommandSupported: true, 372 expectedCommandEnabled: false, 373 beforeinputExpected: null, inputExpected: null, 374 }, 375 {command: "insertorderedlist", param: null, 376 value: "a[b]c", expectedValue: "a[b]c", 377 expectedExecCommandResult: false, 378 expectedCommandSupported: true, 379 expectedCommandEnabled: false, 380 beforeinputExpected: null, inputExpected: null, 381 }, 382 {command: "insertunorderedlist", param: null, 383 value: "a[b]c", expectedValue: "a[b]c", 384 expectedExecCommandResult: false, 385 expectedCommandSupported: true, 386 expectedCommandEnabled: false, 387 beforeinputExpected: null, inputExpected: null, 388 }, 389 {command: "insertparagraph", param: null, 390 value: "a[b]c", expectedValue: kIsTextArea ? "a\n[]c" : "a[b]c", 391 expectedExecCommandResult: kIsTextArea, 392 expectedCommandSupported: true, 393 expectedCommandEnabled: kIsTextArea, 394 beforeinputExpected: null, 395 inputExpected: kIsTextArea ? { inputType: "insertParagraph", target: aTarget } : null, 396 }, 397 {command: "insertlinebreak", param: null, 398 value: "a[b]c", expectedValue: kIsTextArea ? "a\n[]c" : "a[b]c", 399 expectedExecCommandResult: kIsTextArea, 400 expectedCommandSupported: true, 401 expectedCommandEnabled: kIsTextArea, 402 beforeinputExpected: null, 403 inputExpected: kIsTextArea ? { inputType: "insertLineBreak", target: aTarget } : null, 404 }, 405 {command: "formatblock", param: "div", 406 value: "a[b]c", expectedValue: "a[b]c", 407 expectedExecCommandResult: false, 408 expectedCommandSupported: true, 409 expectedCommandEnabled: false, 410 beforeinputExpected: null, inputExpected: null, 411 }, 412 {command: "heading", param: "h1", 413 value: "a[b]c", expectedValue: "a[b]c", 414 expectedExecCommandResult: false, 415 expectedCommandSupported: false, 416 expectedCommandEnabled: false, 417 beforeinputExpected: null, inputExpected: null, 418 }, 419 {command: "styleWithCSS", param: "true", 420 value: "a[b]c", expectedValue: "a[b]c", 421 expectedExecCommandResult: container.isContentEditable, 422 expectedCommandSupported: true, 423 expectedCommandEnabled: container.isContentEditable, 424 beforeinputExpected: null, inputExpected: null, 425 additionalCheckFunc: aDescription => { 426 test( 427 () => assert_equals(document.queryCommandState("styleWithCSS"), container.isContentEditable), 428 `${aDescription}: styleWithCSS state should be ${container.isContentEditable} when ${ 429 kIsTextArea ? "<textarea>" : "<input>" 430 } has focus` 431 ); 432 aTarget.blur(); 433 container.focus(); 434 getSelection().collapse(container, 0); 435 test( 436 () => assert_equals(document.queryCommandState("styleWithCSS"), container.isContentEditable), 437 `${aDescription}: styleWithCSS state should be ${container.isContentEditable} when ${ 438 kIsTextArea ? "<textarea>" : "<input>" 439 } does not have focus` 440 ); 441 }, 442 }, 443 {command: "styleWithCSS", param: "false", 444 value: "a[b]c", expectedValue: "a[b]c", 445 expectedExecCommandResult: container.isContentEditable, 446 expectedCommandSupported: true, 447 expectedCommandEnabled: container.isContentEditable, 448 beforeinputExpected: null, inputExpected: null, 449 additionalCheckFunc: aDescription => { 450 test( 451 () => assert_equals(document.queryCommandState("styleWithCSS"), false), 452 `${aDescription}: styleWithCSS state should be false when ${ 453 kIsTextArea ? "<textarea>" : "<input>" 454 } has focus` 455 ); 456 aTarget.blur(); 457 container.focus(); 458 getSelection().collapse(container, 0); 459 test( 460 () => assert_equals(document.queryCommandState("styleWithCSS"), false), 461 `${aDescription}: styleWithCSS state should be false when ${ 462 kIsTextArea ? "<textarea>" : "<input>" 463 } does not have focus` 464 ); 465 }, 466 }, 467 {command: "contentReadOnly", param: "true", 468 value: "a[b]c", expectedValue: "a[b]c", 469 expectedExecCommandResult: false, 470 expectedCommandSupported: false, 471 expectedCommandEnabled: false, 472 beforeinputExpected: null, inputExpected: null, 473 additionalCheckFunc: aDescription => { 474 test( 475 () => assert_equals(document.queryCommandState("contentReadOnly"), false), 476 `${aDescription}: contentReadOnly state should be true when ${ 477 kIsTextArea ? "<textarea>" : "<input>" 478 } has focus` 479 ); 480 test( 481 () => assert_equals(aTarget.readOnly, false), 482 `${aDescription}: readonly property should be true` 483 ); 484 aTarget.blur(); 485 container.focus(); 486 getSelection().collapse(container, 0); 487 test( 488 () => assert_equals(document.queryCommandState("contentReadOnly"), false), 489 `${aDescription}: contentReadOnly state should be false when ${ 490 kIsTextArea ? "<textarea>" : "<input>" 491 } does not have focus` 492 ); 493 }, 494 }, 495 {command: "contentReadOnly", param: "false", 496 value: "a[b]c", expectedValue: "a[b]c", 497 expectedExecCommandResult: false, 498 expectedCommandSupported: false, 499 expectedCommandEnabled: false, 500 beforeinputExpected: null, inputExpected: null, 501 additionalCheckFunc: aDescription => { 502 test( 503 () => assert_equals(document.queryCommandState("contentReadOnly"), false), 504 `${aDescription}: contentReadOnly state should be false when ${ 505 kIsTextArea ? "<textarea>" : "<input>" 506 } has focus` 507 ); 508 test( 509 () => assert_equals(aTarget.readOnly, false), 510 `${aDescription}: readonly property should be false` 511 ); 512 aTarget.blur(); 513 container.focus(); 514 getSelection().collapse(container, 0); 515 test( 516 () => assert_equals(document.queryCommandState("contentReadOnly"), false), 517 `${aDescription}: contentReadOnly state should be false when ${ 518 kIsTextArea ? "<textarea>" : "<input>" 519 } does not have focus` 520 ); 521 }, 522 }, 523 {command: "defaultParagraphSeparator", param: "p", 524 value: "a[b]c", expectedValue: "a[b]c", 525 expectedExecCommandResult: container.isContentEditable, 526 expectedCommandSupported: true, 527 expectedCommandEnabled: container.isContentEditable, 528 beforeinputExpected: null, inputExpected: null, 529 additionalCheckFunc: aDescription => { 530 test( 531 () => 532 assert_equals( 533 document.queryCommandValue("defaultParagraphSeparator"), 534 container.isContentEditable ? "p" : "div" 535 ) 536 , 537 `${aDescription}: defaultParagraphSeparator value should be "p" when ${ 538 kIsTextArea ? "<textarea>" : "<input>" 539 } has focus` 540 ); 541 aTarget.blur(); 542 container.focus(); 543 getSelection().collapse(container, 0); 544 test( 545 () => 546 assert_equals( 547 document.queryCommandValue("defaultParagraphSeparator"), 548 container.isContentEditable ? "p" : "div" 549 ), 550 `${aDescription}: defaultParagraphSeparator value should be "p" when ${ 551 kIsTextArea ? "<textarea>" : "<input>" 552 } does not have focus` 553 ); 554 }, 555 }, 556 {command: "defaultParagraphSeparator", param: "div", 557 value: "a[b]c", expectedValue: "a[b]c", 558 expectedExecCommandResult: container.isContentEditable, 559 expectedCommandSupported: true, 560 expectedCommandEnabled: container.isContentEditable, 561 beforeinputExpected: null, inputExpected: null, 562 additionalCheckFunc: aDescription => { 563 test( 564 () => assert_equals(document.queryCommandValue("defaultParagraphSeparator"), "div"), 565 `${aDescription}: defaultParagraphSeparator value should be "div" when ${ 566 kIsTextArea ? "<textarea>" : "<input>" 567 } has focus` 568 ); 569 aTarget.blur(); 570 container.focus(); 571 getSelection().collapse(container, 0); 572 test( 573 () => assert_equals(document.queryCommandValue("defaultParagraphSeparator"), "div"), 574 `${aDescription}: defaultParagraphSeparator value should be "div" when ${ 575 kIsTextArea ? "<textarea>" : "<input>" 576 } does not have focus` 577 ); 578 }, 579 }, 580 ]; 581 582 for (const kTest of kTests) { 583 const kDescription = 584 `${aDescription}, execCommand("${kTest.command}", false, ${kTest.param}), ${kTest.value})`; 585 if (kTest.command === "paste" || kTest.command === "copy" || kTest.command === "cut") { 586 await test_driver.click(document.body); 587 } 588 aTarget.value = "dummy value to ensure the following value setting clear the undo history"; 589 let value = kTest.value.replace(/[\[\]]/g, ""); 590 aTarget.value = value; 591 aTarget.focus(); 592 aTarget.selectionStart = kTest.value.indexOf("["); 593 aTarget.selectionEnd = kTest.value.indexOf("]") - 1; 594 595 test( 596 () => assert_equals(document.queryCommandSupported(kTest.command), kTest.expectedCommandSupported), 597 `${kDescription}: The command should ${ 598 kTest.expectedCommandSupported ? "be" : "not be" 599 } supported` 600 ); 601 test( 602 () => assert_equals(document.queryCommandEnabled(kTest.command), kTest.expectedCommandEnabled), 603 `${kDescription}: The command should ${ 604 kTest.expectedCommandEnabled ? "be" : "not be" 605 } enabled` 606 ); 607 608 if (!document.queryCommandSupported(kTest.command) || !kTest.expectedCommandSupported) { 609 continue; 610 } 611 612 if (kTest.initFunc) { 613 kTest.initFunc(); 614 } 615 616 let beforeinput = null; 617 function onBeforeinput(event) { 618 beforeinput = event; 619 } 620 window.addEventListener("beforeinput", onBeforeinput, {capture: true}); 621 let input = null; 622 function onInput(event) { 623 input = event; 624 } 625 window.addEventListener("input", onInput, {capture: true}); 626 let ret; 627 test(function () { 628 ret = document.execCommand(kTest.command, false, kTest.param); 629 assert_equals(ret, kTest.expectedExecCommandResult); 630 }, `${kDescription}: execCommand() should return ${kTest.expectedExecCommandResult}`); 631 test(function () { 632 let value = aTarget.value.substring(0, aTarget.selectionStart) + 633 "[" + 634 aTarget.value.substring(aTarget.selectionStart, aTarget.selectionEnd) + 635 "]" + 636 aTarget.value.substring(aTarget.selectionEnd); 637 assert_equals(value, kTest.expectedValue); 638 }, `${kDescription}: ${kIsTextArea ? "<textarea>" : "<input>"}.value should be "${kTest.expectedValue}"`); 639 test(function () { 640 assert_equals(beforeinput?.inputType, kTest.beforeinputExpected?.inputType); 641 }, `${kDescription}: beforeinput.inputType should be ${kTest.beforeinputExpected?.inputType}`); 642 test(function () { 643 assert_equals(beforeinput?.target, kTest.beforeinputExpected?.target); 644 }, `${kDescription}: beforeinput.target should be ${kTest.beforeinputExpected?.target}`); 645 test(function () { 646 assert_equals(input?.inputType, kTest.inputExpected?.inputType); 647 }, `${kDescription}: input.inputType should be ${kTest.inputExpected?.inputType}`); 648 test(function () { 649 assert_equals(input?.target, kTest.inputExpected?.target); 650 }, `${kDescription}: input.target should be ${kTest.inputExpected?.target}`); 651 if (kTest.additionalCheckFunc) { 652 kTest.additionalCheckFunc(kDescription); 653 } 654 window.removeEventListener("beforeinput", onBeforeinput, {capture: true}); 655 window.removeEventListener("input", onInput, {capture: true}); 656 } 657 } 658 659 window.addEventListener("load", runTests, {once: true}); 660 </script>