gecko-dev/dom/inputmethod/mochitest/bug1110030_helper.js

268 строки
6.8 KiB
JavaScript

// ***********************************
// * 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;
}
},
};