summaryrefslogtreecommitdiffstats
path: root/dom/inputmethod/mochitest/bug1110030_helper.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/inputmethod/mochitest/bug1110030_helper.js')
-rw-r--r--dom/inputmethod/mochitest/bug1110030_helper.js267
1 files changed, 267 insertions, 0 deletions
diff --git a/dom/inputmethod/mochitest/bug1110030_helper.js b/dom/inputmethod/mochitest/bug1110030_helper.js
new file mode 100644
index 000000000..54f15825b
--- /dev/null
+++ b/dom/inputmethod/mochitest/bug1110030_helper.js
@@ -0,0 +1,267 @@
+// ***********************************
+// * Global variables
+// ***********************************
+const kIsWin = navigator.platform.indexOf("Win") == 0;
+
+// Bit value for the keyboard events
+const kKeyDown = 0x01;
+const kKeyPress = 0x02;
+const kKeyUp = 0x04;
+
+// Pair the event name to its bit value
+const kEventCode = {
+ 'keydown' : kKeyDown,
+ 'keypress' : kKeyPress,
+ 'keyup' : kKeyUp
+};
+
+// Holding the current test case's infomation:
+var gCurrentTest;
+
+// The current used input method of this test
+var gInputMethod;
+
+// ***********************************
+// * Utilities
+// ***********************************
+function addKeyEventListeners(eventTarget, handler)
+{
+ Object.keys(kEventCode).forEach(function(type) {
+ eventTarget.addEventListener(type, handler);
+ });
+}
+
+function eventToCode(type)
+{
+ return kEventCode[type];
+}
+
+// To test key events that will be generated by input method here,
+// we need to convert alphabets to native key code.
+// (Our input method for testing will handle alphabets)
+// On the other hand, to test key events that will not be generated by IME,
+// we use 0-9 for such case in our testing.
+function guessNativeKeyCode(key)
+{
+ let nativeCodeName = (kIsWin)? 'WIN_VK_' : 'MAC_VK_ANSI_';
+ if (/^[A-Z]$/.test(key)) {
+ nativeCodeName += key;
+ } else if (/^[a-z]$/.test(key)) {
+ nativeCodeName += key.toUpperCase();
+ } else if (/^[0-9]$/.test(key)) {
+ nativeCodeName += key.toString();
+ } else {
+ return 0;
+ }
+
+ return eval(nativeCodeName);
+}
+
+// ***********************************
+// * Frame loader and frame scripts
+// ***********************************
+function frameScript()
+{
+ function handler(e) {
+ sendAsyncMessage("forwardevent", { type: e.type, key: e.key });
+ }
+ function notifyFinish(e) {
+ if (e.type != 'keyup') return;
+ sendAsyncMessage("finish");
+ }
+ let input = content.document.getElementById('test-input');
+ input.addEventListener('keydown', handler);
+ input.addEventListener('keypress', handler);
+ input.addEventListener('keyup', handler);
+ input.addEventListener('keyup', notifyFinish);
+}
+
+function loadTestFrame(goNext) {
+ let iframe = document.createElement('iframe');
+ iframe.src = 'file_test_empty_app.html';
+ iframe.setAttribute('mozbrowser', true);
+
+ iframe.addEventListener("mozbrowserloadend", function onloadend() {
+ iframe.removeEventListener("mozbrowserloadend", onloadend);
+ iframe.focus();
+ var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
+ mm.addMessageListener("forwardevent", function(msg) {
+ inputtextEventReceiver(msg.json);
+ });
+ mm.addMessageListener("finish", function(msg) {
+ if(goNext) {
+ goNext();
+ }
+ });
+ mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
+ return;
+ });
+
+ document.body.appendChild(iframe);
+}
+
+// ***********************************
+// * Event firer and listeners
+// ***********************************
+function fireEvent(callback)
+{
+ let key = gCurrentTest.key;
+ synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, guessNativeKeyCode(key), {},
+ key, key, (callback) ? callback : null);
+}
+
+function hardwareEventReceiver(evt)
+{
+ if (!gCurrentTest) {
+ return;
+ }
+ gCurrentTest.hardwareinput.receivedEvents |= eventToCode(evt.type);
+ gCurrentTest.hardwareinput.receivedKeys += evt.key;
+}
+
+function inputtextEventReceiver(evt)
+{
+ if (!gCurrentTest) {
+ return;
+ }
+ gCurrentTest.inputtext.receivedEvents |= eventToCode(evt.type);
+ gCurrentTest.inputtext.receivedKeys += evt.key;
+}
+
+// ***********************************
+// * Event verifier
+// ***********************************
+function verifyResults(test)
+{
+ // Verify results received from inputcontent.hardwareinput
+ is(test.hardwareinput.receivedEvents,
+ test.hardwareinput.expectedEvents,
+ "received events from inputcontent.hardwareinput are wrong");
+
+ is(test.hardwareinput.receivedKeys,
+ test.hardwareinput.expectedKeys,
+ "received keys from inputcontent.hardwareinput are wrong");
+
+ // Verify results received from actual input text
+ is(test.inputtext.receivedEvents,
+ test.inputtext.expectedEvents,
+ "received events from input text are wrong");
+
+ is(test.inputtext.receivedKeys,
+ test.inputtext.expectedKeys,
+ "received keys from input text are wrong");
+}
+
+function areEventsSame(test)
+{
+ return (test.hardwareinput.receivedEvents ==
+ test.hardwareinput.expectedEvents) &&
+ (test.inputtext.receivedEvents ==
+ test.inputtext.expectedEvents);
+}
+
+// ***********************************
+// * Input Method
+// ***********************************
+// The method input used in this test
+// only handles alphabets
+function InputMethod(inputContext)
+{
+ this._inputContext = inputContext;
+ this.init();
+}
+
+InputMethod.prototype = {
+ init: function im_init() {
+ this._setKepMap();
+ },
+
+ handler: function im_handler(evt) {
+ // Ignore the key if the event is defaultPrevented
+ if (evt.defaultPrevented) {
+ return;
+ }
+
+ // Finish if there is no _inputContext
+ if (!this._inputContext) {
+ return;
+ }
+
+ // Generate the keyDict for inputcontext.keydown/keyup
+ let keyDict = this._generateKeyDict(evt);
+
+ // Ignore the key if IME doesn't want to handle it
+ if (!keyDict) {
+ return;
+ }
+
+ // Call preventDefault if the key will be handled.
+ evt.preventDefault();
+
+ // Call inputcontext.keydown/keyup
+ this._inputContext[evt.type](keyDict);
+ },
+
+ mapKey: function im_keymapping(key) {
+ if (!this._mappingTable) {
+ return;
+ }
+ return this._mappingTable[key];
+ },
+
+ _setKepMap: function im_setKeyMap() {
+ // A table to map characters:
+ // {
+ // 'A': 'B'
+ // 'a': 'b'
+ // 'B': 'C'
+ // 'b': 'c'
+ // ..
+ // ..
+ // 'Z': 'A',
+ // 'z': 'a',
+ // }
+ this._mappingTable = {};
+
+ let rotation = 1;
+
+ for (let i = 0 ; i < 26 ; i++) {
+ // Convert 'A' to 'B', 'B' to 'C', ..., 'Z' to 'A'
+ this._mappingTable[String.fromCharCode(i + 'A'.charCodeAt(0))] =
+ String.fromCharCode((i+rotation)%26 + 'A'.charCodeAt(0));
+
+ // Convert 'a' to 'b', 'b' to 'c', ..., 'z' to 'a'
+ this._mappingTable[String.fromCharCode(i + 'a'.charCodeAt(0))] =
+ String.fromCharCode((i+rotation)%26 + 'a'.charCodeAt(0));
+ }
+ },
+
+ _generateKeyDict: function im_generateKeyDict(evt) {
+
+ let mappedKey = this.mapKey(evt.key);
+
+ if (!mappedKey) {
+ return;
+ }
+
+ let keyDict = {
+ key: mappedKey,
+ code: this._guessCodeFromKey(mappedKey),
+ repeat: evt.repeat,
+ };
+
+ return keyDict;
+ },
+
+ _guessCodeFromKey: function im_guessCodeFromKey(key) {
+ if (/^[A-Z]$/.test(key)) {
+ return "Key" + key;
+ } else if (/^[a-z]$/.test(key)) {
+ return "Key" + key.toUpperCase();
+ } else if (/^[0-9]$/.test(key)) {
+ return "Digit" + key.toString();
+ } else {
+ return 0;
+ }
+ },
+};