summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/data/npapi/execute_script_delete_in_mouse_move.html39
-rw-r--r--chrome/test/ui/npapi_uitest.cpp38
-rw-r--r--webkit/glue/plugins/test/plugin_client.cc7
-rw-r--r--webkit/glue/plugins/test/plugin_execute_script_delete_test.cc52
-rw-r--r--webkit/glue/plugins/test/plugin_execute_script_delete_test.h6
-rw-r--r--webkit/glue/webplugin_impl.cc10
6 files changed, 131 insertions, 21 deletions
diff --git a/chrome/test/data/npapi/execute_script_delete_in_mouse_move.html b/chrome/test/data/npapi/execute_script_delete_in_mouse_move.html
new file mode 100644
index 0000000..a82cde7
--- /dev/null
+++ b/chrome/test/data/npapi/execute_script_delete_in_mouse_move.html
@@ -0,0 +1,39 @@
+<html>
+
+<head>
+<script src="npapi.js"></script>
+
+<script>
+function DeletePluginWithinScript() {
+ var plugin_div = document.getElementById("PluginDiv");
+ plugin_div.innerHTML = "Object Deleted";
+ onSuccess("execute_script_delete_in_mouse_move", 1);
+}
+</script>
+</head>
+
+<body>
+<div id="statusPanel" style="border: 1px solid red; width: 100%">
+Test running....
+</div>
+
+
+NPObject Proxy Test<p>
+
+Tests the case where a plugin instance is deleted in the context
+of a synchronous mouse event.
+
+<DIV ID=PluginDiv>
+<embed type="application/vnd.npapi-test"
+ src="foo"
+ name="execute_script_delete_in_mouse_move"
+ id="1"
+ mode="np_embed"
+>
+</DIV>
+<script>
+ var height = document.body.offsetHeight;
+</script>
+
+</body>
+</html>
diff --git a/chrome/test/ui/npapi_uitest.cpp b/chrome/test/ui/npapi_uitest.cpp
index bce1497..58c6574 100644
--- a/chrome/test/ui/npapi_uitest.cpp
+++ b/chrome/test/ui/npapi_uitest.cpp
@@ -279,4 +279,40 @@ TEST_F(NPAPIVisiblePluginTester, OpenPopupWindowWithPlugin) {
WaitForFinish("plugin_popup_with_plugin_target", "1", url,
kTestCompleteCookie, kTestCompleteSuccess,
kShortWaitTimeout);
-} \ No newline at end of file
+}
+
+// Tests if a plugin executing a self deleting script in the context of
+// a synchronous mousemove works correctly
+TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInvokeInSynchronousMouseMove) {
+ if (!UITest::in_process_plugins() && !UITest::in_process_renderer()) {
+ scoped_ptr<TabProxy> tab_proxy(GetActiveTab());
+ HWND tab_window = NULL;
+ tab_proxy->GetHWND(&tab_window);
+
+ EXPECT_TRUE(IsWindow(tab_window));
+
+ show_window_ = true;
+ std::wstring test_case = L"execute_script_delete_in_mouse_move.html";
+ GURL url = GetTestUrl(L"npapi", test_case);
+ NavigateToURL(url);
+
+ POINT cursor_position = {130, 130};
+ ClientToScreen(tab_window, &cursor_position);
+
+ double screen_width = ::GetSystemMetrics( SM_CXSCREEN ) - 1;
+ double screen_height = ::GetSystemMetrics( SM_CYSCREEN ) - 1;
+ double location_x = cursor_position.x * (65535.0f / screen_width);
+ double location_y = cursor_position.y * (65535.0f / screen_height);
+
+ INPUT input_info = {0};
+ input_info.type = INPUT_MOUSE;
+ input_info.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
+ input_info.mi.dx = static_cast<long>(location_x);
+ input_info.mi.dy = static_cast<long>(location_y);
+ ::SendInput(1, &input_info, sizeof(INPUT));
+
+ WaitForFinish("execute_script_delete_in_mouse_move", "1", url,
+ kTestCompleteCookie, kTestCompleteSuccess,
+ kShortWaitTimeout);
+ }
+}
diff --git a/webkit/glue/plugins/test/plugin_client.cc b/webkit/glue/plugins/test/plugin_client.cc
index 868810e..b0e7e91 100644
--- a/webkit/glue/plugins/test/plugin_client.cc
+++ b/webkit/glue/plugins/test/plugin_client.cc
@@ -102,7 +102,7 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode,
} else if (base::strcasecmp(argv[name_index],
"execute_script_delete_in_paint") == 0) {
new_test = new NPAPIClient::ExecuteScriptDeleteTest(instance,
- NPAPIClient::PluginClient::HostFunctions());
+ NPAPIClient::PluginClient::HostFunctions(), argv[name_index]);
windowless_plugin = true;
} else if (base::strcasecmp(argv[name_index], "getjavascripturl") == 0) {
new_test = new NPAPIClient::ExecuteGetJavascriptUrlTest(instance,
@@ -137,6 +137,11 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode,
"plugin_popup_with_plugin_target") == 0) {
new_test = new NPAPIClient::ExecuteJavascriptPopupWindowTargetPluginTest(
instance, NPAPIClient::PluginClient::HostFunctions());
+ } else if (base::strcasecmp(argv[name_index],
+ "execute_script_delete_in_mouse_move") == 0) {
+ new_test = new NPAPIClient::ExecuteScriptDeleteTest(instance,
+ NPAPIClient::PluginClient::HostFunctions(), argv[name_index]);
+ windowless_plugin = true;
} else {
// If we don't have a test case for this, create a
// generic one which basically never fails.
diff --git a/webkit/glue/plugins/test/plugin_execute_script_delete_test.cc b/webkit/glue/plugins/test/plugin_execute_script_delete_test.cc
index 7137ceb..3f1d0e1 100644
--- a/webkit/glue/plugins/test/plugin_execute_script_delete_test.cc
+++ b/webkit/glue/plugins/test/plugin_execute_script_delete_test.cc
@@ -8,25 +8,47 @@
namespace NPAPIClient {
-ExecuteScriptDeleteTest::ExecuteScriptDeleteTest(NPP id, NPNetscapeFuncs *host_functions)
- : PluginTest(id, host_functions) {
+ExecuteScriptDeleteTest::ExecuteScriptDeleteTest(
+ NPP id, NPNetscapeFuncs *host_functions, const std::string& test_name)
+ : PluginTest(id, host_functions),
+ test_name_(test_name) {
}
int16 ExecuteScriptDeleteTest::HandleEvent(void* event) {
+
+ NPNetscapeFuncs* browser = NPAPIClient::PluginClient::HostFunctions();
+
+ NPBool supports_windowless = 0;
+ NPError result = browser->getvalue(id(), NPNVSupportsWindowless,
+ &supports_windowless);
+ if ((result != NPERR_NO_ERROR) || (supports_windowless != TRUE)) {
+ SetError("Failed to read NPNVSupportsWindowless value");
+ SignalTestCompleted();
+ return PluginTest::HandleEvent(event);
+ }
+
NPEvent* np_event = reinterpret_cast<NPEvent*>(event);
- if (WM_PAINT == np_event->event ) {
- NPNetscapeFuncs* browser = NPAPIClient::PluginClient::HostFunctions();
-
- NPBool supports_windowless = 0;
- NPError result = browser->getvalue(id(), NPNVSupportsWindowless,
- &supports_windowless);
- if ((result != NPERR_NO_ERROR) || (supports_windowless != TRUE)) {
- SetError("Failed to read NPNVSupportsWindowless value");
- } else {
- NPUTF8* urlString = "javascript:DeletePluginWithinScript()";
- NPUTF8* targetString = NULL;
- browser->geturl(id(), urlString, targetString);
- }
+ if (WM_PAINT == np_event->event &&
+ base::strcasecmp(test_name_.c_str(),
+ "execute_script_delete_in_paint") == 0) {
+ NPUTF8* urlString = "javascript:DeletePluginWithinScript()";
+ NPUTF8* targetString = NULL;
+ browser->geturl(id(), urlString, targetString);
+ SignalTestCompleted();
+ } else if (WM_MOUSEMOVE == np_event->event &&
+ base::strcasecmp(test_name_.c_str(),
+ "execute_script_delete_in_mouse_move") == 0) {
+ std::string script = "javascript:DeletePluginWithinScript()";
+ NPString script_string;
+ script_string.UTF8Characters = script.c_str();
+ script_string.UTF8Length =
+ static_cast<unsigned int>(script.length());
+
+ NPObject *window_obj = NULL;
+ browser->getvalue(id(), NPNVWindowNPObject, &window_obj);
+ NPVariant result_var;
+ NPError result = browser->evaluate(id(), window_obj,
+ &script_string, &result_var);
SignalTestCompleted();
}
// If this test failed, then we'd have crashed by now.
diff --git a/webkit/glue/plugins/test/plugin_execute_script_delete_test.h b/webkit/glue/plugins/test/plugin_execute_script_delete_test.h
index 5266d6d..92a1d04 100644
--- a/webkit/glue/plugins/test/plugin_execute_script_delete_test.h
+++ b/webkit/glue/plugins/test/plugin_execute_script_delete_test.h
@@ -14,9 +14,13 @@ namespace NPAPIClient {
class ExecuteScriptDeleteTest : public PluginTest {
public:
// Constructor.
- ExecuteScriptDeleteTest(NPP id, NPNetscapeFuncs *host_functions);
+ ExecuteScriptDeleteTest(NPP id, NPNetscapeFuncs *host_functions,
+ const std::string& test_name);
// NPAPI HandleEvent handler
virtual int16 HandleEvent(void* event);
+
+ private:
+ std::string test_name_;
};
} // namespace NPAPIClient
diff --git a/webkit/glue/webplugin_impl.cc b/webkit/glue/webplugin_impl.cc
index 496de7f..36d7fc6 100644
--- a/webkit/glue/webplugin_impl.cc
+++ b/webkit/glue/webplugin_impl.cc
@@ -786,9 +786,13 @@ void WebPluginImpl::handleEvent(WebCore::Event* event) {
void WebPluginImpl::handleMouseEvent(WebCore::MouseEvent* event) {
#if defined(OS_WIN)
DCHECK(parent()->isFrameView());
+ // We cache the parent FrameView here as the plugin widget could be deleted
+ // in the call to HandleEvent. See http://b/issue?id=1362948
+ WebCore::FrameView* parent_view = static_cast<WebCore::FrameView*>(parent());
+
WebCore::IntPoint p =
- static_cast<WebCore::FrameView*>(parent())->contentsToWindow(
- WebCore::IntPoint(event->pageX(), event->pageY()));
+ parent_view->contentsToWindow(WebCore::IntPoint(event->pageX(),
+ event->pageY()));
NPEvent np_event;
np_event.lParam = static_cast<uint32>(MAKELPARAM(p.x(), p.y()));
np_event.wParam = 0;
@@ -867,7 +871,7 @@ void WebPluginImpl::handleMouseEvent(WebCore::MouseEvent* event) {
// A windowless plugin can change the cursor in response to the WM_MOUSEMOVE
// event. We need to reflect the changed cursor in the frame view as the
// the mouse is moved in the boundaries of the windowless plugin.
- parent()->setCursor(WebCore::PlatformCursor(current_web_cursor));
+ parent_view->setCursor(WebCore::PlatformCursor(current_web_cursor));
#else
NOTIMPLEMENTED();
#endif