diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /editor/libeditor/tests/test_nsIEditorMailSupport_insertAsCitedQuotation.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | editor/libeditor/tests/test_nsIEditorMailSupport_insertAsCitedQuotation.html | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/editor/libeditor/tests/test_nsIEditorMailSupport_insertAsCitedQuotation.html b/editor/libeditor/tests/test_nsIEditorMailSupport_insertAsCitedQuotation.html new file mode 100644 index 0000000000..531a8c6015 --- /dev/null +++ b/editor/libeditor/tests/test_nsIEditorMailSupport_insertAsCitedQuotation.html @@ -0,0 +1,322 @@ +<!DOCTYPE> +<html> +<head> + <title>Test for nsIEditorMailSupport.insertAsCitedQuotation()</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +SimpleTest.waitForExplicitFinish(); +SimpleTest.waitForFocus(() => { + function testInputEvents() { + const inReadonlyMode = getEditor().flags & SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask; + const editorDescription = `(readonly=${!!inReadonlyMode})`; + + const editor = document.querySelector("div[contenteditable]"); + const selection = getSelection(); + + let beforeInputEvents = []; + let inputEvents = []; + let selectionRanges = []; + function onBeforeInput(aEvent) { + beforeInputEvents.push(aEvent); + selectionRanges = []; + for (let i = 0; i < selection.rangeCount; i++) { + let range = selection.getRangeAt(i); + selectionRanges.push({startContainer: range.startContainer, startOffset: range.startOffset, + endContainer: range.endContainer, endOffset: range.endOffset}); + } + } + function onInput(aEvent) { + inputEvents.push(aEvent); + } + editor.addEventListener("beforeinput", onBeforeInput); + editor.addEventListener("input", onInput); + + editor.innerHTML = ""; + editor.focus(); + selection.collapse(editor, 0); + + function checkInputEvent(aEvent, aInputType, aData, aDescription) { + ok(aEvent instanceof InputEvent, + `"${aEvent.type}" event should be dispatched with InputEvent interface ${aDescription}`); + // If it were cancelable whose inputType is empty string, web apps would + // block any Firefox specific modification whose inputType are not declared + // by the spec. + let expectedCancelable = aEvent.type === "beforeinput" && aInputType !== ""; + is(aEvent.cancelable, expectedCancelable, + `"${aEvent.type}" event should ${expectedCancelable ? "be" : "be never"} cancelable ${aDescription}`); + is(aEvent.bubbles, true, + `"${aEvent.type}" event should always bubble ${aDescription}`); + is(aEvent.inputType, aInputType, + `inputType of "${aEvent.type}" event should be "${aInputType}" ${aDescription}`); + is(aEvent.data, aData, + `data of "${aEvent.type}" event should be ${aData} ${aDescription}`); + is(aEvent.dataTransfer, null, + `dataTransfer of "${aEvent.type}" event should be null ${aDescription}`); + let targetRanges = aEvent.getTargetRanges(); + if (aEvent.type === "beforeinput") { + is(targetRanges.length, selectionRanges.length, + `getTargetRanges() of "beforeinput" event should return selection ranges ${aDescription}`); + if (targetRanges.length === selectionRanges.length) { + for (let i = 0; i < selectionRanges.length; i++) { + is(targetRanges[i].startContainer, selectionRanges[i].startContainer, + `startContainer of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`); + is(targetRanges[i].startOffset, selectionRanges[i].startOffset, + `startOffset of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`); + is(targetRanges[i].endContainer, selectionRanges[i].endContainer, + `endContainer of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`); + is(targetRanges[i].endOffset, selectionRanges[i].endOffset, + `endOffset of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`); + } + } + } else { + is(targetRanges.length, 0, + `getTargetRanges() of "${aEvent.type}" event should return empty array ${aDescription}`); + } + } + + // Tests when the editor is in plaintext mode. + + getEditor().flags |= SpecialPowers.Ci.nsIEditor.eEditorPlaintextMask; + + beforeInputEvents = []; + inputEvents = []; + getEditorMailSupport().insertAsCitedQuotation("this is quoted text\nAnd here is second line.", "this is cited text", false); + + ok( + selection.isCollapsed, + `Selection should be collapsed after calling nsIEditorMailSupport.insertAsCitedQuotation() of plaintext editor ${editorDescription}` + ); + is( + selection.focusNode, + editor, + `focus node of Selection should be a child of the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of plaintext editor ${editorDescription}` + ); + is( + selection.focusOffset, + 1, + `focus offset of Selection should be next to inserted <span> element after calling nsIEditorMailSupport.insertAsCitedQuotation() of plaintext editor ${editorDescription}` + ); + is( + editor.innerHTML, + '<span style="white-space: pre-wrap;">> this is quoted text<br>> And here is second line.<br><br></span>', + `The quoted text should be inserted as plaintext into the plaintext editor ${editorDescription}` + ); + is( + beforeInputEvents.length, + 1, + `One "beforeinput" event should be fired on the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of plaintext editor ${editorDescription}` + ); + checkInputEvent( + beforeInputEvents[0], + "insertText", "this is quoted text\nAnd here is second line.", + `after calling nsIEditorMailSupport.insertAsCitedQuotation() of plaintext editor ${editorDescription}` + ); + is( + inputEvents.length, + 1, + `One "input" event should be fired on the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of plaintext editor ${editorDescription}` + ); + checkInputEvent( + inputEvents[0], + "insertText", "this is quoted text\nAnd here is second line.", + `after calling nsIEditorMailSupport.insertAsCitedQuotation() of plaintext editor ${editorDescription}` + ); + + // Tests when the editor is in HTML editor mode. + getEditor().flags &= ~SpecialPowers.Ci.nsIEditor.eEditorPlaintextMask; + + editor.innerHTML = ""; + + beforeInputEvents = []; + inputEvents = []; + getEditorMailSupport().insertAsCitedQuotation("this is quoted text<br>", "this is cited text", false); + + ok( + selection.isCollapsed, + `Selection should be collapsed after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as plaintext) ${editorDescription}` + ); + is( + selection.focusNode, + editor, + `focus node of Selection should be a child of the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as plaintext) ${editorDescription}` + ); + is( + selection.focusOffset, + 1, + `focus offset of Selection should be next to inserted <span> element after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as plaintext) ${editorDescription}` + ); + is( + editor.innerHTML, + '<blockquote type="cite" cite="this is cited text">this is quoted text<br></blockquote>', + `The quoted text should be inserted as plaintext into the HTML editor ${editorDescription}` + ); + is( + beforeInputEvents.length, + 1, + `One "beforeinput" event should be fired on the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as plaintext) ${editorDescription}` + ); + checkInputEvent( + beforeInputEvents[0], + "", + null, + `after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as plaintext) ${editorDescription}` + ); + is( + inputEvents.length, + 1, + `One "input" event should be fired on the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as plaintext) ${editorDescription}` + ); + checkInputEvent( + inputEvents[0], + "", + null, + `after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as plaintext) ${editorDescription}` + ); + + editor.innerHTML = ""; + + beforeInputEvents = []; + inputEvents = []; + getEditorMailSupport().insertAsCitedQuotation("this is quoted text<br>And here is second line.", "this is cited text", true); + + ok( + selection.isCollapsed, + `Selection should be collapsed after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as HTML source) ${editorDescription}` + ); + is( + selection.focusNode, + editor, + `focus node of Selection should be a child of the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as HTML source) ${editorDescription}` + ); + is( + selection.focusOffset, + 1, + `focus offset of Selection should be next to inserted <span> element after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as HTML source) ${editorDescription}` + ); + is( + editor.innerHTML, + '<blockquote type="cite" cite="this is cited text">this is quoted text<br>And here is second line.</blockquote>', + `The quoted text should be inserted as HTML source into the HTML editor ${editorDescription}` + ); + is( + beforeInputEvents.length, + 1, + `One "beforeinput" event should be fired on the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as HTML source) ${editorDescription}` + ); + checkInputEvent( + beforeInputEvents[0], + "", + null, + `after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as HTML source) ${editorDescription}` + ); + is( + inputEvents.length, + 1, + `One "input" event should be fired on the editing host after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as HTML source) ${editorDescription}` + ); + checkInputEvent( + inputEvents[0], + "", + null, + `after calling nsIEditorMailSupport.insertAsCitedQuotation() of HTMLEditor editor (inserting as HTML source) ${editorDescription}` + ); + + editor.removeEventListener("beforeinput", onBeforeInput); + editor.removeEventListener("input", onInput); + } + + function testStyleOfPlaintextMode() { + const inReadonlyMode = getEditor().flags & SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask; + const editorDescription = `(readonly=${!!inReadonlyMode})`; + + getEditor().flags |= SpecialPowers.Ci.nsIEditor.eEditorPlaintextMask; + + (function testInDiv() { + const editor = document.querySelector("div[contenteditable]"); + editor.innerHTML = ""; + editor.focus(); + getEditorMailSupport().insertAsCitedQuotation( + "this is quoted text.", + "this is cited text", + false + ); + is( + editor.firstChild.tagName, + "SPAN", + `testStyleOfPlaintextMode: testInDiv: insertAsCitedQuotation should insert a <span> element ${editorDescription}` + ); + const computedSpanStyle = getComputedStyle(editor.firstChild); + is( + computedSpanStyle.display, + "inline", + `testStyleOfPlaintextMode: testInDiv: The inserted <span> element should be "display: inline;" ${editorDescription}` + ); + is( + computedSpanStyle.whiteSpace, + "pre-wrap", + `testStyleOfPlaintextMode: testInDiv: The inserted <span> element should be "white-space: pre-wrap;" ${editorDescription}` + ); + })(); + + try { + document.body.contentEditable = true; + (function testInBody() { + getSelection().collapse(document.body, 0); + getEditorMailSupport().insertAsCitedQuotation( + "this is quoted text.", + "this is cited text", + false + ); + is( + document.body.firstChild.tagName, + "SPAN", + `testStyleOfPlaintextMode: testInBody: insertAsCitedQuotation should insert a <span> element in plaintext mode and in a <body> element ${editorDescription}` + ); + const computedSpanStyle = getComputedStyle(document.body.firstChild); + is( + computedSpanStyle.display, + "block", + `testStyleOfPlaintextMode: testInBody: The inserted <span> element should be "display: block;" in plaintext mode and in a <body> element ${editorDescription}` + ); + is( + computedSpanStyle.whiteSpace, + "pre-wrap", + `testStyleOfPlaintextMode: testInBody: The inserted <span> element should be "white-space: pre-wrap;" in plaintext mode and in a <body> element ${editorDescription}` + ); + document.body.firstChild.remove(); + })(); + } finally { + document.body.contentEditable = false; + } + } + + testInputEvents(); + testStyleOfPlaintextMode(); + + // Even if the HTMLEditor is readonly, XPCOM API should keep working. + getEditor().flags |= SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask; + testInputEvents(); + testStyleOfPlaintextMode(); + + SimpleTest.finish(); +}); + +function getEditor() { + var editingSession = SpecialPowers.wrap(window).docShell.editingSession; + return editingSession.getEditorForWindow(window); +} + +function getEditorMailSupport() { + return getEditor().QueryInterface(SpecialPowers.Ci.nsIEditorMailSupport); +} + +</script> +</body> + +</html> |