Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Ufimtsev2016-08-04 19:13:18 +0000
committerAlexander Kurtakov2016-09-09 07:13:36 +0000
commit7003ce9e76832ab4cf8e13c1633c97edca922ae7 (patch)
treed4c2cc7a465b49142606ccfafe3d7e9630bbe3da /bundles/org.eclipse.swt/Eclipse SWT WebKit
parent03e505a39be2165463f88264099ee8921b2bb263 (diff)
downloadeclipse.platform.swt-7003ce9e76832ab4cf8e13c1633c97edca922ae7.tar.gz
eclipse.platform.swt-7003ce9e76832ab4cf8e13c1633c97edca922ae7.tar.xz
eclipse.platform.swt-7003ce9e76832ab4cf8e13c1633c97edca922ae7.zip
Bug 430538: [GTK3][webkit] Support Custom JavaScript execution in
WebKit2 mode of SWT Browser Stage 1 - RADY FOR REVIEW. 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: I5a7b8ecb599de5ac30c2483f99d30f3a47995a64 Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=430538 Signed-off-by: Lev Ufimtsev <lufimtse@redhat.com>
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT WebKit')
-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
8 files changed, 195 insertions, 5 deletions
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