mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1119609 part.13 EventUtils.synthesizeComposition() and synthesizeCompositionChange() should take KeyboardEvent for emulating composition state change caused by a key operation rs=smaug
This commit is contained in:
parent
60d702a190
commit
d837b657fd
@ -565,34 +565,28 @@ function synthesizeKey(aKey, aEvent, aWindow)
|
||||
{
|
||||
var utils = _getDOMWindowUtils(aWindow);
|
||||
if (utils) {
|
||||
var keyCode = 0, charCode = 0;
|
||||
if (aKey.indexOf("VK_") == 0) {
|
||||
keyCode = KeyEvent["DOM_" + aKey];
|
||||
if (!keyCode) {
|
||||
throw "Unknown key: " + aKey;
|
||||
}
|
||||
} else {
|
||||
charCode = aKey.charCodeAt(0);
|
||||
keyCode = _computeKeyCodeFromChar(aKey.charAt(0));
|
||||
}
|
||||
var keyEventDict = _createKeyboardEventDictionary(aKey, aEvent);
|
||||
var keyCode = keyEventDict.dictionary.keyCode;
|
||||
var charCode =
|
||||
(aKey.indexOf("VK_") == 0) ?
|
||||
0 : ((keyEventDict.dictionary.key != "") ?
|
||||
keyEventDict.dictionary.key.charCodeAt(0) : 0);
|
||||
|
||||
var modifiers = _parseModifiers(aEvent);
|
||||
var flags = 0;
|
||||
if (aEvent.location != undefined) {
|
||||
switch (aEvent.location) {
|
||||
case KeyboardEvent.DOM_KEY_LOCATION_STANDARD:
|
||||
flags |= utils.KEY_FLAG_LOCATION_STANDARD;
|
||||
break;
|
||||
case KeyboardEvent.DOM_KEY_LOCATION_LEFT:
|
||||
flags |= utils.KEY_FLAG_LOCATION_LEFT;
|
||||
break;
|
||||
case KeyboardEvent.DOM_KEY_LOCATION_RIGHT:
|
||||
flags |= utils.KEY_FLAG_LOCATION_RIGHT;
|
||||
break;
|
||||
case KeyboardEvent.DOM_KEY_LOCATION_NUMPAD:
|
||||
flags |= utils.KEY_FLAG_LOCATION_NUMPAD;
|
||||
break;
|
||||
}
|
||||
switch (keyEventDict.dictionary.location) {
|
||||
case KeyboardEvent.DOM_KEY_LOCATION_STANDARD:
|
||||
flags |= utils.KEY_FLAG_LOCATION_STANDARD;
|
||||
break;
|
||||
case KeyboardEvent.DOM_KEY_LOCATION_LEFT:
|
||||
flags |= utils.KEY_FLAG_LOCATION_LEFT;
|
||||
break;
|
||||
case KeyboardEvent.DOM_KEY_LOCATION_RIGHT:
|
||||
flags |= utils.KEY_FLAG_LOCATION_RIGHT;
|
||||
break;
|
||||
case KeyboardEvent.DOM_KEY_LOCATION_NUMPAD:
|
||||
flags |= utils.KEY_FLAG_LOCATION_NUMPAD;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!("type" in aEvent) || !aEvent.type) {
|
||||
@ -897,6 +891,279 @@ function _getTIP(aWindow, aCallback)
|
||||
return tip;
|
||||
}
|
||||
|
||||
function _guessKeyNameFromKeyCode(aKeyCode)
|
||||
{
|
||||
switch (aKeyCode) {
|
||||
case KeyboardEvent.DOM_VK_CANCEL:
|
||||
return "Cancel";
|
||||
case KeyboardEvent.DOM_VK_HELP:
|
||||
return "Help";
|
||||
case KeyboardEvent.DOM_VK_BACK_SPACE:
|
||||
return "Backspace";
|
||||
case KeyboardEvent.DOM_VK_TAB:
|
||||
return "Tab";
|
||||
case KeyboardEvent.DOM_VK_CLEAR:
|
||||
return "Clear";
|
||||
case KeyboardEvent.DOM_VK_RETURN:
|
||||
return "Enter";
|
||||
case KeyboardEvent.DOM_VK_SHIFT:
|
||||
return "Shift";
|
||||
case KeyboardEvent.DOM_VK_CONTROL:
|
||||
return "Control";
|
||||
case KeyboardEvent.DOM_VK_ALT:
|
||||
return "Alt";
|
||||
case KeyboardEvent.DOM_VK_PAUSE:
|
||||
return "Pause";
|
||||
case KeyboardEvent.DOM_VK_EISU:
|
||||
return "Eisu";
|
||||
case KeyboardEvent.DOM_VK_ESCAPE:
|
||||
return "Escape";
|
||||
case KeyboardEvent.DOM_VK_CONVERT:
|
||||
return "Convert";
|
||||
case KeyboardEvent.DOM_VK_NONCONVERT:
|
||||
return "NonConvert";
|
||||
case KeyboardEvent.DOM_VK_ACCEPT:
|
||||
return "Accept";
|
||||
case KeyboardEvent.DOM_VK_MODECHANGE:
|
||||
return "ModeChange";
|
||||
case KeyboardEvent.DOM_VK_PAGE_UP:
|
||||
return "PageUp";
|
||||
case KeyboardEvent.DOM_VK_PAGE_DOWN:
|
||||
return "PageDown";
|
||||
case KeyboardEvent.DOM_VK_END:
|
||||
return "End";
|
||||
case KeyboardEvent.DOM_VK_HOME:
|
||||
return "Home";
|
||||
case KeyboardEvent.DOM_VK_LEFT:
|
||||
return "ArrowLeft";
|
||||
case KeyboardEvent.DOM_VK_UP:
|
||||
return "ArrowUp";
|
||||
case KeyboardEvent.DOM_VK_RIGHT:
|
||||
return "ArrowRight";
|
||||
case KeyboardEvent.DOM_VK_DOWN:
|
||||
return "ArrowDown";
|
||||
case KeyboardEvent.DOM_VK_SELECT:
|
||||
return "Select";
|
||||
case KeyboardEvent.DOM_VK_PRINT:
|
||||
return "Print";
|
||||
case KeyboardEvent.DOM_VK_EXECUTE:
|
||||
return "Execute";
|
||||
case KeyboardEvent.DOM_VK_PRINTSCREEN:
|
||||
return "PrintScreen";
|
||||
case KeyboardEvent.DOM_VK_INSERT:
|
||||
return "Insert";
|
||||
case KeyboardEvent.DOM_VK_DELETE:
|
||||
return "Delete";
|
||||
case KeyboardEvent.DOM_VK_WIN:
|
||||
return "OS";
|
||||
case KeyboardEvent.DOM_VK_CONTEXT_MENU:
|
||||
return "ContextMenu";
|
||||
case KeyboardEvent.DOM_VK_SLEEP:
|
||||
return "Standby";
|
||||
case KeyboardEvent.DOM_VK_F1:
|
||||
return "F1";
|
||||
case KeyboardEvent.DOM_VK_F2:
|
||||
return "F2";
|
||||
case KeyboardEvent.DOM_VK_F3:
|
||||
return "F3";
|
||||
case KeyboardEvent.DOM_VK_F4:
|
||||
return "F4";
|
||||
case KeyboardEvent.DOM_VK_F5:
|
||||
return "F5";
|
||||
case KeyboardEvent.DOM_VK_F6:
|
||||
return "F6";
|
||||
case KeyboardEvent.DOM_VK_F7:
|
||||
return "F7";
|
||||
case KeyboardEvent.DOM_VK_F8:
|
||||
return "F8";
|
||||
case KeyboardEvent.DOM_VK_F9:
|
||||
return "F9";
|
||||
case KeyboardEvent.DOM_VK_F10:
|
||||
return "F10";
|
||||
case KeyboardEvent.DOM_VK_F11:
|
||||
return "F11";
|
||||
case KeyboardEvent.DOM_VK_F12:
|
||||
return "F12";
|
||||
case KeyboardEvent.DOM_VK_F13:
|
||||
return "F13";
|
||||
case KeyboardEvent.DOM_VK_F14:
|
||||
return "F14";
|
||||
case KeyboardEvent.DOM_VK_F15:
|
||||
return "F15";
|
||||
case KeyboardEvent.DOM_VK_F16:
|
||||
return "F16";
|
||||
case KeyboardEvent.DOM_VK_F17:
|
||||
return "F17";
|
||||
case KeyboardEvent.DOM_VK_F18:
|
||||
return "F18";
|
||||
case KeyboardEvent.DOM_VK_F19:
|
||||
return "F19";
|
||||
case KeyboardEvent.DOM_VK_F20:
|
||||
return "F20";
|
||||
case KeyboardEvent.DOM_VK_F21:
|
||||
return "F21";
|
||||
case KeyboardEvent.DOM_VK_F22:
|
||||
return "F22";
|
||||
case KeyboardEvent.DOM_VK_F23:
|
||||
return "F23";
|
||||
case KeyboardEvent.DOM_VK_F24:
|
||||
return "F24";
|
||||
case KeyboardEvent.DOM_VK_NUM_LOCK:
|
||||
return "NumLock";
|
||||
case KeyboardEvent.DOM_VK_SCROLL_LOCK:
|
||||
return "ScrollLock";
|
||||
case KeyboardEvent.DOM_VK_VOLUME_MUTE:
|
||||
return "VolumeMute";
|
||||
case KeyboardEvent.DOM_VK_VOLUME_DOWN:
|
||||
return "VolumeDown";
|
||||
case KeyboardEvent.DOM_VK_VOLUME_UP:
|
||||
return "VolumeUp";
|
||||
case KeyboardEvent.DOM_VK_META:
|
||||
return "Meta";
|
||||
case KeyboardEvent.DOM_VK_ALTGR:
|
||||
return "AltGraph";
|
||||
case KeyboardEvent.DOM_VK_ATTN:
|
||||
return "Attn";
|
||||
case KeyboardEvent.DOM_VK_CRSEL:
|
||||
return "CrSel";
|
||||
case KeyboardEvent.DOM_VK_EXSEL:
|
||||
return "ExSel";
|
||||
case KeyboardEvent.DOM_VK_EREOF:
|
||||
return "EraseEof";
|
||||
case KeyboardEvent.DOM_VK_PLAY:
|
||||
return "Play";
|
||||
default:
|
||||
return "Unidentified";
|
||||
}
|
||||
}
|
||||
|
||||
function _createKeyboardEventDictionary(aKey, aKeyEvent)
|
||||
{
|
||||
var result = { dictionary: null, flags: 0 };
|
||||
|
||||
var keyCodeIsDefined = "keyCode" in aKeyEvent;
|
||||
var keyCode =
|
||||
(keyCodeIsDefined && aKeyEvent.keyCode >= 0 && aKeyEvent.keyCode <= 255) ?
|
||||
aKeyEvent.keyCode : 0;
|
||||
var keyName = "Unidentified";
|
||||
if (aKey.indexOf("KEY_") == 0) {
|
||||
keyName = aKey.substr("KEY_".length);
|
||||
result.flags |= _EU_Ci.nsITextInputProcessor.KEY_NON_PRINTABLE_KEY;
|
||||
} else if (aKey.indexOf("VK_") == 0) {
|
||||
keyCode = KeyEvent["DOM_" + aKey];
|
||||
if (!keyCode) {
|
||||
throw "Unknown key: " + aKey;
|
||||
}
|
||||
keyName = _guessKeyNameFromKeyCode(keyCode);
|
||||
result.flags |= _EU_Ci.nsITextInputProcessor.KEY_NON_PRINTABLE_KEY;
|
||||
} else if (aKey != "") {
|
||||
keyName = aKey;
|
||||
if (!keyCodeIsDefined) {
|
||||
keyCode = _computeKeyCodeFromChar(aKey.charAt(0));
|
||||
}
|
||||
if (!keyCode) {
|
||||
result.flags |= _EU_Ci.nsITextInputProcessor.KEY_KEEP_KEYCODE_ZERO;
|
||||
}
|
||||
result.flags |= _EU_Ci.nsITextInputProcessor.KEY_FORCE_PRINTABLE_KEY;
|
||||
}
|
||||
var locationIsDefined = "location" in aKeyEvent;
|
||||
if (locationIsDefined && aKeyEvent.location === 0) {
|
||||
result.flags |= _EU_Ci.nsITextInputProcessor.KEY_KEEP_KEY_LOCATION_STANDARD;
|
||||
}
|
||||
result.dictionary = {
|
||||
key: keyName,
|
||||
code: "code" in aKeyEvent ? aKeyEvent.code : "",
|
||||
location: locationIsDefined ? aKeyEvent.location : 0,
|
||||
repeat: "repeat" in aKeyEvent ? aKeyEvent.repeat : false,
|
||||
keyCode: keyCode,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
function _emulateToActivateModifiers(aTIP, aKeyEvent)
|
||||
{
|
||||
if (!aKeyEvent) {
|
||||
return null;
|
||||
}
|
||||
var modifiers = {
|
||||
normal: [
|
||||
{ key: "Alt", attr: "altKey" },
|
||||
{ key: "AltGraph", attr: "altGraphKey" },
|
||||
{ key: "Control", attr: "ctrlKey" },
|
||||
{ key: "Fn", attr: "fnKey" },
|
||||
{ key: "Meta", attr: "metaKey" },
|
||||
{ key: "OS", attr: "osKey" },
|
||||
{ key: "Shift", attr: "shiftKey" },
|
||||
{ key: "Symbol", attr: "symbolKey" },
|
||||
{ key: (navigator.platform.indexOf("Mac") >= 0) ? "Meta" : "Control",
|
||||
attr: "accelKey" },
|
||||
],
|
||||
lockable: [
|
||||
{ key: "CapsLock", attr: "capsLockKey" },
|
||||
{ key: "FnLock", attr: "fnLockKey" },
|
||||
{ key: "NumLock", attr: "numLockKey" },
|
||||
{ key: "ScrollLock", attr: "scrollLockKey" },
|
||||
{ key: "SymbolLock", attr: "symbolLockKey" },
|
||||
]
|
||||
}
|
||||
|
||||
for (var i = 0; i < modifiers.normal.length; i++) {
|
||||
if (!aKeyEvent[modifiers.normal[i].attr]) {
|
||||
continue;
|
||||
}
|
||||
if (aTIP.getModifierState(modifiers.normal[i].key)) {
|
||||
continue; // already activated.
|
||||
}
|
||||
var event = new KeyboardEvent("", { key: modifiers.normal[i].key });
|
||||
aTIP.keydown(event,
|
||||
aTIP.KEY_NON_PRINTABLE_KEY | aTIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
|
||||
modifiers.normal[i].activated = true;
|
||||
}
|
||||
for (var i = 0; i < modifiers.lockable.length; i++) {
|
||||
if (!aKeyEvent[modifiers.lockable[i].attr]) {
|
||||
continue;
|
||||
}
|
||||
if (aTIP.getModifierState(modifiers.lockable[i].key)) {
|
||||
continue; // already activated.
|
||||
}
|
||||
var event = new KeyboardEvent("", { key: modifiers.lockable[i].key });
|
||||
aTIP.keydown(event,
|
||||
aTIP.KEY_NON_PRINTABLE_KEY | aTIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
|
||||
aTIP.keyup(event,
|
||||
aTIP.KEY_NON_PRINTABLE_KEY | aTIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
|
||||
modifiers.lockable[i].activated = true;
|
||||
}
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
function _emulateToInactivateModifiers(aTIP, aModifiers)
|
||||
{
|
||||
if (!aModifiers) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < aModifiers.normal.length; i++) {
|
||||
if (!aModifiers.normal[i].activated) {
|
||||
continue;
|
||||
}
|
||||
var event = new KeyboardEvent("", { key: aModifiers.normal[i].key });
|
||||
aTIP.keyup(event,
|
||||
aTIP.KEY_NON_PRINTABLE_KEY | aTIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
|
||||
}
|
||||
for (var i = 0; i < aModifiers.lockable.length; i++) {
|
||||
if (!aModifiers.lockable[i].activated) {
|
||||
continue;
|
||||
}
|
||||
if (!aTIP.getModifierState(aModifiers.lockable[i].key)) {
|
||||
continue; // who already inactivated this?
|
||||
}
|
||||
var event = new KeyboardEvent("", { key: aModifiers.lockable[i].key });
|
||||
aTIP.keydown(event,
|
||||
aTIP.KEY_NON_PRINTABLE_KEY | aTIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
|
||||
aTIP.keyup(event,
|
||||
aTIP.KEY_NON_PRINTABLE_KEY | aTIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize a composition event.
|
||||
*
|
||||
@ -909,6 +1176,11 @@ function _getTIP(aWindow, aCallback)
|
||||
* the composition event. Note that the |data| is
|
||||
* ignored if the event type is "compositionstart"
|
||||
* or "compositioncommitasis".
|
||||
* If |key| is specified, the key event may be
|
||||
* dispatched. This can emulates changing
|
||||
* composition state caused by key operation.
|
||||
* Its key value should start with "KEY_" if the
|
||||
* value is non-printable key name defined in D3E.
|
||||
* @param aWindow Optional (If null, current |window| will be used)
|
||||
* @param aCallback Optional (If non-null, use the callback for
|
||||
* receiving notifications to IME)
|
||||
@ -919,15 +1191,32 @@ function synthesizeComposition(aEvent, aWindow, aCallback)
|
||||
if (!TIP) {
|
||||
return false;
|
||||
}
|
||||
switch (aEvent.type) {
|
||||
case "compositionstart":
|
||||
return TIP.startComposition();
|
||||
case "compositioncommitasis":
|
||||
return TIP.commitComposition();
|
||||
case "compositioncommit":
|
||||
return TIP.commitComposition(null, 0, aEvent.data);
|
||||
default:
|
||||
return false;
|
||||
var modifiers = _emulateToActivateModifiers(TIP, aEvent.key);
|
||||
var ret = false;
|
||||
var keyEventDict =
|
||||
"key" in aEvent ?
|
||||
_createKeyboardEventDictionary(aEvent.key.key, aEvent.key) :
|
||||
{ dictionary: null, flags: 0 };
|
||||
var keyEvent =
|
||||
"key" in aEvent ?
|
||||
new KeyboardEvent(aEvent.type === "keydown" ? "keydown" : "",
|
||||
keyEventDict.dictionary) :
|
||||
null;
|
||||
try {
|
||||
switch (aEvent.type) {
|
||||
case "compositionstart":
|
||||
ret = TIP.startComposition(keyEvent, keyEventDict.flags);
|
||||
break;
|
||||
case "compositioncommitasis":
|
||||
ret = TIP.commitComposition(keyEvent, keyEventDict.flags);
|
||||
break;
|
||||
case "compositioncommit":
|
||||
ret = TIP.commitComposition(keyEvent, keyEventDict.flags,
|
||||
aEvent.data);
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
_emulateToInactivateModifiers(TIP, modifiers);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -947,8 +1236,9 @@ function synthesizeComposition(aEvent, aWindow, aCallback)
|
||||
* | +-- length
|
||||
* | +-- attr
|
||||
* +-- caret
|
||||
* +-- start
|
||||
* +-- length
|
||||
* | +-- start
|
||||
* | +-- length
|
||||
* +-- key
|
||||
*
|
||||
* Set the composition string to |composition.string|. Set its
|
||||
* clauses information to the |clauses| array.
|
||||
@ -969,6 +1259,11 @@ function synthesizeComposition(aEvent, aWindow, aCallback)
|
||||
* caret. However, current nsEditor doesn't support wide
|
||||
* caret, therefore, you should always set 0 now.
|
||||
*
|
||||
* If |key| is specified, the key event may be dispatched.
|
||||
* This can emulates changing composition state caused by key
|
||||
* operation. Its key value should start with "KEY_" if the
|
||||
* value is non-printable key name defined in D3E.
|
||||
*
|
||||
* @param aWindow Optional (If null, current |window| will be used)
|
||||
* @param aCallback Optional (If non-null, use the callback for receiving
|
||||
* notifications to IME)
|
||||
@ -1011,7 +1306,21 @@ function synthesizeCompositionChange(aEvent, aWindow, aCallback)
|
||||
TIP.setCaretInPendingComposition(aEvent.caret.start);
|
||||
}
|
||||
|
||||
TIP.flushPendingComposition();
|
||||
var modifiers = _emulateToActivateModifiers(TIP, aEvent.key);
|
||||
try {
|
||||
var keyEventDict =
|
||||
"key" in aEvent ?
|
||||
_createKeyboardEventDictionary(aEvent.key.key, aEvent.key) :
|
||||
{ dictionary: null, flags: 0 };
|
||||
var keyEvent =
|
||||
"key" in aEvent ?
|
||||
new KeyboardEvent(aEvent.type === "keydown" ? "keydown" : "",
|
||||
keyEventDict.dictionary) :
|
||||
null;
|
||||
TIP.flushPendingComposition(keyEvent, keyEventDict.flags);
|
||||
} finally {
|
||||
_emulateToInactivateModifiers(TIP, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
// Must be synchronized with nsIDOMWindowUtils.
|
||||
|
@ -86,7 +86,6 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "compositionstart shouldn't open the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow);
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "M",
|
||||
@ -95,7 +94,9 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "M", code: "KeyM", keyCode: KeyboardEvent.DOM_VK_M,
|
||||
shiftKey: true },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "M", searchString: ""
|
||||
},
|
||||
@ -110,15 +111,16 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
"caret": { "start": 2, "length": 0 },
|
||||
"key": { key: "o", code: "KeyO", keyCode: KeyboardEvent.DOM_VK_O },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mo", searchString: ""
|
||||
},
|
||||
{ description: "compositionend should open the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeComposition({ type: "compositioncommitasis" }, aWindow);
|
||||
synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow);
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Enter", code: "Enter" } }, aWindow);
|
||||
}, popup: true, value: "Mo", searchString: "Mo"
|
||||
},
|
||||
// If composition starts when popup is shown, the compositionstart event
|
||||
@ -126,7 +128,6 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "compositionstart should close the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeKey("z", { type: "keydown" }, aWindow);
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "z",
|
||||
@ -135,7 +136,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "z", code: "KeyZ", keyCode: KeyboardEvent.DOM_VK_Z },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Moz", searchString: "Mo"
|
||||
},
|
||||
@ -150,22 +152,22 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
"caret": { "start": 2, "length": 0 },
|
||||
"key": { key: "i", code: "KeyI", keyCode: KeyboardEvent.DOM_VK_I },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mozi", searchString: "Mo"
|
||||
},
|
||||
{ description: "compositionend should research the result and open the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeComposition({ type: "compositioncommitasis" }, aWindow);
|
||||
synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow);
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Enter", code: "Enter" } }, aWindow);
|
||||
}, popup: true, value: "Mozi", searchString: "Mozi"
|
||||
},
|
||||
// If composition is cancelled, the value shouldn't be changed.
|
||||
{ description: "compositionstart should reclose the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeKey("l", { type: "keydown" }, aWindow);
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "l",
|
||||
@ -174,7 +176,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "l", code: "KeyL", keyCode: KeyboardEvent.DOM_VK_L },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mozil", searchString: "Mozi"
|
||||
},
|
||||
@ -189,7 +192,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
"caret": { "start": 2, "length": 0 },
|
||||
"key": { key: "l", code: "KeyL", keyCode: KeyboardEvent.DOM_VK_L },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mozill", searchString: "Mozi"
|
||||
},
|
||||
@ -211,8 +215,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "cancled compositionend should reopen the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeComposition({ type: "compositioncommit", data: "" }, aWindow);
|
||||
synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
|
||||
synthesizeComposition({ type: "compositioncommit", data: "",
|
||||
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
|
||||
}, popup: true, value: "Mozi", searchString: "Mozi"
|
||||
},
|
||||
// But if composition replaces some characters and canceled, the search
|
||||
@ -222,7 +226,6 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
execute: function (aWindow) {
|
||||
synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow);
|
||||
synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow);
|
||||
synthesizeKey("z", { type: "keydown" }, aWindow);
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "z",
|
||||
@ -231,7 +234,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "z", code: "KeyZ", keyCode: KeyboardEvent.DOM_VK_Z },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Moz", searchString: "Mozi"
|
||||
},
|
||||
@ -246,7 +250,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
"caret": { "start": 2, "length": 0 },
|
||||
"key": { key: "i", code: "KeyI", keyCode: KeyboardEvent.DOM_VK_I },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mozi", searchString: "Mozi"
|
||||
},
|
||||
@ -268,8 +273,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "canceled compositionend should seach the result with the latest value",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeComposition({ type: "compositioncommitasis" }, aWindow);
|
||||
synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
|
||||
}, popup: true, value: "Mo", searchString: "Mo"
|
||||
},
|
||||
//If all characters are removed, the popup should be closed.
|
||||
@ -284,7 +289,6 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "compositionstart shouldn't open the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow);
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "M",
|
||||
@ -293,7 +297,9 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "m", code: "KeyM", keyCode: KeyboardEvent.DOM_VK_M,
|
||||
shiftKey: true },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "M", searchString: ""
|
||||
},
|
||||
@ -308,7 +314,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
"caret": { "start": 2, "length": 0 },
|
||||
"key": { key: "o", code: "KeyO", keyCode: KeyboardEvent.DOM_VK_O },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mo", searchString: ""
|
||||
},
|
||||
@ -330,8 +337,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "canceled compositionend shouldn't open the popup if it was closed",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeComposition({ type: "compositioncommitasis" }, aWindow);
|
||||
synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
|
||||
}, popup: false, value: "", searchString: ""
|
||||
},
|
||||
// Down key should open the popup even if the editor is empty.
|
||||
@ -346,7 +353,6 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "compositionstart shouldn't open the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow);
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "M",
|
||||
@ -355,7 +361,9 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "M", code: "KeyM", keyCode: KeyboardEvent.DOM_VK_M,
|
||||
shiftKey: true },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "M", searchString: ""
|
||||
},
|
||||
@ -370,7 +378,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
"caret": { "start": 2, "length": 0 },
|
||||
"key": { key: "o", code: "KeyO", keyCode: KeyboardEvent.DOM_VK_O },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mo", searchString: ""
|
||||
},
|
||||
@ -392,8 +401,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "canceled compositionend should open the popup if it was opened",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeComposition({ type: "compositioncommitasis" }, aWindow);
|
||||
synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
|
||||
}, popup: true, value: "", searchString: ""
|
||||
},
|
||||
// Type normally, and hit escape, the popup should be closed.
|
||||
@ -411,7 +420,6 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "compositionstart shouldn't open the popup",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeKey("z", { type: "keydown", shiftKey: true }, aWindow);
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "z",
|
||||
@ -420,7 +428,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "z", code: "KeyZ", keyCode: KeyboardEvent.DOM_VK_Z },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Moz", searchString: "Mo"
|
||||
},
|
||||
@ -435,7 +444,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
"caret": { "start": 2, "length": 0 },
|
||||
"key": { key: "i", code: "KeyI", keyCode: KeyboardEvent.DOM_VK_I },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mozi", searchString: "Mo"
|
||||
},
|
||||
@ -457,8 +467,8 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "canceled compositionend shouldn't open the popup if the popup was closed",
|
||||
completeDefaultIndex: false,
|
||||
execute: function (aWindow) {
|
||||
synthesizeComposition({ type: "compositioncommitasis" }, aWindow);
|
||||
synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
|
||||
}, popup: true, value: "Mo", searchString: "Mo"
|
||||
},
|
||||
// House keeping...
|
||||
@ -473,7 +483,6 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ description: "compositionstart shouldn't open the popup (completeDefaultIndex is true)",
|
||||
completeDefaultIndex: true,
|
||||
execute: function (aWindow) {
|
||||
synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow);
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
{ "string": "M",
|
||||
@ -482,7 +491,9 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "M", code: "KeyM", keyCode: KeyboardEvent.DOM_VK_M,
|
||||
shiftKey: true },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "M", searchString: ""
|
||||
},
|
||||
@ -497,15 +508,16 @@ nsDoTestsForAutoCompleteWithComposition.prototype = {
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
"caret": { "start": 2, "length": 0 },
|
||||
"key": { key: "o", code: "KeyO", keyCode: KeyboardEvent.DOM_VK_O },
|
||||
}, aWindow);
|
||||
}, popup: false, value: "Mo", searchString: ""
|
||||
},
|
||||
{ description: "compositionend should open the popup (completeDefaultIndex is true)",
|
||||
completeDefaultIndex: true,
|
||||
execute: function (aWindow) {
|
||||
synthesizeComposition({ type: "compositioncommitasis" }, aWindow);
|
||||
synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow);
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Enter", code: "Enter" } }, aWindow);
|
||||
}, popup: true, value: "Mozilla", searchString: "Mo"
|
||||
},
|
||||
// House keeping...
|
||||
|
@ -172,9 +172,9 @@ const kTests = [
|
||||
{ description: "WidgetKeyboardEvent (keyup during composition)",
|
||||
targetID: "input-text", eventType: "keyup",
|
||||
dispatchEvent: function () {
|
||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
||||
document.getElementById(this.targetID).value = "";
|
||||
document.getElementById(this.targetID).focus();
|
||||
synthesizeKey("a", { type: "keydown" });
|
||||
synthesizeCompositionChange({ "composition":
|
||||
{ "string": "\u306D",
|
||||
"clauses":
|
||||
@ -182,10 +182,11 @@ const kTests = [
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A },
|
||||
});
|
||||
synthesizeKey("a", { type: "keyup" });
|
||||
synthesizeComposition({ type: "compositioncommitasis" });
|
||||
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
||||
},
|
||||
canRun: function () {
|
||||
return true;
|
||||
@ -195,6 +196,7 @@ const kTests = [
|
||||
{ description: "WidgetKeyboardEvent (keydown during composition)",
|
||||
targetID: "input-text", eventType: "keydown",
|
||||
dispatchEvent: function () {
|
||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
||||
document.getElementById(this.targetID).value = "";
|
||||
document.getElementById(this.targetID).focus();
|
||||
synthesizeCompositionChange({ "composition":
|
||||
@ -206,9 +208,9 @@ const kTests = [
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
});
|
||||
synthesizeKey("VK_RETURN", { type: "keydown" });
|
||||
synthesizeComposition({ type: "compositioncommitasis" });
|
||||
synthesizeKey("VK_RETURN", { type: "keyup" });
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Enter", code: "Enter" } });
|
||||
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
||||
},
|
||||
canRun: function () {
|
||||
return true;
|
||||
|
@ -2938,10 +2938,10 @@ function runIsComposingTest()
|
||||
|
||||
// XXX These cases shouldn't occur in actual native key events because we
|
||||
// don't dispatch key events while composition (bug 354358).
|
||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
||||
description = "events before dispatching compositionstart";
|
||||
synthesizeKey("VK_LEFT", {});
|
||||
|
||||
synthesizeKey("a", { type: "keydown" });
|
||||
description = "events after dispatching compositionchange";
|
||||
synthesizeCompositionChange(
|
||||
{ "composition":
|
||||
@ -2951,23 +2951,25 @@ function runIsComposingTest()
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
"caret": { "start": 1, "length": 0 },
|
||||
"key": { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A },
|
||||
});
|
||||
synthesizeKey("a", { type: "keyup" });
|
||||
|
||||
// Although, firing keypress event during composition is a bug.
|
||||
synthesizeKey("VK_INSERT", {});
|
||||
|
||||
description = "events for committing composition string";
|
||||
synthesizeKey("VK_RETURN", { type: "keydown" });
|
||||
|
||||
synthesizeComposition({ type: "compositioncommitasis" });
|
||||
synthesizeComposition({ type: "compositioncommitasis",
|
||||
key: { key: "KEY_Enter", code: "Enter", type: "keydown" } });
|
||||
|
||||
// input event will be fired by synthesizing compositionend event.
|
||||
// Then, its isComposing should be false.
|
||||
description = "events after dispatching compositioncommitasis";
|
||||
synthesizeKey("VK_RETURN", { type: "keyup" });
|
||||
|
||||
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
||||
|
||||
textarea.removeEventListener("keydown", eventHandler, true);
|
||||
textarea.removeEventListener("keypress", eventHandler, true);
|
||||
textarea.removeEventListener("keyup", eventHandler, true);
|
||||
|
Loading…
Reference in New Issue
Block a user