|
| 1 | +import * as config from "trix/config" |
1 | 2 | import { rangesAreEqual } from "trix/core/helpers"
|
2 | 3 |
|
3 | 4 | import {
|
@@ -500,7 +501,7 @@ testGroup("Custom element API", { template: "editor_empty" }, () => {
|
500 | 501 | testGroup("<label> support", { template: "editor_with_labels" }, () => {
|
501 | 502 | test("associates all label elements", () => {
|
502 | 503 | const labels = [ document.getElementById("label-1"), document.getElementById("label-3") ]
|
503 |
| - assert.deepEqual(getEditorElement().labels, labels) |
| 504 | + assert.deepEqual(Array.from(getEditorElement().labels), labels) |
504 | 505 | })
|
505 | 506 |
|
506 | 507 | test("focuses when <label> clicked", () => {
|
@@ -538,4 +539,161 @@ testGroup("form property references its <form>", { template: "editors_with_forms
|
538 | 539 | const editor = document.getElementById("editor-with-no-form")
|
539 | 540 | assert.equal(editor.form, null)
|
540 | 541 | })
|
| 542 | + |
| 543 | + test("editor resets to its original value on element reset", async () => { |
| 544 | + const element = getEditorElement() |
| 545 | + |
| 546 | + await typeCharacters("hello") |
| 547 | + element.reset() |
| 548 | + expectDocument("\n") |
| 549 | + }) |
| 550 | + |
| 551 | + test("element returns empty string when value is missing", () => { |
| 552 | + const element = getEditorElement() |
| 553 | + |
| 554 | + assert.equal(element.value, "") |
| 555 | + }) |
| 556 | + |
| 557 | + test("editor returns its type", () => { |
| 558 | + const element = getEditorElement() |
| 559 | + |
| 560 | + assert.equal("trix-editor", element.type) |
| 561 | + }) |
| 562 | + |
| 563 | + testIfFormAssociated("adds [disabled] attribute based on .disabled property", () => { |
| 564 | + const editor = document.getElementById("editor-with-ancestor-form") |
| 565 | + |
| 566 | + editor.disabled = true |
| 567 | + |
| 568 | + assert.equal(editor.hasAttribute("disabled"), true, "adds [disabled] attribute") |
| 569 | + |
| 570 | + editor.disabled = false |
| 571 | + |
| 572 | + assert.equal(editor.hasAttribute("disabled"), false, "removes [disabled] attribute") |
| 573 | + }) |
| 574 | + |
| 575 | + testIfFormAssociated("removes [contenteditable] and disables input when editor element has [disabled]", () => { |
| 576 | + const editor = document.getElementById("editor-with-no-form") |
| 577 | + |
| 578 | + editor.setAttribute("disabled", "") |
| 579 | + |
| 580 | + assert.equal(editor.matches(":disabled"), true, "sets :disabled CSS pseudostate") |
| 581 | + assert.equal(editor.inputElement.disabled, true, "disables input") |
| 582 | + assert.equal(editor.disabled, true, "exposes [disabled] attribute as .disabled property") |
| 583 | + assert.equal(editor.hasAttribute("contenteditable"), false, "removes [contenteditable] attribute") |
| 584 | + |
| 585 | + editor.removeAttribute("disabled") |
| 586 | + |
| 587 | + assert.equal(editor.matches(":disabled"), false, "removes sets :disabled pseudostate") |
| 588 | + assert.equal(editor.inputElement.disabled, false, "enabled input") |
| 589 | + assert.equal(editor.disabled, false, "updates .disabled property") |
| 590 | + assert.equal(editor.hasAttribute("contenteditable"), true, "adds [contenteditable] attribute") |
| 591 | + }) |
| 592 | + |
| 593 | + testIfFormAssociated("removes [contenteditable] and disables input when editor element is :disabled", () => { |
| 594 | + const editor = document.getElementById("editor-within-fieldset") |
| 595 | + const fieldset = document.getElementById("fieldset") |
| 596 | + |
| 597 | + fieldset.disabled = true |
| 598 | + |
| 599 | + assert.equal(editor.matches(":disabled"), true, "sets :disabled CSS pseudostate") |
| 600 | + assert.equal(editor.inputElement.disabled, true, "disables input") |
| 601 | + assert.equal(editor.disabled, true, "infers disabled state from ancestor") |
| 602 | + assert.equal(editor.hasAttribute("disabled"), false, "does not set [disabled] attribute") |
| 603 | + assert.equal(editor.hasAttribute("contenteditable"), false, "removes [contenteditable] attribute") |
| 604 | + |
| 605 | + fieldset.disabled = false |
| 606 | + |
| 607 | + assert.equal(editor.matches(":disabled"), false, "removes sets :disabled pseudostate") |
| 608 | + assert.equal(editor.inputElement.disabled, false, "enabled input") |
| 609 | + assert.equal(editor.disabled, false, "updates .disabled property") |
| 610 | + assert.equal(editor.hasAttribute("disabled"), false, "does not set [disabled] attribute") |
| 611 | + assert.equal(editor.hasAttribute("contenteditable"), true, "adds [contenteditable] attribute") |
| 612 | + }) |
| 613 | + |
| 614 | + testIfFormAssociated("does not receive focus when :disabled", () => { |
| 615 | + const activeEditor = document.getElementById("editor-with-input-form") |
| 616 | + const editor = document.getElementById("editor-within-fieldset") |
| 617 | + |
| 618 | + activeEditor.focus() |
| 619 | + editor.disabled = true |
| 620 | + editor.focus() |
| 621 | + |
| 622 | + assert.equal(activeEditor, document.activeElement, "disabled editor does not receive focus") |
| 623 | + }) |
| 624 | + |
| 625 | + testIfFormAssociated("disabled editor does not encode its value when the form is submitted", () => { |
| 626 | + const editor = document.getElementById("editor-with-ancestor-form") |
| 627 | + const form = editor.form |
| 628 | + |
| 629 | + editor.inputElement.value = "Hello world" |
| 630 | + editor.disabled = true |
| 631 | + |
| 632 | + assert.deepEqual({}, Object.fromEntries(new FormData(form).entries()), "does not write to FormData") |
| 633 | + }) |
| 634 | + |
| 635 | + testIfFormAssociated("validates with [required] attribute as invalid", () => { |
| 636 | + const editor = document.getElementById("editor-with-ancestor-form") |
| 637 | + const form = editor.form |
| 638 | + let invalidEvent, submitEvent = null |
| 639 | + |
| 640 | + editor.addEventListener("invalid", event => invalidEvent = event, { once: true }) |
| 641 | + form.addEventListener("submit", event => submitEvent = event, { once: true }) |
| 642 | + |
| 643 | + editor.required = true |
| 644 | + form.requestSubmit() |
| 645 | + |
| 646 | + // assert.equal(document.activeElement, editor, "editor receives focus") |
| 647 | + assert.equal(editor.required, true, ".required property retrurns true") |
| 648 | + assert.equal(editor.validity.valid, false, "validity.valid is false") |
| 649 | + assert.equal(editor.validationMessage, "Please fill out this field.", "sets .validationMessage") |
| 650 | + assert.equal(invalidEvent.target, editor, "dispatches 'invalid' event on editor") |
| 651 | + assert.equal(submitEvent, null, "does not dispatch a 'submit' event") |
| 652 | + }) |
| 653 | + |
| 654 | + testIfFormAssociated("does not validate with [disabled] attribute", () => { |
| 655 | + const editor = document.getElementById("editor-with-ancestor-form") |
| 656 | + let invalidEvent = null |
| 657 | + |
| 658 | + editor.disabled = true |
| 659 | + editor.required = true |
| 660 | + editor.addEventListener("invalid", event => invalidEvent = event, { once: true }) |
| 661 | + editor.reportValidity() |
| 662 | + |
| 663 | + assert.equal(invalidEvent, null, "does not dispatch an 'invalid' event") |
| 664 | + }) |
| 665 | + |
| 666 | + testIfFormAssociated("re-validates when the value changes", async () => { |
| 667 | + const editor = document.getElementById("editor-with-ancestor-form") |
| 668 | + editor.required = true |
| 669 | + editor.focus() |
| 670 | + |
| 671 | + assert.equal(editor.validity.valid, false, "validity.valid is initially false") |
| 672 | + |
| 673 | + await typeCharacters("a") |
| 674 | + |
| 675 | + assert.equal(editor.validity.valid, true, "validity.valid is true after re-validating") |
| 676 | + assert.equal(editor.validity.valueMissing, false, "validity.valueMissing is false") |
| 677 | + assert.equal(editor.validationMessage, "", "clears the validationMessage") |
| 678 | + }) |
| 679 | + |
| 680 | + testIfFormAssociated("accepts a customError validation message", () => { |
| 681 | + const editor = document.getElementById("editor-with-ancestor-form") |
| 682 | + |
| 683 | + editor.setCustomValidity("A custom validation message") |
| 684 | + |
| 685 | + assert.equal(editor.validity.valid, false) |
| 686 | + assert.equal(editor.validity.customError, true) |
| 687 | + assert.equal(editor.validationMessage, "A custom validation message") |
| 688 | + }) |
541 | 689 | })
|
| 690 | + |
| 691 | +function testIfFormAssociated(name, callback) { |
| 692 | + test(name, async () => { |
| 693 | + if (config.editor.formAssociated) { |
| 694 | + await callback() |
| 695 | + } else { |
| 696 | + assert.equal(config.editor.formAssociated, false, "skipping test that requires ElementInternals") |
| 697 | + } |
| 698 | + }) |
| 699 | +} |
0 commit comments