Quelle window_nsITextInputProcessor.xhtml
Sprache: unbekannt
|
|
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Testing nsITextInputProcessor behavior"
xmlns:html=" http://www.w3.org/1999/xhtml"
xmlns=" http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onunload="onunload();">
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<body xmlns=" http://www.w3.org/1999/xhtml">
<div id="display">
<input id="input" type="text"/><input id="anotherInput" type="text"/><br/>
<textarea></textarea>
<iframe id="iframe" width="300" height="150"
src="data:text/html,<textarea id='textarea' cols='20' rows='4'></textarea>"></iframe><br/>
<div contenteditable=""><br/></div>
</div>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
var SimpleTest = window.arguments[0].SimpleTest;
SimpleTest.waitForFocus(runTests, window);
function getHTMLEditor(aWindow) {
return SpecialPowers.wrap(aWindow).docShell.editingSession?.getEditorForWindow(aW indow);
}
function ok(aCondition, aMessage)
{
SimpleTest.ok(aCondition, aMessage);
}
function is(aLeft, aRight, aMessage)
{
SimpleTest.is(aLeft, aRight, aMessage);
}
function isnot(aLeft, aRight, aMessage)
{
SimpleTest.isnot(aLeft, aRight, aMessage);
}
function todo_is(aLeft, aRight, aMessage)
{
SimpleTest.todo_is(aLeft, aRight, aMessage);
}
function info(aMessage) {
SimpleTest.info(aMessage);
}
function finish()
{
window.close();
}
function onunload()
{
SimpleTest.finish();
}
function checkInputEvent(aEvent, aCancelable, aIsComposing, aInputType, aData, aDescription) {
if (aEvent.type !== "input" && aEvent.type !== "beforeinput") {
console.trace();
throw new Error(`${aDescription}"${aEvent.type}" is not InputEvent`);
}
ok(InputEvent.isInstance(aEvent), `${aDescription}"${aEvent.type}" event should be dispatched with InputEvent interface`);
is(aEvent.cancelable, aCancelable, `${aDescription}"${aEvent.type}" event should ${aCancelable ? "be" : "not be"} cancelable`);
is(aEvent.bubbles, true, `${aDescription}"${aEvent.type}" event should always bubble`);
is(aEvent.isComposing, aIsComposing, `${aDescription}isComposing of "${aEvent.type}" event should be ${aIsComposing}`);
is(aEvent.inputType, aInputType, `${aDescription}inputType of "${aEvent.type}" event should be "${aInputType}"`);
is(aEvent.data, aData, `${aDescription}data of "${aEvent.type}" event should be "${aData}"`);
is(aEvent.dataTransfer, null, `${aDescription}dataTransfer of "${aEvent.type}" event should be null`);
is(aEvent.getTargetRanges().length, 0, `${aDescription}getTargetRanges() of "${aEvent.type}" event should return empty array`);
}
const kIsMac = (navigator.platform.indexOf("Mac") == 0);
const iframe = document.getElementById("iframe");
let childWindow = iframe.contentWindow;
let textareaInFrame;
let input = document.getElementById("input");
const textarea = document.querySelector("textarea");
const otherWindow = window.arguments[0];
const otherDocument = otherWindow.document;
const inputInChildWindow = otherDocument.getElementById("input");
const contenteditable = document.querySelector("div[contenteditable]");
const { AppConstants } = ChromeUtils.importESModule(
"resource://gre/modules/AppConstants.sys.mjs"
);
const kLF = "\n";
const kExpectInputBeforeCompositionEnd = SpecialPowers.getBoolPref("dom.input_events.dispatch_before_compositionend");
function getNativeText(aXPText)
{
if (kLF == "\n") {
return aXPText;
}
return aXPText.replace(/\n/g, kLF);
}
function createTIP()
{
return Cc["@mozilla.org/text-input-processor;1"].
createInstance(Ci.nsITextInputProcessor);
}
function runBeginInputTransactionMethodTests()
{
var description = "runBeginInputTransactionMethodTests: ";
input.value = "";
input.focus();
var simpleCallback = function (aTIP, aNotification)
{
switch (aNotification.type) {
case "request-to-commit":
aTIP.commitComposition();
break;
case "request-to-cancel":
aTIP.cancelComposition();
break;
}
return true;
};
var TIP1 = createTIP();
var TIP2 = createTIP();
isnot(TIP1, TIP2,
description + "TIP instances should be different");
// beginInputTransaction() and beginInputTransactionForTests() can take ownership if there is no composition.
ok(TIP1.beginInputTransaction(window, simpleCallback),
description + "TIP1.beginInputTransaction(window) should succeed because there is no composition");
ok(TIP1.beginInputTransactionForTests(window),
description + "TIP1.beginInputTransactionForTests(window) should succeed because there is no composition");
ok(TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2.beginInputTransaction(window) should succeed because there is no composition");
ok(TIP2.beginInputTransactionForTests(window),
description + "TIP2.beginInputTransactionForTests(window) should succeed because there is no composition");
// Start composition with TIP1, then, other TIPs cannot take ownership during a composition.
ok(TIP1.beginInputTransactionForTests(window),
description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition");
var composingStr = "foo";
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
ok(TIP1.flushPendingComposition(),
description + "TIP1.flushPendingComposition() should return true becuase it should be valid composition");
is(input.value, composingStr,
description + "The input element should have composing string");
// Composing nsITextInputProcessor instance shouldn't allow initialize it again.
try {
TIP1.beginInputTransaction(window, simpleCallback);
ok(false,
"TIP1.beginInputTransaction(window) should cause throwing an exception because it's composing with different purpose");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(window) should cause throwing an exception including NS_ERROR_ALREADY_INITIALIZED because it's composing for tests");
}
try {
TIP1.beginInputTransactionForTests(otherWindow);
ok(false,
"TIP1.beginInputTransactionForTests(otherWindow) should cause throwing an exception because it's composing on different window");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow) should cause throwing an exception including NS_ERROR_ALREADY_INITIALIZED because it's composing on this window");
}
ok(TIP1.beginInputTransactionForTests(window),
description + "TIP1.beginInputTransactionForTests(window) should succeed because TextEventDispatcher was initialized with same purpose");
ok(TIP1.beginInputTransactionForTests(childWindow),
description + "TIP1.beginInputTransactionForTests(childWindow) should succeed because TextEventDispatcher was initialized with same purpose and is shared by window and childWindow");
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2.beginInputTransaction(window) should not succeed because there is composition synthesized by TIP1");
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2.beginInputTransactionForTests(window) should not succeed because there is composition synthesized by TIP1");
ok(!TIP2.beginInputTransaction(childWindow, simpleCallback),
description + "TIP2.beginInputTransaction(childWindow) should not succeed because there is composition synthesized by TIP1");
ok(!TIP2.beginInputTransactionForTests(childWindow),
description + "TIP2.beginInputTransactionForTests(childWindow) should not succeed because there is composition synthesized by TIP1");
ok(TIP2.beginInputTransaction(otherWindow, simpleCallback),
description + "TIP2.beginInputTransaction(otherWindow) should succeed because there is composition synthesized by TIP1 but it's in other window");
ok(TIP2.beginInputTransactionForTests(otherWindow),
description + "TIP2.beginInputTransactionForTests(otherWindow) should succeed because there is composition synthesized by TIP1 but it's in other window");
// Let's confirm that the composing string is NOT committed by above tests.
TIP1.commitComposition();
is(input.value, composingStr,
description + "TIP1.commitString() without specifying commit string should commit current composition with the last composing string");
ok(!TIP1.hasComposition,
description + "TIP1.commitString() without specifying commit string should've end composition");
ok(TIP1.beginInputTransaction(window, simpleCallback),
description + "TIP1.beginInputTransaction() should succeed because there is no composition #2");
ok(TIP1.beginInputTransactionForTests(window),
description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition #2");
ok(TIP2.beginInputTransactionForTests(window),
description + "TIP2.beginInputTransactionForTests() should succeed because the composition was already committed #2");
// Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during startComposition().
var events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
// eslint-disable-next-line no-caller
input.removeEventListener(aEvent.type, arguments.callee);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from compositionstart event handler during TIP1.startComposition();");
});
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.startComposition();
is(events.length, 1,
description + "compositionstart event should be fired by TIP1.startComposition()");
TIP1.cancelComposition();
// Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during flushPendingComposition().
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from compositionstart event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from compositionupdate event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from text event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from beforeinput event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
input.addEventListener("input", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from input event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
is(events.length, 5,
description + "compositionstart, compositionupdate, text, beforeinput and input events should be fired by TIP1.flushPendingComposition()");
is(events[0].type, "compositionstart",
description + "events[0] should be compositionstart");
is(events[1].type, "compositionupdate",
description + "events[1] should be compositionupdate");
is(events[2].type, "text",
description + "events[2] should be text");
is(events[3].type, "beforeinput",
description + "events[3] should be beforeinput");
checkInputEvent(events[3], false, true, "insertCompositionText", composingStr, description);
is(events[4].type, "input",
description + "events[4] should be input");
checkInputEvent(events[4], false, true, "insertCompositionText", composingStr, description);
TIP1.cancelComposition();
// Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during commitComposition().
(() => {
events = [];
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from text event handler during a call of TIP1.commitComposition();");
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from compositionend event handler during a call of TIP1.commitComposition();");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from beforeinput event handler during a call of TIP1.commitComposition();");
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from input event handler during a call of TIP1.commitComposition();");
}
input.addEventListener("input", onInput);
TIP1.commitComposition();
is(events.length, kExpectInputBeforeCompositionEnd ? 5 : 4,
description + "text, beforeinput, compositionend and input events should be fired by TIP1.commitComposition()");
let index = -1;
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[index], false, true, "insertCompositionText", composingStr, description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", composingStr, description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", composingStr, description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during commitCompositionWith("bar").
(() => {
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from compositionstart event handler during TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction during compositionupdate event handler TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction during text event handler TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction during compositionend event handler TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction during beforeinput event handler TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction during input event handler TIP1.commitCompositionWith(\"bar\");");
}
input.addEventListener("input", onInput);
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.commitCompositionWith("bar");
is(events.length, kExpectInputBeforeCompositionEnd ? 7 : 6,
description + "compositionstart, compositionupdate, text, beforeinput, compositionend and input events should be fired by TIP1.commitCompositionWith(\"bar\")");
let index = -1;
is(events[++index].type, "compositionstart",
`${description}events[${index}] should be compositionstart`);
is(events[++index].type, "compositionupdate",
`${description}events[${index}] should be compositionupdate`);
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[3], false, true, "insertCompositionText", "bar", description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", "bar", description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", "bar", description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during cancelComposition().
(() => {
events = [];
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from compositionupdate event handler during a call of TIP1.cancelComposition();");
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from text event handler during a call of TIP1.cancelComposition();");
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from compositionend event handler during a call of TIP1.cancelComposition();");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from beforeinput event handler during a call of TIP1.cancelComposition();");
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from input event handler during a call of TIP1.cancelComposition();");
}
input.addEventListener("input", onInput);
TIP1.cancelComposition();
is(events.length, kExpectInputBeforeCompositionEnd ? 6 : 5,
description + "compositionupdate, text, beforeinput, compositionend and input events should be fired by TIP1.cancelComposition()");
let index = -1;
is(events[++index].type, "compositionupdate",
`${description}events[${index}] should be compositionupdate`);
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[index], false, true, "insertCompositionText", "", description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", "", description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", "", description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during keydown() and keyup().
events = [];
TIP1.beginInputTransaction(window, simpleCallback);
input.addEventListener("keydown", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from keydown event handler during a call of TIP1.keydown();");
}, {once: true});
input.addEventListener("keypress", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from keypress event handler during a call of TIP1.keydown();");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from beforeinput event handler during a call of TIP1.keydown();");
}, {once: true});
input.addEventListener("input", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from input event handler during a call of TIP1.keydown();");
}, {once: true});
input.addEventListener("keyup", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransaction(window, simpleCallback),
description + "TIP2 shouldn't be able to begin input transaction from keyup event handler during a call of TIP1.keyup();");
}, {once: true});
var keyA = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A });
TIP1.keydown(keyA);
TIP1.keyup(keyA);
is(events.length, 5,
description + "keydown, keypress, beforeinput, input, keyup events should be fired by TIP1.keydown() and TIP1.keyup()");
is(events[0].type, "keydown",
description + "events[0] should be keydown");
is(events[1].type, "keypress",
description + "events[1] should be keypress");
is(events[2].type, "beforeinput",
description + "events[2] should be beforeinput");
checkInputEvent(events[2], true, false, "insertText", "a", description);
is(events[3].type, "input",
description + "events[3] should be input");
checkInputEvent(events[3], false, false, "insertText", "a", description);
is(events[4].type, "keyup",
description + "events[4] should be keyup");
// Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during startComposition().
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
// eslint-disable-next-line no-caller
input.removeEventListener(aEvent.type, arguments.callee);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from compositionstart event handler during TIP1.startComposition();");
});
TIP1.beginInputTransactionForTests(window);
TIP1.startComposition();
is(events.length, 1,
description + "compositionstart event should be fired by TIP1.startComposition()");
TIP1.cancelComposition();
// Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during flushPendingComposition().
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from compositionstart event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from compositionupdate event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from text event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from beforeinput event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
input.addEventListener("input", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from input event handler during a call of TIP1.flushPendingComposition();");
}, {once: true});
TIP1.beginInputTransactionForTests(window);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
is(events.length, 5,
description + "compositionstart, compositionupdate, text, beforeinput and input events should be fired by TIP1.flushPendingComposition()");
is(events[0].type, "compositionstart",
description + "events[0] should be compositionstart");
is(events[1].type, "compositionupdate",
description + "events[1] should be compositionupdate");
is(events[2].type, "text",
description + "events[2] should be text");
is(events[3].type, "beforeinput",
description + "events[3] should be beforeinput");
checkInputEvent(events[3], false, true, "insertCompositionText", composingStr, description);
is(events[4].type, "input",
description + "events[4] should be input");
checkInputEvent(events[4], false, true, "insertCompositionText", composingStr, description);
TIP1.cancelComposition();
// Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during commitComposition().
(function () {
events = [];
TIP1.beginInputTransactionForTests(window, simpleCallback);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from text event handler during a call of TIP1.commitComposition();");
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from compositionend event handler during a call of TIP1.commitComposition();");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from beforeinput event handler during a call of TIP1.commitComposition();");
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from input event handler during a call of TIP1.commitComposition();");
}
input.addEventListener("input", onInput);
TIP1.commitComposition();
is(events.length, kExpectInputBeforeCompositionEnd ? 5 : 4,
description + "text, beforeinput, compositionend and input events should be fired by TIP1.commitComposition()");
let index = -1;
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[index], false, true, "insertCompositionText", composingStr, description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", composingStr, description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", composingStr, description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during commitCompositionWith("bar").
(() => {
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from compositionstart event handler during TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests during compositionupdate event handler TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests during text event handler TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests during compositionend event handler TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests during beforeinput event handler TIP1.commitCompositionWith(\"bar\");");
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests during input event handler TIP1.commitCompositionWith(\"bar\");");
}
input.addEventListener("input", onInput);
TIP1.beginInputTransactionForTests(window);
TIP1.commitCompositionWith("bar");
is(events.length, kExpectInputBeforeCompositionEnd ? 7 : 6,
description + "compositionstart, compositionupdate, text, beforeinput, compositionend and input events should be fired by TIP1.commitCompositionWith(\"bar\")");
let index = -1;
is(events[++index].type, "compositionstart",
`${description}events[${index}] should be compositionstart`);
is(events[++index].type, "compositionupdate",
`${description}events[${index}] should be compositionupdate`);
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[index], false, true, "insertCompositionText", "bar", description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", "bar", description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", "bar", description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during cancelComposition().
(() => {
events = [];
TIP1.beginInputTransactionForTests(window, simpleCallback);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from compositionupdate event handler during a call of TIP1.cancelComposition();");
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from text event handler during a call of TIP1.cancelComposition();");
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from compositionend event handler during a call of TIP1.cancelComposition();");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from beforeinput event handler during a call of TIP1.cancelComposition();");
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from input event handler during a call of TIP1.cancelComposition();");
}
input.addEventListener("input", onInput);
TIP1.cancelComposition();
is(events.length, kExpectInputBeforeCompositionEnd ? 6 : 5,
description + "compositionupdate, text, beforeinput, compositionend and input events should be fired by TIP1.cancelComposition()");
let index = -1;
is(events[++index].type, "compositionupdate",
`${description}events[${index}] should be compositionupdate`);
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[index], false, true, "insertCompositionText", "", description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", "", description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", "", description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during keydown() and keyup().
events = [];
TIP1.beginInputTransactionForTests(window);
input.addEventListener("keydown", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests for tests from keydown event handler during a call of TIP1.keydown();");
}, {once: true});
input.addEventListener("keypress", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from keypress event handler during a call of TIP1.keydown();");
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from beforeinput event handler during a call of TIP1.keydown();");
}, {once: true});
input.addEventListener("input", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from input event handler during a call of TIP1.keydown();");
}, {once: true});
input.addEventListener("keyup", function (aEvent) {
events.push(aEvent);
ok(!TIP2.beginInputTransactionForTests(window),
description + "TIP2 shouldn't be able to begin input transaction for tests from keyup event handler during a call of TIP1.keyup();");
}, {once: true});
keyA = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A });
TIP1.keydown(keyA);
TIP1.keyup(keyA);
is(events.length, 5,
description + "keydown, keypress, beforeinput, input, keyup events should be fired by TIP1.keydown() and TIP1.keyup()");
is(events[0].type, "keydown",
description + "events[0] should be keydown");
is(events[1].type, "keypress",
description + "events[1] should be keypress");
is(events[2].type, "beforeinput",
description + "events[2] should be beforeinput");
checkInputEvent(events[2], true, false, "insertText", "a", description);
is(events[3].type, "input",
description + "events[3] should be input");
checkInputEvent(events[3], false, false, "insertText", "a", description);
is(events[4].type, "keyup",
description + "events[4] should be keyup");
// Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during startComposition().
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during startComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during startComposition()");
}
}, {once: true});
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.startComposition();
is(events.length, 1,
description + "compositionstart event should be fired by TIP1.startComposition()");
TIP1.cancelComposition();
// Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during flushPendingComposition().
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during flushPendingComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()");
}
}, {once: true});
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during flushPendingComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()");
}
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should throw an exception during flushPendingComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()");
}
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should throw an exception during flushPendingComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()");
}
}, {once: true});
input.addEventListener("input", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during flushPendingComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()");
}
}, {once: true});
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
is(events.length, 5,
description + "compositionstart, compositionupdate, text, beforeinput and input events should be fired by TIP1.flushPendingComposition()");
is(events[0].type, "compositionstart",
description + "events[0] should be compositionstart");
is(events[1].type, "compositionupdate",
description + "events[1] should be compositionupdate");
is(events[2].type, "text",
description + "events[2] should be text");
is(events[3].type, "beforeinput",
description + "events[3] should be beforeinput");
checkInputEvent(events[3], false, true, "insertCompositionText", composingStr, description);
is(events[4].type, "input",
description + "events[4] should be input");
checkInputEvent(events[4], false, true, "insertCompositionText", composingStr, description);
TIP1.cancelComposition();
// Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during commitComposition().
(function () {
events = [];
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should throw an exception during commitComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()");
}
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during commitComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()");
}
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should throw an exception during commitComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()");
}
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during commitComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()");
}
}
input.addEventListener("input", onInput);
TIP1.commitComposition();
is(events.length, kExpectInputBeforeCompositionEnd ? 5 : 4,
description + "text, beforeinput, compositionend and input events should be fired by TIP1.commitComposition()");
let index = -1;
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[index], false, true, "insertCompositionText", composingStr, description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", composingStr, description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", composingStr, description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during commitCompositionWith("bar");.
(() => {
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during commitCompositionWith(\"bar\")");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")");
}
}, {once: true});
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during commitCompositionWith(\"bar\")");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")");
}
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should throw an exception during commitCompositionWith(\"bar\")");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")");
}
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during commitCompositionWith(\"bar\")");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")");
}
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should throw an exception during commitCompositionWith(\"bar\")");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")");
}
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during commitCompositionWith(\"bar\")");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")");
}
}
input.addEventListener("input", onInput);
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.commitCompositionWith("bar");
is(events.length, kExpectInputBeforeCompositionEnd ? 7 : 6,
description + "compositionstart, compositionupdate, text, beforeinput, compositionend and input events should be fired by TIP1.commitCompositionWith(\"bar\")");
let index = -1;
is(events[++index].type, "compositionstart",
`${description}events[${index}] should be compositionstart`);
is(events[++index].type, "compositionupdate",
`${description}events[${index}] should be compositionupdate`);
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[index], false, true, "insertCompositionText", "bar", description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", "bar", description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", "bar", description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during cancelComposition();.
(() => {
events = [];
TIP1.beginInputTransaction(window, simpleCallback);
TIP1.setPendingCompositionString(composingStr);
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
TIP1.flushPendingComposition();
input.addEventListener("compositionupdate", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during cancelComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()");
}
}, {once: true});
input.addEventListener("text", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should throw an exception during cancelComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()");
}
}, {once: true});
input.addEventListener("compositionend", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during cancelComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()");
}
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should throw an exception during cancelComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()");
}
}, {once: true});
function onInput(aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during cancelComposition()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()");
}
}
input.addEventListener("input", onInput);
TIP1.cancelComposition();
is(events.length, kExpectInputBeforeCompositionEnd ? 6 : 5,
description + "compositionupdate, text, beforeinput, compositionend and input events should be fired by TIP1.cancelComposition()");
let index = -1;
is(events[++index].type, "compositionupdate",
`${description}events[${index}] should be compositionupdate`);
is(events[++index].type, "text",
`${description}events[${index}] should be text`);
is(events[++index].type, "beforeinput",
`${description}events[${index}] should be beforeinput`);
checkInputEvent(events[index], false, true, "insertCompositionText", "", description);
if (kExpectInputBeforeCompositionEnd) {
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, true, "insertCompositionText", "", description);
}
is(events[++index].type, "compositionend",
`${description}events[${index}] should be compositionend`);
is(events[++index].type, "input",
`${description}events[${index}] should be input`);
checkInputEvent(events[index], false, false, "insertCompositionText", "", description);
input.removeEventListener("input", onInput);
})();
// Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during keydown() and keyup();.
events = [];
TIP1.beginInputTransaction(window, simpleCallback);
input.addEventListener("keydown", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keydown\" should throw an exception during keydown()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keydown\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()");
}
}, {once: true});
input.addEventListener("keypress", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keypress\" should throw an exception during keydown()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keypress\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()");
}
}, {once: true});
input.addEventListener("beforeinput", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should throw an exception during keydown()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"beforeinput\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()");
}
}, {once: true});
input.addEventListener("input", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during keydown()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()");
}
}, {once: true});
input.addEventListener("keyup", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransaction(otherWindow, simpleCallback);
ok(false,
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keyup\" should throw an exception during keyup()");
} catch (e) {
ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"),
description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keyup\" should cause NS_ERROR_ALREADY_INITIALIZED during keyup()");
}
}, {once: true});
keyA = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A });
TIP1.keydown(keyA);
TIP1.keyup(keyA);
is(events.length, 5,
description + "keydown, keypress, beforeinput, input, keyup events should be fired by TIP1.keydown() and TIP1.keyup()");
is(events[0].type, "keydown",
description + "events[0] should be keydown");
is(events[1].type, "keypress",
description + "events[1] should be keypress");
is(events[2].type, "beforeinput",
description + "events[2] should be beforeinput");
checkInputEvent(events[2], true, false, "insertText", "a", description);
is(events[3].type, "input",
description + "events[3] should be input");
checkInputEvent(events[3], false, false, "insertText", "a", description);
is(events[4].type, "keyup",
description + "events[4] should be keyup");
// Let's check if beginInputTransactionForTests() with another window fails to begin new input transaction with different TextEventDispatcher during startComposition().
events = [];
input.addEventListener("compositionstart", function (aEvent) {
events.push(aEvent);
try {
TIP1.beginInputTransactionForTests(otherWindow, simpleCallback);
ok(false,
--> --------------------
--> maximum size reached
--> --------------------
[ Dauer der Verarbeitung: 0.54 Sekunden
(vorverarbeitet)
]
|
2026-04-02
|