Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Ufimtsev2016-08-04 19:13:18 +0000
committerLeo Ufimtsev2016-09-19 14:51:39 +0000
commit688c0e346bc63c155a78983d3bf38fb76a8c5b6c (patch)
treea039ab5fed1e6f88c606073894af7cf2ee6a45e8
parent002373ea04e53bd20e0f1f34ceea2733b256c5be (diff)
downloadeclipse.platform.swt-688c0e346bc63c155a78983d3bf38fb76a8c5b6c.tar.gz
eclipse.platform.swt-688c0e346bc63c155a78983d3bf38fb76a8c5b6c.tar.xz
eclipse.platform.swt-688c0e346bc63c155a78983d3bf38fb76a8c5b6c.zip
Bug 430538: [GTK3][webkit] Support Custom JavaScript execution in
WebKit2 mode of SWT Browser Re-Applying patch that was reverted because build servers were not updated: https://git.eclipse.org/r/#/c/80902/ -------------------------- Stage 1 Patch Set 1: 2016-08Aug-04Thu (pushed2Gerrit) Implement return mechanism for webkit_*_run_javascript() - Adding a webkitgtk_custom.c file for custom function - modified linux_makefil for additional file - cleanup of linux_makefile for webkit, (confusing target naming). Patch Set 2: 2016-08Aug-08Mon (pushed2Gerrit) - Implemented call to webkit - Implemented spinlock and while loop to wait for callback to finish. Spinlock is passed as pointer to callback. Patch Set 3: (pushed2Gerrit) - 2016-08Aug-08Mon - minor tweaks. - 2016-08Aug-09Tue - renamed custom method/function name. - 2016-08Aug-10Wed - fixed potential memory leak. - 2016-08Aug-15Mon - Implemented conditional compilation for build servers without webkit2gtk4 Patch Set 4: 2016-08Aug-30Tue - Rewrite to call webkit functions dynamically instead of hard-linking - removed pkg-config dependencies to webkitgtk - Changed pkg-config webkit flags to use gio instead of glib. Note, glib is a subset of gio, and gio is a subset of Gtk2/Gtk3, thus this should not break anything. Patchset 14: - Adjusted comment in webkitgtk_custom.c > Warning to future developers as it's not obvious. I did not know until you pointed it out. - Removed 'ifndef' from function swt_webkit_web_view_run_javascript call. In hindsight, it doesn't look like it's necessary. Things I've tested: - Child Eclipse with webkit2 browser - Browser tests: (fixes tests 3,4, 8). - Various browser snippets. To test yourself: - To enable webkit2, set: SWT_WEBKIT2=1 - Manual inspection via SWT-SNIPPET: https://github.com/ericwill/SWT-snippets/blob/master/src/browser/Bug430538_JS_Set_Background.java If you click the 'execute' button, now background is set. (Note, other button 'evalute' not working yet). - Browser8.java now passes and correctly executes JS (enable verbose on line 30 to see before/after, now background changes). - Browser3.java now passes Change-Id: I1202064798ef7839af1d29aff41391d411276005 Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=430538 Signed-off-by: Lev Ufimtsev <lufimtse@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak25
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c16
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.c133
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.h24
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java11
9 files changed, 210 insertions, 15 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak
index 9d3aa874e7..40ee285d22 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak
@@ -100,7 +100,9 @@ MOZILLAEXCLUDES = -DNO__1XPCOMGlueShutdown \
-DNO_nsDynamicFunctionLoad
XULRUNNEREXCLUDES = -DNO__1NS_1InitXPCOM2
-WEBKITCFLAGS = `pkg-config --cflags glib-2.0`
+
+WEBKITLIBS = `pkg-config --libs-only-l gio-2.0` # Avoid adding 'webkit2gtk-4.0', as some systems might not have it.
+WEBKITCFLAGS = `pkg-config --cflags gio-2.0` # webkit functions should be called dynamically. See Bug 430538
SWT_OBJECTS = swt.o c.o c_stats.o callback.o
CDE_OBJECTS = swt.o cde.o cde_structs.o cde_stats.o
@@ -112,7 +114,7 @@ GNOME_OBJECTS = swt.o gnome.o gnome_structs.o gnome_stats.o
MOZILLA_OBJECTS = swt.o xpcom.o xpcom_custom.o xpcom_structs.o xpcom_stats.o
XULRUNNER_OBJECTS = swt.o xpcomxul.o xpcomxul_custom.o xpcomxul_structs.o xpcomxul_stats.o
XPCOMINIT_OBJECTS = swt.o xpcominit.o xpcominit_structs.o xpcominit_stats.o
-WEBKIT_OBJECTS = swt.o webkit.o webkit_structs.o webkit_stats.o
+WEBKIT_OBJECTS = swt.o webkitgtk.o webkitgtk_structs.o webkitgtk_stats.o webkitgtk_custom.o
GLX_OBJECTS = swt.o glx.o glx_structs.o glx_stats.o
CFLAGS = -O -Wall \
@@ -294,16 +296,19 @@ xpcominit_stats.o: xpcominit_stats.cpp
make_webkit: $(WEBKIT_LIB)
$(WEBKIT_LIB): $(WEBKIT_OBJECTS)
- $(CC) $(LFLAGS) -o $(WEBKIT_LIB) $(WEBKIT_OBJECTS)
+ $(CC) $(LFLAGS) -o $(WEBKIT_LIB) $(WEBKIT_OBJECTS) $(WEBKITLIBS)
-webkit.o: webkitgtk.c
- $(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk.c -o webkit.o
+webkitgtk.o: webkitgtk.c webkitgtk_custom.h
+ $(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk.c
-webkit_structs.o: webkitgtk_structs.c
- $(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_structs.c -o webkit_structs.o
-
-webkit_stats.o: webkitgtk_stats.c webkitgtk_stats.h
- $(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_stats.c -o webkit_stats.o
+webkitgtk_structs.o: webkitgtk_structs.c
+ $(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_structs.c
+
+webkitgtk_stats.o: webkitgtk_stats.c webkitgtk_stats.h
+ $(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_stats.c
+
+webkitgtk_custom.o: webkitgtk_custom.c
+ $(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_custom.c
#
# GLX lib
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
index 87ead7f286..3947b5bfe3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
@@ -1041,6 +1041,22 @@ JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1soup_1uri_1to_1string)
}
#endif
+#ifndef NO__1swt_1webkit_1web_1view_1run_1javascript
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(_1swt_1webkit_1web_1view_1run_1javascript)
+ (JNIEnv *env, jclass that, jintLong arg0, jbyteArray arg1)
+{
+ jbyte *lparg1=NULL;
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, _1swt_1webkit_1web_1view_1run_1javascript_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+ rc = (jlong)swt_webkit_web_view_run_javascript(arg0, lparg1);
+fail:
+ if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+ WebKitGTK_NATIVE_EXIT(env, that, _1swt_1webkit_1web_1view_1run_1javascript_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1webkit_1authentication_1request_1authenticate
JNIEXPORT void JNICALL WebKitGTK_NATIVE(_1webkit_1authentication_1request_1authenticate)
(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h
index 8621fef9c3..00219cf811 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.h
@@ -12,7 +12,9 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-
+
+/* Manually written code */
+
#ifndef INC_webkitgtk_H
#define INC_webkitgtk_H
@@ -21,6 +23,9 @@
#include <stdlib.h>
#include <glib-object.h>
+// For JNI bindings in webkitgtk.c to properly link to custom functions:
+#include "webkitgtk_custom.h"
+
#define WebKitGTK_LOAD_FUNCTION(var, name) \
static int initialized = 0; \
static void *var = NULL; \
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.c
new file mode 100644
index 0000000000..3b2f887377
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.c
@@ -0,0 +1,133 @@
+/*******************************************************************************
+* Copyright (c) 2016 Red Hat, Inc. All rights reserved.
+* The contents of this file are made available under the terms
+* of the GNU Lesser General Public License (LGPL) Version 2.1 that
+* accompanies this distribution (lgpl-v21.txt). The LGPL is also
+* available at http://www.gnu.org/licenses/lgpl.html. If the version
+* of the LGPL at http://www.gnu.org is different to the version of
+* the LGPL accompanying this distribution and there is any conflict
+* between the two license versions, the terms of the LGPL accompanying
+* this distribution shall govern.
+*
+* Contributors:
+* Red Hat, Inc
+*******************************************************************************/
+
+/* Manually written code */
+
+#include "webkitgtk_custom.h"
+#include "webkitgtk.h" // For WebKitGTK_LOAD_FUNCTION macro
+#include "swt.h" // For types like jintLong etc..
+
+#include <gio/gio.h> // For things like GAsyncResult
+
+
+// Note about webkit includes:
+// Do not include things like '<webkit2/webkit2.h>' '<JavaScriptCore/JavaScript.h>' directly.
+// All webkit functions must be loaded dynamically.
+// If you compile on a newer Linux that contains Webkit2, trying to run the compiled binary on older
+// OS's without webkit2 will lead to a crash even when they are running in 'Webkit1' mode.
+// See Bug 430538.
+
+
+/*
+ Calling JS script and getting return value example copied and adapted from:
+ https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#webkit-web-view-run-javascript-finish
+*/
+static void
+web_view_javascript_finished_callback (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+
+ //// TODO handling of return value to be implemented in Stage 2.
+ //// All webkit functions will need to be called dynamically.
+// WebKitJavascriptResult *js_result;
+// JSValueRef value;
+// JSGlobalContextRef context;
+// GError *error = NULL;
+//
+//
+// js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);
+// if (!js_result) {
+// // Recoverable runtime error:
+// g_warning ("webkitgtk_custom.c: Error running javascript(1): %s", error->message);
+// g_error_free (error);
+// } else {
+// context = webkit_javascript_result_get_global_context (js_result);
+// value = webkit_javascript_result_get_value (js_result);
+//
+//
+//// // TODO WEBKIT2 - handle various return value(s). Starter code below.
+// // Idea: create struct with pointer to return value and lock;
+// // then pass it along via user_data. NOTE *malloc it*
+//
+// // Supress compiler warnings till return types implemented.
+// (void) value;
+// (void) context;
+//
+//// if (JSValueIsString (context, value)) {
+//// JSStringRef js_str_value;
+//// gchar *str_value;
+//// gsize str_length;
+////
+//// js_str_value = JSValueToStringCopy (context, value, NULL);
+//// str_length = JSStringGetMaximumUTF8CStringSize (js_str_value);
+//// str_value = (gchar *)g_malloc (str_length);
+//// JSStringGetUTF8CString (js_str_value, str_value, str_length);
+//// JSStringRelease (js_str_value);
+//// g_print ("Script result: %s\n", str_value);
+//// g_free (str_value);
+////
+//// // else if JSValueIsBoolean
+//// // else if JSValueIsNumber
+//// // else if JSValueIsObject
+//// // else if JSValueIsNull
+//// // else if JSValueIsArray
+//// // else if JSValueIsUndefined (?)
+//// // else if JSValueIsDate (?)
+//// } else {
+//// g_warning ("webkitgtk_custom.c: Error running javascript(2): unexpected return value");
+//// }
+//
+// webkit_javascript_result_unref (js_result);
+// }
+//
+// // Note about exit points: this function must unlock the spinlock prior to returning.
+// // As such there should not be a 'return' in this function above the unlocking code
+ gboolean *JsCallFinished = (gboolean* ) user_data;
+ *JsCallFinished = TRUE;
+}
+
+
+
+/*
+ * Type notes:
+ * [Java] -> [native]
+ * byte [] -> signed char *str
+ * long /int/ -> long
+*/
+/**
+ * Convert the async function webkit_web_view_run_javascript(..) into a synchronous one
+ * by spinning until the callback is completed.
+ */
+long swt_webkit_web_view_run_javascript (long webkit_handle, signed char *script) {
+
+ // TODO - WEBKIT2 port this will eventually be a struct that will hold the return value.
+ gboolean * JsCallFinished = g_new(gboolean, 1); //allocate 1 unit of gboolean (not assigning '1' to it).
+ *JsCallFinished = FALSE;
+
+ // Macro usage copied and adjusted from webkitgtk.c's 'NO__1webkit_1web_1view_1run_1javascript' wrapper.
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_web_view_run_javascript)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jintLong, jbyte *, jintLong, jintLong, jintLong))fp)((jintLong) webkit_handle, script, (jintLong) 0, (jintLong) web_view_javascript_finished_callback, (jintLong) JsCallFinished);
+ }
+
+ // Spin till callback completes. Note this spin is needed for 'callback' event to be called, otherwise we have a hang.
+ while (*JsCallFinished == FALSE) {
+ g_main_context_iteration(0, FALSE);
+ }
+ g_free(JsCallFinished);
+
+ return 1;
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.h
new file mode 100644
index 0000000000..c220705b07
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_custom.h
@@ -0,0 +1,24 @@
+/*******************************************************************************
+* Copyright (c) 2016 Red Hat, Inc. All rights reserved.
+* The contents of this file are made available under the terms
+* of the GNU Lesser General Public License (LGPL) Version 2.1 that
+* accompanies this distribution (lgpl-v21.txt). The LGPL is also
+* available at http://www.gnu.org/licenses/lgpl.html. If the version
+* of the LGPL at http://www.gnu.org is different to the version of
+* the LGPL accompanying this distribution and there is any conflict
+* between the two license versions, the terms of the LGPL accompanying
+* this distribution shall govern.
+*
+* Contributors:
+* Red Hat, Inc
+*******************************************************************************/
+
+#ifndef INC_webkitgtk_custom_H
+#define INC_webkitgtk_custom_H
+
+/* Manually written code */
+
+long swt_webkit_web_view_run_javascript (long webkit_handle, signed char *script);
+
+#endif /*INC_webkit_custom_H*/
+
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
index 6d0961a560..0a8a44ae42 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
@@ -73,6 +73,7 @@ char * WebKitGTK_nativeFunctionNames[] = {
"_1soup_1uri_1free",
"_1soup_1uri_1new",
"_1soup_1uri_1to_1string",
+ "_1swt_1webkit_1web_1view_1run_1javascript",
"_1webkit_1authentication_1request_1authenticate",
"_1webkit_1authentication_1request_1cancel",
"_1webkit_1authentication_1request_1is_1retry",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
index a882b17f55..20502b0ba8 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
@@ -83,6 +83,7 @@ typedef enum {
_1soup_1uri_1free_FUNC,
_1soup_1uri_1new_FUNC,
_1soup_1uri_1to_1string_FUNC,
+ _1swt_1webkit_1web_1view_1run_1javascript_FUNC,
_1webkit_1authentication_1request_1authenticate_FUNC,
_1webkit_1authentication_1request_1cancel_FUNC,
_1webkit_1authentication_1request_1is_1retry_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
index a4abe6e53f..a850e8da21 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
@@ -905,12 +905,11 @@ boolean close (boolean showPrompters) {
public boolean execute (String script) {
byte[] scriptBytes = (script + '\0').getBytes (StandardCharsets.UTF_8); //$NON-NLS-1$
-
long /*int*/ result = 0;
if (WEBKIT2){
- WebKitGTK.webkit_web_view_run_javascript (webView, scriptBytes, 0, 0, 0);
- // TODO - this call is asynchronous, so no return vaulue. As result this call executes but
- // returns false. Handling of return value to be implemented...
+ // Currently always returns 1 upon completion.
+ // TODO WEBKIT2 - modify webkitgtk_custom to return 0 if there is an error.
+ result = (int) WebKitGTK.swt_webkit_web_view_run_javascript(webView, scriptBytes);
} else {
long /*int*/ jsScriptString = WebKitGTK.JSStringCreateWithUTF8CString (scriptBytes);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
index 98fe4e30d0..4e52d2db86 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
@@ -1675,4 +1675,15 @@ public static final long /*int*/ SoupMessage_request_headers (long /*int*/ messa
}
}
+/* This custom function must only be called on Webkit2, use if (WEBKIT2) boolean. */
+public static final native long _swt_webkit_web_view_run_javascript (long /*int*/ webkit_handle, byte[] script);
+public static final long swt_webkit_web_view_run_javascript (long /*int*/ webkit_handle, byte[] script) {
+ lock.lock();
+ try {
+ return _swt_webkit_web_view_run_javascript (webkit_handle, script);
+ } finally {
+ lock.unlock();
+ }
+}
+
}

Back to the top