Bug 347185 Adding automated tests r=roc

This commit is contained in:
Masayuki Nakano 2011-04-21 08:54:43 +09:00
Родитель 7b44ff8cc2
Коммит 1f33181162
10 изменённых файлов: 144 добавлений и 8 удалений

Просмотреть файл

@ -446,8 +446,10 @@ public:
PRBool SendNativeEvents() PRBool SendNativeEvents()
{ {
#ifdef XP_WIN #ifdef XP_WIN
// XXX we should remove the plugin name check
return mPluginWindow->type == NPWindowTypeDrawable && return mPluginWindow->type == NPWindowTypeDrawable &&
MatchPluginName("Shockwave Flash"); (MatchPluginName("Shockwave Flash") ||
MatchPluginName("Test Plug-in"));
#elif defined(MOZ_X11) || defined(XP_MACOSX) #elif defined(MOZ_X11) || defined(XP_MACOSX)
return PR_TRUE; return PR_TRUE;
#else #else

Просмотреть файл

@ -225,6 +225,13 @@ getClipRegionRectCount(), this will throw an error. The coordinates are
the same as for getEdge. See getClipRegionRectCount() above for the same as for getEdge. See getClipRegionRectCount() above for
notes on platform plugin limitations. notes on platform plugin limitations.
== Keyboard events ==
* getLastKeyText()
Returns the text which was inputted by last keyboard events. This is cleared at
every keydown event.
NOTE: Currently, this is implemented only on Windows.
== Mouse events == == Mouse events ==
The test plugin supports the following scriptable methods: The test plugin supports the following scriptable methods:

Просмотреть файл

@ -165,6 +165,7 @@ static bool getWindowPosition(NPObject* npobj, const NPVariant* args, uint32_t a
static bool constructObject(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool constructObject(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool setSitesWithData(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool setSitesWithData(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool setSitesWithDataCapabilities(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool setSitesWithDataCapabilities(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getLastKeyText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static const NPUTF8* sPluginMethodIdentifierNames[] = { static const NPUTF8* sPluginMethodIdentifierNames[] = {
"npnEvaluateTest", "npnEvaluateTest",
@ -221,7 +222,8 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
"getWindowPosition", "getWindowPosition",
"constructObject", "constructObject",
"setSitesWithData", "setSitesWithData",
"setSitesWithDataCapabilities" "setSitesWithDataCapabilities",
"getLastKeyText"
}; };
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)]; static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
static const ScriptableFunction sPluginMethodFunctions[] = { static const ScriptableFunction sPluginMethodFunctions[] = {
@ -279,7 +281,8 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
getWindowPosition, getWindowPosition,
constructObject, constructObject,
setSitesWithData, setSitesWithData,
setSitesWithDataCapabilities setSitesWithDataCapabilities,
getLastKeyText
}; };
STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) == STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) ==
@ -3436,3 +3439,15 @@ bool setSitesWithDataCapabilities(NPObject* npobj, const NPVariant* args, uint32
return true; return true;
} }
bool getLastKeyText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
NPVariant* result)
{
if (argCount != 0) {
return false;
}
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
STRINGZ_TO_NPVARIANT(NPN_StrDup(id->lastKeyText.c_str()), *result);
return true;
}

Просмотреть файл

@ -138,6 +138,7 @@ typedef struct InstanceData {
int32_t focusEventCount; int32_t focusEventCount;
int32_t eventModel; int32_t eventModel;
bool closeStream; bool closeStream;
std::string lastKeyText;
} InstanceData; } InstanceData;
void notifyDidPaint(InstanceData* instanceData); void notifyDidPaint(InstanceData* instanceData);

Просмотреть файл

@ -458,6 +458,27 @@ handleEventInternal(InstanceData* instanceData, NPEvent* pe, LRESULT* result)
return true; return true;
} }
case WM_KEYDOWN:
instanceData->lastKeyText.erase();
*result = 0;
return true;
case WM_CHAR: {
*result = 0;
wchar_t uniChar = static_cast<wchar_t>(pe->wParam);
if (!uniChar) {
return true;
}
char utf8Char[6];
int len =
::WideCharToMultiByte(CP_UTF8, 0, &uniChar, 1, utf8Char, 6, NULL, NULL);
if (len == 0 || len > 6) {
return true;
}
instanceData->lastKeyText.append(utf8Char, len);
return true;
}
default: default:
return false; return false;
} }

Просмотреть файл

@ -3993,10 +3993,17 @@ PRBool nsWindow::DispatchPluginEvent(UINT aMessage,
} }
void nsWindow::RemoveMessageAndDispatchPluginEvent(UINT aFirstMsg, void nsWindow::RemoveMessageAndDispatchPluginEvent(UINT aFirstMsg,
UINT aLastMsg) UINT aLastMsg, nsFakeCharMessage* aFakeCharMessage)
{ {
MSG msg; MSG msg;
if (aFakeCharMessage) {
if (aFirstMsg > WM_CHAR || aLastMsg < WM_CHAR) {
return;
}
msg = aFakeCharMessage->GetCharMessage(mWnd);
} else {
::GetMessageW(&msg, mWnd, aFirstMsg, aLastMsg); ::GetMessageW(&msg, mWnd, aFirstMsg, aLastMsg);
}
DispatchPluginEvent(msg); DispatchPluginEvent(msg);
} }
@ -6986,6 +6993,8 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
PRBool anyCharMessagesRemoved = PR_FALSE; PRBool anyCharMessagesRemoved = PR_FALSE;
if (aFakeCharMessage) { if (aFakeCharMessage) {
RemoveMessageAndDispatchPluginEvent(WM_KEYFIRST, WM_KEYLAST,
aFakeCharMessage);
anyCharMessagesRemoved = PR_TRUE; anyCharMessagesRemoved = PR_TRUE;
} else { } else {
while (gotMsg && (msg.message == WM_CHAR || msg.message == WM_SYSCHAR)) while (gotMsg && (msg.message == WM_CHAR || msg.message == WM_SYSCHAR))
@ -7010,9 +7019,12 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
else if (gotMsg && else if (gotMsg &&
(aFakeCharMessage || (aFakeCharMessage ||
msg.message == WM_CHAR || msg.message == WM_SYSCHAR || msg.message == WM_DEADCHAR)) { msg.message == WM_CHAR || msg.message == WM_SYSCHAR || msg.message == WM_DEADCHAR)) {
if (aFakeCharMessage) if (aFakeCharMessage) {
MSG msg = aFakeCharMessage->GetCharMessage(mWnd);
return OnCharRaw(aFakeCharMessage->mCharCode, return OnCharRaw(aFakeCharMessage->mCharCode,
aFakeCharMessage->mScanCode, aModKeyState, extraFlags); aFakeCharMessage->mScanCode,
aModKeyState, extraFlags, &msg);
}
// If prevent default set for keydown, do same for keypress // If prevent default set for keydown, do same for keypress
::GetMessageW(&msg, mWnd, msg.message, msg.message); ::GetMessageW(&msg, mWnd, msg.message, msg.message);

Просмотреть файл

@ -355,7 +355,9 @@ protected:
PRBool DispatchCommandEvent(PRUint32 aEventCommand); PRBool DispatchCommandEvent(PRUint32 aEventCommand);
void RelayMouseEvent(UINT aMsg, WPARAM wParam, LPARAM lParam); void RelayMouseEvent(UINT aMsg, WPARAM wParam, LPARAM lParam);
static void RemoveNextCharMessage(HWND aWnd); static void RemoveNextCharMessage(HWND aWnd);
void RemoveMessageAndDispatchPluginEvent(UINT aFirstMsg, UINT aLastMsg); void RemoveMessageAndDispatchPluginEvent(UINT aFirstMsg,
UINT aLastMsg,
nsFakeCharMessage* aFakeCharMessage = nsnull);
static MSG InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam); static MSG InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam);
virtual PRBool ProcessMessage(UINT msg, WPARAM &wParam, virtual PRBool ProcessMessage(UINT msg, WPARAM &wParam,
LPARAM &lParam, LRESULT *aRetValue); LPARAM &lParam, LRESULT *aRetValue);

Просмотреть файл

@ -244,6 +244,18 @@ struct nsAlternativeCharCode; // defined in nsGUIEvent.h
struct nsFakeCharMessage { struct nsFakeCharMessage {
UINT mCharCode; UINT mCharCode;
UINT mScanCode; UINT mScanCode;
MSG GetCharMessage(HWND aWnd)
{
MSG msg;
msg.hwnd = aWnd;
msg.message = WM_CHAR;
msg.wParam = static_cast<WPARAM>(mCharCode);
msg.lParam = static_cast<LPARAM>(mScanCode);
msg.time = 0;
msg.pt.x = msg.pt.y = 0;
return msg;
}
}; };
// Used in char processing // Used in char processing

Просмотреть файл

@ -113,6 +113,7 @@ _CHROME_FILES += taskbar_previews.xul \
window_state_windows.xul \ window_state_windows.xul \
taskbar_progress.xul \ taskbar_progress.xul \
test_chrome_context_menus_win.xul \ test_chrome_context_menus_win.xul \
test_plugin_input_event.html \
chrome_context_menus_win.xul \ chrome_context_menus_win.xul \
$(NULL) $(NULL)

Просмотреть файл

@ -0,0 +1,63 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for plugin input event</title>
<script type="text/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="text/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display">
<embed id="plugin" type="application/x-test" wmode="opaque">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
var gPlugin = document.getElementById("plugin");
var gUtils = window.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
function doTest() {
gPlugin.focus();
is(gUtils.IMEStatus, gUtils.IME_STATUS_PLUGIN,
"Plugin failed to get focus");
is(gPlugin.getLastKeyText(), "", "Must be empty before first key test");
gUtils.sendNativeKeyEvent(0x409 /* US */,
0x41, 0,
"a", "a");
is(gPlugin.getLastKeyText(), "a", "Invalid character was inputted");
gUtils.sendNativeKeyEvent(0x407 /* German */,
0xBB, 0,
"+", "+");
is(gPlugin.getLastKeyText(), "+", "Invalid character was inputted");
gUtils.sendNativeKeyEvent(0x407 /* German */,
0xBB, 0x1400 /* Ctrl + Alt (AltGr) */,
"~", "+");
is(gPlugin.getLastKeyText(), "~", "Invalid character was inputted");
SimpleTest.finish();
}
SimpleTest.waitForFocus(doTest);
</script>
</body>
</html>