mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1093153 - Introduce 'BrowserTestUtils#synthesizeKey', 'BrowserTestUtils#synthesizeComposition' and 'BrowserTestUtils#synthesizeCompositionChange' to allow mochitests to remotely invoke EventUtils' text composition utilities. Changes to EventUtils include 1) removed dependency on the 'navigator' object when 'nsIXULRuntime' is available and 2) make '_getKeyboardEvent' more robust when used in frame scripts. r=Enn, a=test-only
This commit is contained in:
parent
40e492b522
commit
b6b5962e27
@ -38,6 +38,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
|
|||||||
Cu.permitCPOWsInScope(this);
|
Cu.permitCPOWsInScope(this);
|
||||||
|
|
||||||
var gSendCharCount = 0;
|
var gSendCharCount = 0;
|
||||||
|
var gSynthesizeKeyCount = 0;
|
||||||
|
var gSynthesizeCompositionCount = 0;
|
||||||
|
var gSynthesizeCompositionChangeCount = 0;
|
||||||
|
|
||||||
this.BrowserTestUtils = {
|
this.BrowserTestUtils = {
|
||||||
/**
|
/**
|
||||||
@ -827,7 +830,7 @@ this.BrowserTestUtils = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Version of EventUtils' `sendChar` function; it will synthesize a keypress
|
* Version of EventUtils' `sendChar` function; it will synthesize a keypress
|
||||||
* event in a child process and returns a Promise that will result when the
|
* event in a child process and returns a Promise that will resolve when the
|
||||||
* event was fired. Instead of a Window, a Browser object is required to be
|
* event was fired. Instead of a Window, a Browser object is required to be
|
||||||
* passed to this function.
|
* passed to this function.
|
||||||
*
|
*
|
||||||
@ -849,7 +852,7 @@ this.BrowserTestUtils = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
mm.removeMessageListener("Test:SendCharDone", charMsg);
|
mm.removeMessageListener("Test:SendCharDone", charMsg);
|
||||||
resolve(message.data.sendCharResult);
|
resolve(message.data.result);
|
||||||
});
|
});
|
||||||
|
|
||||||
mm.sendAsyncMessage("Test:SendChar", {
|
mm.sendAsyncMessage("Test:SendChar", {
|
||||||
@ -859,6 +862,99 @@ this.BrowserTestUtils = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version of EventUtils' `synthesizeKey` function; it will synthesize a key
|
||||||
|
* event in a child process and returns a Promise that will resolve when the
|
||||||
|
* event was fired. Instead of a Window, a Browser object is required to be
|
||||||
|
* passed to this function.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* See the documentation available for EventUtils#synthesizeKey.
|
||||||
|
* @param {Object} event
|
||||||
|
* See the documentation available for EventUtils#synthesizeKey.
|
||||||
|
* @param {Browser} browser
|
||||||
|
* Browser element, must not be null.
|
||||||
|
*
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
synthesizeKey(key, event, browser) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
let seq = ++gSynthesizeKeyCount;
|
||||||
|
let mm = browser.messageManager;
|
||||||
|
|
||||||
|
mm.addMessageListener("Test:SynthesizeKeyDone", function keyMsg(message) {
|
||||||
|
if (message.data.seq != seq)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mm.removeMessageListener("Test:SynthesizeKeyDone", keyMsg);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
mm.sendAsyncMessage("Test:SynthesizeKey", { key, event, seq });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version of EventUtils' `synthesizeComposition` function; it will synthesize
|
||||||
|
* a composition event in a child process and returns a Promise that will
|
||||||
|
* resolve when the event was fired. Instead of a Window, a Browser object is
|
||||||
|
* required to be passed to this function.
|
||||||
|
*
|
||||||
|
* @param {Object} event
|
||||||
|
* See the documentation available for EventUtils#synthesizeComposition.
|
||||||
|
* @param {Browser} browser
|
||||||
|
* Browser element, must not be null.
|
||||||
|
*
|
||||||
|
* @returns {Promise}
|
||||||
|
* @resolves False if the composition event could not be synthesized.
|
||||||
|
*/
|
||||||
|
synthesizeComposition(event, browser) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
let seq = ++gSynthesizeCompositionCount;
|
||||||
|
let mm = browser.messageManager;
|
||||||
|
|
||||||
|
mm.addMessageListener("Test:SynthesizeCompositionDone", function compMsg(message) {
|
||||||
|
if (message.data.seq != seq)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mm.removeMessageListener("Test:SynthesizeCompositionDone", compMsg);
|
||||||
|
resolve(message.data.result);
|
||||||
|
});
|
||||||
|
|
||||||
|
mm.sendAsyncMessage("Test:SynthesizeComposition", { event, seq });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version of EventUtils' `synthesizeCompositionChange` function; it will
|
||||||
|
* synthesize a compositionchange event in a child process and returns a
|
||||||
|
* Promise that will resolve when the event was fired. Instead of a Window, a
|
||||||
|
* Browser object is required to be passed to this function.
|
||||||
|
*
|
||||||
|
* @param {Object} event
|
||||||
|
* See the documentation available for EventUtils#synthesizeCompositionChange.
|
||||||
|
* @param {Browser} browser
|
||||||
|
* Browser element, must not be null.
|
||||||
|
*
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
synthesizeCompositionChange(event, browser) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
let seq = ++gSynthesizeCompositionChangeCount;
|
||||||
|
let mm = browser.messageManager;
|
||||||
|
|
||||||
|
mm.addMessageListener("Test:SynthesizeCompositionChangeDone", function compMsg(message) {
|
||||||
|
if (message.data.seq != seq)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mm.removeMessageListener("Test:SynthesizeCompositionChangeDone", compMsg);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
mm.sendAsyncMessage("Test:SynthesizeCompositionChange", { event, seq });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will poll a condition function until it returns true.
|
* Will poll a condition function until it returns true.
|
||||||
*
|
*
|
||||||
|
@ -58,8 +58,20 @@ addMessageListener("Test:SynthesizeMouse", (message) => {
|
|||||||
|
|
||||||
addMessageListener("Test:SendChar", message => {
|
addMessageListener("Test:SendChar", message => {
|
||||||
let result = EventUtils.sendChar(message.data.char, content);
|
let result = EventUtils.sendChar(message.data.char, content);
|
||||||
sendAsyncMessage("Test:SendCharDone", {
|
sendAsyncMessage("Test:SendCharDone", { result, seq: message.data.seq });
|
||||||
sendCharResult: result,
|
});
|
||||||
seq: message.data.seq
|
|
||||||
});
|
addMessageListener("Test:SynthesizeKey", message => {
|
||||||
|
EventUtils.synthesizeKey(message.data.key, message.data.event || {}, content);
|
||||||
|
sendAsyncMessage("Test:SynthesizeKeyDone", { seq: message.data.seq });
|
||||||
|
});
|
||||||
|
|
||||||
|
addMessageListener("Test:SynthesizeComposition", message => {
|
||||||
|
let result = EventUtils.synthesizeComposition(message.data.event, content);
|
||||||
|
sendAsyncMessage("Test:SynthesizeCompositionDone", { result, seq: message.data.seq });
|
||||||
|
});
|
||||||
|
|
||||||
|
addMessageListener("Test:SynthesizeCompositionChange", message => {
|
||||||
|
EventUtils.synthesizeCompositionChange(message.data.event, content);
|
||||||
|
sendAsyncMessage("Test:SynthesizeCompositionChangeDone", { seq: message.data.seq });
|
||||||
});
|
});
|
||||||
|
@ -43,6 +43,40 @@ window.__defineGetter__('_EU_Cu', function() {
|
|||||||
return c.value && !c.writable ? Components.utils : SpecialPowers.Cu;
|
return c.value && !c.writable ? Components.utils : SpecialPowers.Cu;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.__defineGetter__("_EU_OS", function() {
|
||||||
|
delete this._EU_OS;
|
||||||
|
try {
|
||||||
|
this._EU_OS = this._EU_Cu.import("resource://gre/modules/AppConstants.jsm", {}).platform;
|
||||||
|
} catch (ex) {
|
||||||
|
this._EU_OS = null;
|
||||||
|
}
|
||||||
|
return this._EU_OS;
|
||||||
|
});
|
||||||
|
|
||||||
|
function _EU_isMac(aWindow = window) {
|
||||||
|
if (window._EU_OS) {
|
||||||
|
return window._EU_OS == "macosx";
|
||||||
|
}
|
||||||
|
if (aWindow) {
|
||||||
|
try {
|
||||||
|
return aWindow.navigator.platform.indexOf("Mac") > -1;
|
||||||
|
} catch (ex) {}
|
||||||
|
}
|
||||||
|
return navigator.platform.indexOf("Mac") > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _EU_isWin(aWindow = window) {
|
||||||
|
if (window._EU_OS) {
|
||||||
|
return window._EU_OS == "win";
|
||||||
|
}
|
||||||
|
if (aWindow) {
|
||||||
|
try {
|
||||||
|
return aWindow.navigator.platform.indexOf("Win") > -1;
|
||||||
|
} catch (ex) {}
|
||||||
|
}
|
||||||
|
return navigator.platform.indexOf("Win") > -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a mouse event to the node aTarget (aTarget can be an id, or an
|
* Send a mouse event to the node aTarget (aTarget can be an id, or an
|
||||||
* actual node) . The "event" passed in to aEvent is just a JavaScript
|
* actual node) . The "event" passed in to aEvent is just a JavaScript
|
||||||
@ -237,7 +271,7 @@ function _parseModifiers(aEvent, aWindow = window)
|
|||||||
mval |= nsIDOMWindowUtils.MODIFIER_META;
|
mval |= nsIDOMWindowUtils.MODIFIER_META;
|
||||||
}
|
}
|
||||||
if (aEvent.accelKey) {
|
if (aEvent.accelKey) {
|
||||||
mval |= (navigator.platform.indexOf("Mac") >= 0) ?
|
mval |= _EU_isMac(aWindow) ?
|
||||||
nsIDOMWindowUtils.MODIFIER_META : nsIDOMWindowUtils.MODIFIER_CONTROL;
|
nsIDOMWindowUtils.MODIFIER_META : nsIDOMWindowUtils.MODIFIER_CONTROL;
|
||||||
}
|
}
|
||||||
if (aEvent.altGrKey) {
|
if (aEvent.altGrKey) {
|
||||||
@ -789,16 +823,13 @@ function _parseNativeModifiers(aModifiers, aWindow = window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (aModifiers.accelKey) {
|
if (aModifiers.accelKey) {
|
||||||
modifiers |=
|
modifiers |= _EU_isMac(aWindow) ? 0x00004000 : 0x00000400;
|
||||||
(navigator.platform.indexOf("Mac") == 0) ? 0x00004000 : 0x00000400;
|
|
||||||
}
|
}
|
||||||
if (aModifiers.accelRightKey) {
|
if (aModifiers.accelRightKey) {
|
||||||
modifiers |=
|
modifiers |= _EU_isMac(aWindow) ? 0x00008000 : 0x00000800;
|
||||||
(navigator.platform.indexOf("Mac") == 0) ? 0x00008000 : 0x00000800;
|
|
||||||
}
|
}
|
||||||
if (aModifiers.altGrKey) {
|
if (aModifiers.altGrKey) {
|
||||||
modifiers |=
|
modifiers |= _EU_isWin(aWindow) ? 0x00002800 : 0x00001000;
|
||||||
(navigator.platform.indexOf("Win") == 0) ? 0x00002800 : 0x00001000;
|
|
||||||
}
|
}
|
||||||
return modifiers;
|
return modifiers;
|
||||||
}
|
}
|
||||||
@ -873,9 +904,9 @@ function synthesizeNativeKey(aKeyboardLayout, aNativeKeyCode, aModifiers,
|
|||||||
}
|
}
|
||||||
var navigator = _getNavigator(aWindow);
|
var navigator = _getNavigator(aWindow);
|
||||||
var nativeKeyboardLayout = null;
|
var nativeKeyboardLayout = null;
|
||||||
if (navigator.platform.indexOf("Mac") == 0) {
|
if (_EU_isMac(aWindow)) {
|
||||||
nativeKeyboardLayout = aKeyboardLayout.Mac;
|
nativeKeyboardLayout = aKeyboardLayout.Mac;
|
||||||
} else if (navigator.platform.indexOf("Win") == 0) {
|
} else if (_EU_isWin(aWindow)) {
|
||||||
nativeKeyboardLayout = aKeyboardLayout.Win;
|
nativeKeyboardLayout = aKeyboardLayout.Win;
|
||||||
}
|
}
|
||||||
if (nativeKeyboardLayout === null) {
|
if (nativeKeyboardLayout === null) {
|
||||||
@ -1063,7 +1094,15 @@ function _getTIP(aWindow, aCallback)
|
|||||||
function _getKeyboardEvent(aWindow = window)
|
function _getKeyboardEvent(aWindow = window)
|
||||||
{
|
{
|
||||||
if (typeof KeyboardEvent != "undefined") {
|
if (typeof KeyboardEvent != "undefined") {
|
||||||
return KeyboardEvent;
|
try {
|
||||||
|
// See if the object can be instantiated; sometimes this yields
|
||||||
|
// 'TypeError: can't access dead object' or 'KeyboardEvent is not a constructor'.
|
||||||
|
new KeyboardEvent("", {});
|
||||||
|
return KeyboardEvent;
|
||||||
|
} catch (ex) {}
|
||||||
|
}
|
||||||
|
if (typeof content != "undefined" && ("KeyboardEvent" in content)) {
|
||||||
|
return content.KeyboardEvent;
|
||||||
}
|
}
|
||||||
return aWindow.KeyboardEvent;
|
return aWindow.KeyboardEvent;
|
||||||
}
|
}
|
||||||
@ -1282,7 +1321,7 @@ function _emulateToActivateModifiers(aTIP, aKeyEvent, aWindow = window)
|
|||||||
{ key: "OS", attr: "osKey" },
|
{ key: "OS", attr: "osKey" },
|
||||||
{ key: "Shift", attr: "shiftKey" },
|
{ key: "Shift", attr: "shiftKey" },
|
||||||
{ key: "Symbol", attr: "symbolKey" },
|
{ key: "Symbol", attr: "symbolKey" },
|
||||||
{ key: (navigator.platform.indexOf("Mac") >= 0) ? "Meta" : "Control",
|
{ key: _EU_isMac(aWindow) ? "Meta" : "Control",
|
||||||
attr: "accelKey" },
|
attr: "accelKey" },
|
||||||
],
|
],
|
||||||
lockable: [
|
lockable: [
|
||||||
|
Loading…
Reference in New Issue
Block a user