Bug 544945: Mochitest of clipboard interaction that forces the plugin subprocess into a nested event loop on gtk2 platforms. r=karlt
authorChris Jones <jones.chris.g@gmail.com>
Tue, 16 Feb 2010 12:44:26 -0600
changeset 38686 a31c15677467d51b04a527757bdcdaa2cdcc60c9
parent 38685 d553de3fad407432815d87555ec5b854454b3657
child 38687 122641d81c499523d03f147a40f8d4f5fa32a61f
push idunknown
push userunknown
push dateunknown
reviewerskarlt
bugs544945
milestone1.9.3a2pre
Bug 544945: Mochitest of clipboard interaction that forces the plugin subprocess into a nested event loop on gtk2 platforms. r=karlt
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/mochitest/test_copyText.html
modules/plugin/test/testplugin/nptest.cpp
modules/plugin/test/testplugin/nptest_gtk2.cpp
modules/plugin/test/testplugin/nptest_platform.h
--- a/modules/plugin/test/mochitest/Makefile.in
+++ b/modules/plugin/test/mochitest/Makefile.in
@@ -100,16 +100,22 @@ endif
   $(NULL)
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _MOCHICHROME_FILES += \
   test_convertpoint.xul \
   $(NULL)
 endif
 
+ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
+_MOCHITEST_FILES += \
+		test_copyText.html \
+		$(NULL)
+endif
+
 ifdef MOZ_IPC
 _MOCHICHROME_FILES += \
   test_crash_notify.xul \
   test_crash_notify_no_report.xul \
   $(NULL)
 endif
 
 libs:: $(_MOCHICHROME_FILES)
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/mochitest/test_copyText.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test copying text from browser to plugin</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script class="testbody" type="text/javascript">
+function runTests() {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+  var text = " some text \n to copy 'n paste "
+  var textElt = document.getElementById("input");
+  var plugin = document.getElementById("plugin1");
+
+  textElt.focus();
+  textElt.value = text;
+  textElt.select();
+  textElt.QueryInterface(Components.interfaces.nsIDOMNSEditableElement)
+      .editor.copy();
+
+  is(plugin.getClipboardText(), text);
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+  </script>
+</head>
+
+<body onload="runTests()">
+  <embed id="plugin1" type="application/x-test" width="400" height="400"></embed>
+  <textarea id="input"></textarea>
+
+</body>
+</html>
--- a/modules/plugin/test/testplugin/nptest.cpp
+++ b/modules/plugin/test/testplugin/nptest.cpp
@@ -149,16 +149,17 @@ static bool getObjectValue(NPObject* npo
 static bool checkObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool enableFPExceptions(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool setCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
+static bool getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 
 static const NPUTF8* sPluginMethodIdentifierNames[] = {
   "npnEvaluateTest",
   "npnInvokeTest",
   "npnInvokeDefaultTest",
   "setUndefinedValueTest",
   "identifierToStringTest",
   "timerTest",
@@ -188,16 +189,17 @@ static const NPUTF8* sPluginMethodIdenti
   "checkObjectValue",
   "enableFPExceptions",
   "setCookie",
   "getCookie",
   "getAuthInfo",
   "asyncCallbackTest",
   "checkGCRace",
   "hang",
+  "getClipboardText",
 };
 static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
 static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMethodIdentifierNames)] = {
   npnEvaluateTest,
   npnInvokeTest,
   npnInvokeDefaultTest,
   setUndefinedValueTest,
   identifierToStringTest,
@@ -228,16 +230,17 @@ static const ScriptableFunction sPluginM
   checkObjectValue,
   enableFPExceptions,
   setCookie,
   getCookie,
   getAuthInfo,
   asyncCallbackTest,
   checkGCRace,
   hangPlugin,
+  getClipboardText,
 };
 
 struct URLNotifyData
 {
   const char* cookie;
   NPObject* callback;
   uint32_t size;
   char* data;
@@ -2577,8 +2580,41 @@ hangPlugin(NPObject* npobj, const NPVari
   pause();
 #endif
   // NB: returning true here means that we weren't terminated, and
   // thus the hang detection/handling didn't work correctly.  The
   // test harness will succeed in calling this function, and the
   // test will fail.
   return true;
 }
+
+#if defined(MOZ_WIDGET_GTK2)
+bool
+getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
+                 NPVariant* result)
+{
+  NPP npp = static_cast<TestNPObject*>(npobj)->npp;
+  InstanceData* id = static_cast<InstanceData*>(npp->pdata);
+  string sel = pluginGetClipboardText(id);
+
+  uint32 len = sel.size();
+  char* selCopy = static_cast<char*>(NPN_MemAlloc(1 + len));
+  if (!selCopy)
+    return false;
+
+  memcpy(selCopy, sel.c_str(), len);
+  selCopy[len] = '\0';
+
+  STRINGN_TO_NPVARIANT(selCopy, len, *result);
+  // *result owns str now
+
+  return true;
+}
+
+#else
+#  warning "Implement pluginGetClipboardText for this platform"
+bool
+getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
+                 NPVariant* result)
+{
+  return false;
+}
+#endif
--- a/modules/plugin/test/testplugin/nptest_gtk2.cpp
+++ b/modules/plugin/test/testplugin/nptest_gtk2.cpp
@@ -616,8 +616,22 @@ int32_t pluginGetClipRegionRectEdge(Inst
     return rect.y + rect.height;
   }
   return NPTEST_INT32_ERROR;
 }
 
 void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error)
 {
 }
+
+string
+pluginGetClipboardText(InstanceData* instanceData)
+{
+  GtkClipboard* cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+  // XXX this is a BAD WAY to interact with GtkClipboard.  We use this
+  // deprecated interface only to test nested event loop handling.
+  gchar* text = gtk_clipboard_wait_for_text(cb);
+  string retText = text ? text : "";
+
+  g_free(text);
+
+  return retText;
+}
--- a/modules/plugin/test/testplugin/nptest_platform.h
+++ b/modules/plugin/test/testplugin/nptest_platform.h
@@ -115,9 +115,15 @@ int32_t pluginGetClipRegionRectEdge(Inst
 
 /**
  * Check that the platform-specific plugin state is internally consistent.
  * Just return if everything is OK, otherwise append error messages
  * to 'error' separated by \n.
  */
 void pluginDoInternalConsistencyCheck(InstanceData* instanceData, std::string& error);
 
+/**
+ * Get the current clipboard item as text.  If the clipboard item
+ * isn't text, the returned value is undefined.
+ */
+std::string pluginGetClipboardText(InstanceData* instanceData);
+
 #endif // nptest_platform_h_