+2012-03-21 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ [GTK] Add webkit_web_view_run_javascript() to WebKit2 GTK+
+ https://bugs.webkit.org/show_bug.cgi?id=75543
+
+ Reviewed by Martin Robinson.
+
+ * GNUmakefile.am: Add new files to compilation.
+ * UIProcess/API/gtk/WebKitError.cpp:
+ (webkit_javascript_error_quark): Add new error domain for
+ Javascript errors.
+ * UIProcess/API/gtk/WebKitError.h:
+ * UIProcess/API/gtk/WebKitJavascriptResult.cpp: Added.
+ (webkitJavascriptResultCreate): Create a WebKitJavascriptResult
+ for the given WKSerializedScriptValueRef.
+ (webkit_javascript_result_ref): Increment reference count of
+ WebKitJavascriptResult.
+ (webkit_javascript_result_unref): Decrement reference count of
+ WebKitJavascriptResult.
+ (webkit_javascript_result_get_global_context): Get global
+ javascript context of the result.
+ (webkit_javascript_result_get_value): Get the JSValueRef of the
+ result.
+ * UIProcess/API/gtk/WebKitJavascriptResult.h: Added.
+ * UIProcess/API/gtk/WebKitJavascriptResultPrivate.h: Added.
+ * UIProcess/API/gtk/WebKitPrivate.h:
+ * UIProcess/API/gtk/WebKitWebView.cpp:
+ (webkitWebViewFinalize): Release the global javascript context.
+ (webkit_web_view_get_javascript_global_context): Get or create the
+ global javascript context.
+ (webkitWebViewRunJavaScriptCallback): Callback called by C API when
+ javascript execution finishes.
+ (webkit_web_view_run_javascript): Asynchronously run a given
+ javascript.
+ (webkit_web_view_run_javascript_finish): Finish async operation
+ started by webkit_web_view_run_javascript().
+ * UIProcess/API/gtk/WebKitWebView.h:
+ * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Add new symbols.
+ * UIProcess/API/gtk/docs/webkit2gtk.types: Add
+ webkit_javascript_result_get_type().
+ * UIProcess/API/gtk/tests/TestWebKitWebView.cpp:
+ (testWebViewRunJavaScript):
+ (beforeAll):
+ * UIProcess/API/gtk/tests/WebViewTest.cpp:
+ (WebViewTest::WebViewTest):
+ (WebViewTest::~WebViewTest):
+ (runJavaScriptReadyCallback):
+ (WebViewTest::runJavaScriptAndWaitUntilFinished):
+ (jsValueToCString):
+ (WebViewTest::javascriptResultToCString):
+ (WebViewTest::javascriptResultToNumber):
+ (WebViewTest::javascriptResultToBoolean):
+ (WebViewTest::javascriptResultIsNull):
+ (WebViewTest::javascriptResultIsUndefined):
+ * UIProcess/API/gtk/tests/WebViewTest.h:
+ * UIProcess/API/gtk/webkit2.h:
+
2012-03-20 Eric Seidel <eric@webkit.org>
Move wtf/Platform.h from JavaScriptCore to Source/WTF/wtf
$(WebKit2)/UIProcess/API/gtk/WebKitError.h \
$(WebKit2)/UIProcess/API/gtk/WebKitFindController.h \
$(WebKit2)/UIProcess/API/gtk/WebKitHitTestResult.h \
+ $(WebKit2)/UIProcess/API/gtk/WebKitJavascriptResult.h \
$(WebKit2)/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h \
$(WebKit2)/UIProcess/API/gtk/WebKitPolicyDecision.h \
$(WebKit2)/UIProcess/API/gtk/WebKitPrintOperation.h \
Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp \
Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h \
Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h \
+ Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp \
+ Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h \
+ Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h \
Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.h \
Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp \
Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h \
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_GENERAL, PrintErrorGeneral);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND, PrintErrorPrinterNotFound);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE, PrintErrorInvalidPageRange);
+
+GQuark webkit_javascript_error_quark()
+{
+ return g_quark_from_static_string("WebKitJavascriptError");
+}
G_BEGIN_DECLS
-#define WEBKIT_NETWORK_ERROR webkit_network_error_quark ()
-#define WEBKIT_POLICY_ERROR webkit_policy_error_quark ()
-#define WEBKIT_PLUGIN_ERROR webkit_plugin_error_quark ()
-#define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark ()
-#define WEBKIT_PRINT_ERROR webkit_print_error_quark ()
+#define WEBKIT_NETWORK_ERROR webkit_network_error_quark ()
+#define WEBKIT_POLICY_ERROR webkit_policy_error_quark ()
+#define WEBKIT_PLUGIN_ERROR webkit_plugin_error_quark ()
+#define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark ()
+#define WEBKIT_PRINT_ERROR webkit_print_error_quark ()
+#define WEBKIT_JAVASCRIPT_ERROR webkit_print_error_quark ()
/**
* WebKitNetworkError:
WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE = 501
} WebKitPrintError;
+/**
+ * WebKitJavascriptError:
+ * @WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED: An exception was raised in Javascript execution
+ *
+ * Enum values used to denote errors happending when executing Javascript
+ */
+typedef enum {
+ WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED = 699
+} WebKitJavascriptError;
+
+WEBKIT_API GQuark
+webkit_network_error_quark (void);
+
WEBKIT_API GQuark
-webkit_network_error_quark (void);
+webkit_policy_error_quark (void);
WEBKIT_API GQuark
-webkit_policy_error_quark (void);
+webkit_plugin_error_quark (void);
WEBKIT_API GQuark
-webkit_plugin_error_quark (void);
+webkit_download_error_quark (void);
WEBKIT_API GQuark
-webkit_download_error_quark (void);
+webkit_print_error_quark (void);
WEBKIT_API GQuark
-webkit_print_error_quark (void);
+webkit_javascript_error_quark (void);
G_END_DECLS
--- /dev/null
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebKitJavascriptResult.h"
+
+#include "WebKitJavascriptResultPrivate.h"
+#include <wtf/gobject/GRefPtr.h>
+
+struct _WebKitJavascriptResult {
+ _WebKitJavascriptResult(WebKitWebView* view, WKSerializedScriptValueRef wkSerializedScriptValue)
+ : webView(view)
+ , referenceCount(1)
+ {
+ value = WKSerializedScriptValueDeserialize(wkSerializedScriptValue, webkit_web_view_get_javascript_global_context(view), 0);
+ }
+
+ GRefPtr<WebKitWebView> webView;
+ JSValueRef value;
+
+ int referenceCount;
+};
+
+G_DEFINE_BOXED_TYPE(WebKitJavascriptResult, webkit_javascript_result, webkit_javascript_result_ref, webkit_javascript_result_unref)
+
+WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WKSerializedScriptValueRef wkSerializedScriptValue)
+{
+ WebKitJavascriptResult* result = g_slice_new(WebKitJavascriptResult);
+ new (result) WebKitJavascriptResult(webView, wkSerializedScriptValue);
+ return result;
+}
+
+/**
+ * webkit_javascript_result_ref:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Atomically increments the reference count of @js_result by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #WebKitJavascriptResult
+ */
+WebKitJavascriptResult* webkit_javascript_result_ref(WebKitJavascriptResult* javascriptResult)
+{
+ g_atomic_int_inc(&javascriptResult->referenceCount);
+ return javascriptResult;
+}
+
+/**
+ * webkit_javascript_result_unref:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Atomically decrements the reference count of @js_result by one. If the
+ * reference count drops to 0, all memory allocated by the #WebKitJavascriptResult is
+ * released. This function is MT-safe and may be called from any
+ * thread.
+ */
+void webkit_javascript_result_unref(WebKitJavascriptResult* javascriptResult)
+{
+ if (g_atomic_int_dec_and_test(&javascriptResult->referenceCount)) {
+ javascriptResult->~WebKitJavascriptResult();
+ g_slice_free(WebKitJavascriptResult, javascriptResult);
+ }
+}
+
+/**
+ * webkit_javascript_result_get_global_context:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Get the global Javascript context that should be used with the
+ * <function>JSValueRef</function> returned by webkit_javascript_result_get_value().
+ *
+ * Returns: the <function>JSGlobalContextRef</function> for the #WebKitJavascriptResult
+ */
+JSGlobalContextRef webkit_javascript_result_get_global_context(WebKitJavascriptResult* javascriptResult)
+{
+ return webkit_web_view_get_javascript_global_context(javascriptResult->webView.get());
+}
+
+/**
+ * webkit_javascript_result_get_value:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Get the value of @js_result. You should use the <function>JSGlobalContextRef</function>
+ * returned by webkit_javascript_result_get_global_context() to use the <function>JSValueRef</function>.
+ *
+ * Returns: the <function>JSValueRef</function> of the #WebKitJavascriptResult
+ */
+JSValueRef webkit_javascript_result_get_value(WebKitJavascriptResult* javascriptResult)
+{
+ return javascriptResult->value;
+}
--- /dev/null
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitJavascriptResult_h
+#define WebKitJavascriptResult_h
+
+#include <JavaScriptCore/JSBase.h>
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_JAVASCRIPT_RESULT (webkit_javascript_result_get_type())
+
+typedef struct _WebKitJavascriptResult WebKitJavascriptResult;
+
+
+WEBKIT_API GType
+webkit_javascript_result_get_type (void);
+
+WEBKIT_API WebKitJavascriptResult *
+webkit_javascript_result_ref (WebKitJavascriptResult *js_result);
+
+WEBKIT_API void
+webkit_javascript_result_unref (WebKitJavascriptResult *js_result);
+
+WEBKIT_API JSGlobalContextRef
+webkit_javascript_result_get_global_context (WebKitJavascriptResult *js_result);
+
+WEBKIT_API JSValueRef
+webkit_javascript_result_get_value (WebKitJavascriptResult *js_result);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitJavascriptResultPrivate_h
+#define WebKitJavascriptResultPrivate_h
+
+#include "WebKitJavascriptResult.h"
+#include "WebKitPrivate.h"
+#include "WebKitWebView.h"
+
+WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WKSerializedScriptValueRef);
+
+#endif // WebKitJavascriptResultPrivate_h
#include <WebKit2/WKDownload.h>
#include <WebKit2/WKFindOptions.h>
#include <WebKit2/WKRetainPtr.h>
+#include <WebKit2/WKSerializedScriptValue.h>
#include <WebKit2/WKString.h>
#include <WebKit2/WebKit2.h>
#include <glib.h>
#include "WebKitEnumTypes.h"
#include "WebKitError.h"
#include "WebKitHitTestResultPrivate.h"
+#include "WebKitJavascriptResultPrivate.h"
#include "WebKitLoaderClient.h"
#include "WebKitMarshal.h"
#include "WebKitPolicyClient.h"
#include "WebKitWebViewPrivate.h"
#include "WebKitWindowPropertiesPrivate.h"
#include "WebPageProxy.h"
+#include <JavaScriptCore/APICast.h>
#include <WebCore/DragIcon.h>
#include <WebCore/GtkUtilities.h>
#include <glib/gi18n-lib.h>
unsigned mouseTargetModifiers;
GRefPtr<WebKitFindController> findController;
+ JSGlobalContextRef javascriptGlobalContext;
};
static guint signals[LAST_SIGNAL] = { 0, };
static void webkitWebViewFinalize(GObject* object)
{
- WEBKIT_WEB_VIEW(object)->priv->~WebKitWebViewPrivate();
+ WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(object)->priv;
+ if (priv->javascriptGlobalContext)
+ JSGlobalContextRelease(priv->javascriptGlobalContext);
+ priv->~WebKitWebViewPrivate();
G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
}
return webView->priv->findController.get();
}
+
+/**
+ * webkit_web_view_get_javascript_global_context:
+ * @web_view: a #WebKitWebView
+ *
+ * Get the global JavaScript context used by @web_view to deserialize the
+ * result values of scripts executed with webkit_web_view_run_javascript().
+ *
+ * Returns: the <function>JSGlobalContextRef</function> used by @web_view to deserialize
+ * the result values of scripts.
+ */
+JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+
+ if (!webView->priv->javascriptGlobalContext)
+ webView->priv->javascriptGlobalContext = JSGlobalContextCreate(0);
+ return webView->priv->javascriptGlobalContext;
+}
+
+static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSerializedScriptValue, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ if (wkSerializedScriptValue) {
+ GRefPtr<WebKitWebView> webView = adoptGRef(WEBKIT_WEB_VIEW(g_async_result_get_source_object(G_ASYNC_RESULT(result.get()))));
+ WebKitJavascriptResult* scriptResult = webkitJavascriptResultCreate(webView.get(), wkSerializedScriptValue);
+ g_simple_async_result_set_op_res_gpointer(result.get(), scriptResult, reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref));
+ } else {
+ GError* error = 0;
+ g_set_error_literal(&error, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED, _("An exception was raised in JavaScript"));
+ g_simple_async_result_take_error(result.get(), error);
+ }
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_web_view_run_javascript:
+ * @web_view: a #WebKitWebView
+ * @script: the script to run
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously run @script in the context of the current page in @web_view.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_web_view_run_javascript_finish() to get the result of the operation.
+ */
+void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
+ g_return_if_fail(script);
+
+ WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WKRetainPtr<WKStringRef> wkScript = adoptWK(WKStringCreateWithUTF8CString(script));
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(webView), callback, userData,
+ reinterpret_cast<gpointer>(webkit_web_view_run_javascript));
+ WKPageRunJavaScriptInMainFrame(wkPage, wkScript.get(), result, webkitWebViewRunJavaScriptCallback);
+}
+
+/**
+ * webkit_web_view_run_javascript_finish:
+ * @web_view: a #WebKitWebView
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_web_view_run_javascript().
+ *
+ * This is an example of using webkit_web_view_run_javascript() with a script returning
+ * a string:
+ *
+ * <informalexample><programlisting>
+ * static void
+ * web_view_javascript_finished (GObject *object,
+ * GAsyncResult *result,
+ * gpointer user_data)
+ * {
+ * 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) {
+ * g_warning ("Error running javascript: %s", error->message);
+ * g_error_free (error);
+ * return;
+ * }
+ *
+ * context = webkit_javascript_result_get_global_context (js_result);
+ * value = webkit_javascript_result_get_value (js_result);
+ * 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 {
+ * g_warning ("Error running javascript: unexpected return value");
+ * }
+ * webkit_javascript_result_unref (js_result);
+ * }
+ *
+ * static void
+ * web_view_get_link_url (WebKitWebView *web_view,
+ * const gchar *link_id)
+ * {
+ * gchar *script;
+ *
+ * script = g_strdup_printf ("window.document.getElementById('%s').href;", link_id);
+ * webkit_web_view_run_javascript (web_view, script, web_view_javascript_finished, NULL);
+ * g_free (script);
+ * }
+ * </programlisting></informalexample>
+ *
+ * Returns: (transfer full): a #WebKitJavascriptResult with the result of the last executed statement in @script
+ * or %NULL in case of error
+ */
+WebKitJavascriptResult* webkit_web_view_run_javascript_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
+
+ GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_web_view_run_javascript);
+
+ if (g_simple_async_result_propagate_error(simpleResult, error))
+ return 0;
+
+ WebKitJavascriptResult* scriptResult = static_cast<WebKitJavascriptResult*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
+ return scriptResult ? webkit_javascript_result_ref(scriptResult) : 0;
+}
#ifndef WebKitWebView_h
#define WebKitWebView_h
+#include <JavaScriptCore/JSBase.h>
#include <webkit2/WebKitBackForwardList.h>
#include <webkit2/WebKitDefines.h>
#include <webkit2/WebKitFindController.h>
#include <webkit2/WebKitHitTestResult.h>
+#include <webkit2/WebKitJavascriptResult.h>
#include <webkit2/WebKitScriptDialog.h>
#include <webkit2/WebKitSettings.h>
#include <webkit2/WebKitURIRequest.h>
WEBKIT_API WebKitFindController *
webkit_web_view_get_find_controller (WebKitWebView *web_view);
+WEBKIT_API JSGlobalContextRef
+webkit_web_view_get_javascript_global_context (WebKitWebView *web_view);
+
+WEBKIT_API void
+webkit_web_view_run_javascript (WebKitWebView *web_view,
+ const gchar *script,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+WEBKIT_API WebKitJavascriptResult *
+webkit_web_view_run_javascript_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
#endif
WebKitWebView
WebKitLoadEvent
WebKitPolicyDecisionType
-WebKitScriptDialog
-WebKitScriptDialogType
<SUBSECTION Editing Commands>
WEBKIT_EDITING_COMMAND_CUT
webkit_web_view_can_execute_editing_command_finish
webkit_web_view_execute_editing_command
webkit_web_view_get_find_controller
+webkit_web_view_get_javascript_global_context
+webkit_web_view_run_javascript
+webkit_web_view_run_javascript_finish
+
+<SUBSECTION WebKitJavascriptResult>
+WebKitJavascriptResult
+webkit_javascript_result_ref
+webkit_javascript_result_unref
+webkit_javascript_result_get_global_context
+webkit_javascript_result_get_value
+
+<SUBSECTION WebKitScriptDialog>
+WebKitScriptDialog
+WebKitScriptDialogType
webkit_script_dialog_get_dialog_type
webkit_script_dialog_get_message
webkit_script_dialog_confirm_set_confirmed
WEBKIT_WEB_VIEW_CLASS
WEBKIT_IS_WEB_VIEW_CLASS
WEBKIT_WEB_VIEW_GET_CLASS
+WEBKIT_TYPE_JAVASCRIPT_RESULT
WEBKIT_TYPE_SCRIPT_DIALOG
<SUBSECTION Private>
webkit_web_view_get_type
+webkit_javascript_result_get_type
webkit_script_dialog_get_type
WebKitWebViewPrivate
</SECTION>
WEBKIT_POLICY_ERROR
WEBKIT_DOWNLOAD_ERROR
WEBKIT_PRINT_ERROR
+WEBKIT_JAVASCRIPT_ERROR
WebKitNetworkError
WebKitPluginError
WebKitPolicyError
WebKitDownloadError
WebKitPrintError
+WebKitJavascriptError
webkit_network_error_quark
webkit_plugin_error_quark
webkit_policy_error_quark
webkit_download_error_quark
webkit_print_error_quark
+webkit_javascript_error_quark
</SECTION>
<SECTION>
webkit_download_get_type
webkit_find_controller_get_type
webkit_script_dialog_get_type
+webkit_javascript_result_get_type
g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5);
}
+static void testWebViewRunJavaScript(WebViewTest* test, gconstpointer)
+{
+ static const char* html = "<html><body><a id='WebKitLink' href='http://www.webkitgtk.org/' title='WebKitGTK+ Title'>WebKitGTK+ Website</a></body></html>";
+ test->loadHtml(html, 0);
+ test->waitUntilLoadFinished();
+
+ GOwnPtr<GError> error;
+ WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').title;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ GOwnPtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Title");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').href;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ valueString.set(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "http://www.webkitgtk.org/");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').textContent", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ valueString.set(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Website");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = 25;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 25);
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = 2.5;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 2.5);
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = true", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultToBoolean(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = false", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(!WebViewTest::javascriptResultToBoolean(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = null", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultIsNull(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("function Foo() { a = 25; } Foo();", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultIsUndefined(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("foo();", &error.outPtr());
+ g_assert(!javascriptResult);
+ g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED);
+}
+
void beforeAll()
{
WebViewTest::add("WebKitWebView", "default-context", testWebViewDefaultContext);
UIClientTest::add("WebKitWebView", "window-properties", testWebViewWindowProperties);
UIClientTest::add("WebKitWebView", "mouse-target", testWebViewMouseTarget);
WebViewTest::add("WebKitWebView", "zoom-level", testWebViewZoomLevel);
+ WebViewTest::add("WebKitWebView", "run-javascript", testWebViewRunJavaScript);
}
void afterAll()
#include "config.h"
#include "WebViewTest.h"
+#include <JavaScriptCore/JSRetainPtr.h>
#include <WebCore/GOwnPtrGtk.h>
WebViewTest::WebViewTest()
: m_webView(WEBKIT_WEB_VIEW(g_object_ref_sink(webkit_web_view_new())))
, m_mainLoop(g_main_loop_new(0, TRUE))
, m_parentWindow(0)
+ , m_javascriptResult(0)
{
assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_webView));
}
{
if (m_parentWindow)
gtk_widget_destroy(m_parentWindow);
+ if (m_javascriptResult)
+ webkit_javascript_result_unref(m_javascriptResult);
g_object_unref(m_webView);
g_main_loop_unref(m_mainLoop);
}
gtk_main_do_event(event.get());
}
+static void runJavaScriptReadyCallback(GObject*, GAsyncResult* result, WebViewTest* test)
+{
+ test->m_javascriptResult = webkit_web_view_run_javascript_finish(test->m_webView, result, test->m_javascriptError);
+ g_main_loop_quit(test->m_mainLoop);
+}
+
+WebKitJavascriptResult* WebViewTest::runJavaScriptAndWaitUntilFinished(const char* javascript, GError** error)
+{
+ if (m_javascriptResult)
+ webkit_javascript_result_unref(m_javascriptResult);
+ m_javascriptResult = 0;
+ m_javascriptError = error;
+ webkit_web_view_run_javascript(m_webView, javascript, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptReadyCallback), this);
+ g_main_loop_run(m_mainLoop);
+
+ return m_javascriptResult;
+}
+
+static char* jsValueToCString(JSGlobalContextRef context, JSValueRef value)
+{
+ g_assert(value);
+ g_assert(JSValueIsString(context, value));
+
+ JSRetainPtr<JSStringRef> stringValue(Adopt, JSValueToStringCopy(context, value, 0));
+ g_assert(stringValue);
+
+ size_t cStringLength = JSStringGetMaximumUTF8CStringSize(stringValue.get());
+ char* cString = static_cast<char*>(g_malloc(cStringLength));
+ JSStringGetUTF8CString(stringValue.get(), cString, cStringLength);
+ return cString;
+}
+
+char* WebViewTest::javascriptResultToCString(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ return jsValueToCString(context, webkit_javascript_result_get_value(javascriptResult));
+}
+
+double WebViewTest::javascriptResultToNumber(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+ g_assert(JSValueIsNumber(context, value));
+
+ return JSValueToNumber(context, value, 0);
+}
+
+bool WebViewTest::javascriptResultToBoolean(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+ g_assert(JSValueIsBoolean(context, value));
+
+ return JSValueToBoolean(context, value);
+}
+
+bool WebViewTest::javascriptResultIsNull(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+
+ return JSValueIsNull(context, value);
+}
+
+bool WebViewTest::javascriptResultIsUndefined(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+
+ return JSValueIsUndefined(context, value);
+}
+
void mouseMoveTo(int x, int y, unsigned int mouseModifiers = 0);
+ WebKitJavascriptResult* runJavaScriptAndWaitUntilFinished(const char* javascript, GError**);
+
+ // Javascript result helpers.
+ static char* javascriptResultToCString(WebKitJavascriptResult*);
+ static double javascriptResultToNumber(WebKitJavascriptResult*);
+ static bool javascriptResultToBoolean(WebKitJavascriptResult*);
+ static bool javascriptResultIsNull(WebKitJavascriptResult*);
+ static bool javascriptResultIsUndefined(WebKitJavascriptResult*);
+
WebKitWebView* m_webView;
GMainLoop* m_mainLoop;
CString m_activeURI;
GtkWidget* m_parentWindow;
CString m_expectedTitle;
+ WebKitJavascriptResult* m_javascriptResult;
+ GError** m_javascriptError;
};
#endif // WebViewTest_h
#include <webkit2/WebKitError.h>
#include <webkit2/WebKitFindController.h>
#include <webkit2/WebKitHitTestResult.h>
+#include <webkit2/WebKitJavascriptResult.h>
#include <webkit2/WebKitPrintOperation.h>
#include <webkit2/WebKitScriptDialog.h>
#include <webkit2/WebKitSettings.h>
+2012-03-21 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ [GTK] Add webkit_web_view_run_javascript() to WebKit2 GTK+
+ https://bugs.webkit.org/show_bug.cgi?id=75543
+
+ Reviewed by Martin Robinson.
+
+ * MiniBrowser/gtk/GNUmakefile.am: Add javascriptcore_cppflags to
+ MiniBrowser CPP flags.
+
2012-03-20 Eric Seidel <eric@webkit.org>
Move wtf/Platform.h from JavaScriptCore to Source/WTF/wtf
-I$(top_builddir)/DerivedSources/WebKit2/webkit2gtk/include \
-DWEBKIT_EXEC_PATH=\"${shell pwd}/$(top_builddir)/Programs/\" \
$(global_cppflags) \
+ $(javascriptcore_cppflags) \
$(GLIB_CFLAGS) \
$(GTK_CFLAGS)