Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/testing/web-platform/tests/editing/run/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quellcode-Bibliothek undo-redo.html   Sprache: HTML

 
 products/sources/formale Sprachen/C/Firefox/testing/web-platform/tests/editing/run/undo-redo.html


<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="../include/editor-test-utils.js"></script>
<iframe srcdoc=""></iframe>
<script>
"use strict";
const iframe = document.querySelector("iframe");

promise_test(async () => {
  await new Promise(resolve => {
    addEventListener("load", resolve, {once: true});
  });
}, "Waiting for load...");

/**
 * This test does NOT test whether the edit result is valid or invalid.
 * This test just tests whether "undo" and "redo" restores previous state
 * and additional "undo" and "redo" does not run unexpectedly.
 *
 * description: Set string to explain what's testing.
 * editorInnerHTML: Set initial innerHTML value of editor.
 * init: Set a function object if you need to test complicated cases, e.g.,
 *       testing with empty text node.
 * run: Set a function object which run something modifying the editor (or
 *      does nothing).
 * expectedUndoResult: Set an expected innerHTML result as string or array
 *                     of the string.  If this is not specified, it's compared
 *                     with editorInnerHTML value.
 * cleanUp: Set a function object if you need to clean something up after the
 *          test.
 */

const tests = [
  {
    description: "insertParagraph at start of a paragraph",
    editorInnerHTML: "

[]abcdef

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertParagraph");
    },
  },
  {
    description: "insertParagraph at middle of a paragraph",
    editorInnerHTML: "

abc[]def

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertParagraph");
    },
  },
  {
    description: "insertParagraph at end of a paragraph",
    editorInnerHTML: "

abcdef[]

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertParagraph");
    },
  },
  {
    description: "insertParagraph at start of a listitem",
    editorInnerHTML: "
  • []abcdef
"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertParagraph");
    },
  },
  {
    description: "insertParagraph at middle of a listitem",
    editorInnerHTML: "
  • abc[]def
"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertParagraph");
    },
  },
  {
    description: "insertParagraph at end of a listitem",
    editorInnerHTML: "
  • abcdef[]
"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertParagraph");
    },
  },
  {
    description: "insertLineBreak at start of a paragraph",
    editorInnerHTML: "

[]abcdef

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertLineBreak");
    },
  },
  {
    description: "insertLineBreak at middle of a paragraph",
    editorInnerHTML: "

abc[]def

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertLineBreak");
    },
  },
  {
    description: "insertLineBreak at end of a paragraph",
    editorInnerHTML: "

abcdef[]

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertLineBreak");
    },
  },
  {
    description: "insertLineBreak at start of a listitem",
    editorInnerHTML: "
  • []abcdef
"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertLineBreak");
    },
  },
  {
    description: "insertLineBreak at middle of a listitem",
    editorInnerHTML: "
  • abc[]def
"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertLineBreak");
    },
  },
  {
    description: "insertLineBreak at end of a listitem",
    editorInnerHTML: "
  • abcdef[]
"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("insertLineBreak");
    },
  },
  {
    description: "delete at start of second paragraph",
    editorInnerHTML: "

abc

[]def

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("delete");
    }
  },
  {
    description: "forwarddelete at end of first paragraph",
    editorInnerHTML: "

abc[]

def

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("forwarddelete");
    }
  },
  {
    description: "delete at start of second paragraph starting with an emoji",
    editorInnerHTML: "

abc\uD83D\uDC49

[]\uD83D\uDC48def

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("delete");
    }
  },
  {
    description: "forwarddelete at end of first paragraph ending with an emoji",
    editorInnerHTML: "

abc\uD83D\uDC49[]

\uD83D\uDC48def

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("forwarddelete");
    }
  },
  {
    description: "delete at start of second paragraph ending with a non editable item",
    editorInnerHTML: "

A line

[]Second line with non-editable item

"
,
    run: (win, doc, editingHost) => {
      doc.execCommand("delete");
    }
  }
];

for (const curTest of tests) {
  promise_test(async t => {
    await new Promise(resolve => {
      iframe.addEventListener("load", resolve, {once: true});
      iframe.srcdoc = "
"
;
    });
    const contentDocument = iframe.contentDocument;
    const contentWindow = iframe.contentWindow;
    contentWindow.focus();
    const editingHost = contentDocument.querySelector("div[contenteditable]");
    const utils = new EditorTestUtils(editingHost, window);
    utils.setupEditingHost(curTest.editorInnerHTML);
    contentDocument.documentElement.scrollHeight;  // flush pending things
    if (typeof curTest.init == "function") {
      await curTest.init(contentWindow, contentDocument, editingHost);
    }
    const initialValue = editingHost.innerHTML;
    await curTest.run(contentWindow, contentDocument, editingHost);
    const newValue = editingHost.innerHTML;
    test(t2 => {
      const ret = contentDocument.execCommand("undo");
      if (curTest.expectedUndoResult !== undefined) {
        if (typeof curTest.expectedUndoResult == "string") {
          assert_equals(
            editingHost.innerHTML,
            curTest.expectedUndoResult,
            `${t2.name}: should restore the innerHTML value`
          );
        } else {
          assert_in_array(
            editingHost.innerHTML,
            curTest.expectedUndoResult,
            `${t2.name}: should restore one of the innerHTML values`
          );
        }
      } else {
        assert_equals(
          editingHost.innerHTML,
          initialValue,
          `${t2.name}: should restore the initial innerHTML value`
        );
      }
      assert_true(ret, `${t2.name}: execCommand("undo") should return true`);
    }, `${t.name} - first undo`);
    test(t3 => {
      const ret = contentDocument.execCommand("redo");
      assert_equals(
        editingHost.innerHTML,
        newValue,
        `${t3.name}: should restore the modified innerHTML value`
      );
      assert_true(ret, `${t3.name}: execCommand("redo") should return true`);
    }, `${curTest.description} - first redo`);
    test(t4 => {
      const ret = contentDocument.execCommand("redo");
      assert_equals(
        editingHost.innerHTML,
        newValue,
        `${t4.name}: should not modify the modified innerHTML value`
      );
      assert_false(ret, `${t4.name}: execCommand("redo") should return false`);
    }, `${curTest.description} - second redo`);
    if (typeof curTest.cleanUp == "function") {
      await curTest.cleanUp(contentWindow, contentDocument, editingHost);
    }
    await new Promise(resolve => {
      iframe.addEventListener("load", resolve, {once: true});
      iframe.srcdoc = "";
    });
    contentDocument.documentElement.scrollHeight; // flush pending things
    await new Promise(resolve =>
      requestAnimationFrame(
        () => requestAnimationFrame(resolve)
      )
    );
  }, curTest.description);
}
</script>

Messung V0.5
C=100 H=100 G=100

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.38Bemerkung:  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.