Skip to content

Commit

Permalink
[WPE][GTK] Warning: WebKit2: Couldn't find 'run_async_javascript_func…
Browse files Browse the repository at this point in the history
…tion_in_world_finish' for the corresponding async function: 'run_async_javascript_function_in_world'

https://bugs.webkit.org/show_bug.cgi?id=269377

Reviewed by Adrian Perez de Castro.

We need to use the new finish-func annotation so that language bindings
can figure out how to complete the async call, due to our nonstandard
naming for the finish function. It seems trying to reuse the same finish
function for multiple async calls was not such a good idea.

Unfortunately, with older gobject-introspection, we cannot use this
new annotation or the build will fail due to the unrecognized
annotation. So we will need to conditionalize the entire doc comment.

Finally, I've also fixed the nullability of the world_name parameter,
which was broken due to a missing colon.

* Source/WebKit/PlatformGTK.cmake:
* Source/WebKit/PlatformWPE.cmake:
* Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp:
* Source/WebKit/UIProcess/API/glib/WebKitWebView.h.in:

Canonical link: https://commits.webkit.org/276012@main
  • Loading branch information
mcatanzaro committed Mar 13, 2024
1 parent 61416a0 commit 910ab18
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 69 deletions.
8 changes: 8 additions & 0 deletions Source/WebKit/PlatformGTK.cmake
Expand Up @@ -369,14 +369,22 @@ if (ENABLE_MEDIA_STREAM)
)
endif ()

if (${GI_VERSION} VERSION_GREATER_EQUAL 1.79.2)
set(USE_GI_FINISH_FUNC_ANNOTATION 1)
else ()
set(USE_GI_FINISH_FUNC_ANNOTATION 0)
endif ()

GENERATE_GLIB_API_HEADERS(WebKit WebKitGTK_HEADER_TEMPLATES
${WebKitGTK_DERIVED_SOURCES_DIR}/webkit
WebKitGTK_INSTALLED_HEADERS
"-DWTF_PLATFORM_GTK=1"
"-DWTF_PLATFORM_WPE=0"
"-DUSE_GTK4=$<BOOL:${USE_GTK4}>"
"-DENABLE_2022_GLIB_API=$<BOOL:${ENABLE_2022_GLIB_API}>"
"-DUSE_GI_FINISH_FUNC_ANNOTATION=${USE_GI_FINISH_FUNC_ANNOTATION}"
)
unset(USE_GI_FINISH_FUNC_ANNOTATION)

GENERATE_GLIB_API_HEADERS(WebKit WebKitWebProcessExtension_HEADER_TEMPLATES
${WebKitGTK_DERIVED_SOURCES_DIR}/webkit
Expand Down
8 changes: 8 additions & 0 deletions Source/WebKit/PlatformWPE.cmake
Expand Up @@ -276,14 +276,22 @@ list(APPEND WebKit_DEPENDENCIES
webkitwpe-forwarding-headers
)

if (${GI_VERSION} VERSION_GREATER_EQUAL 1.79.2)
set(USE_GI_FINISH_FUNC_ANNOTATION 1)
else ()
set(USE_GI_FINISH_FUNC_ANNOTATION 0)
endif ()

GENERATE_GLIB_API_HEADERS(WebKit WPE_API_HEADER_TEMPLATES
${DERIVED_SOURCES_WPE_API_DIR}
WPE_API_INSTALLED_HEADERS
"-DWTF_PLATFORM_GTK=0"
"-DWTF_PLATFORM_WPE=1"
"-DUSE_GTK4=0"
"-DENABLE_2022_GLIB_API=$<BOOL:${ENABLE_2022_GLIB_API}>"
"-DUSE_GI_FINISH_FUNC_ANNOTATION=${USE_GI_FINISH_FUNC_ANNOTATION}"
)
unset(USE_GI_FINISH_FUNC_ANNOTATION)

GENERATE_GLIB_API_HEADERS(WebKit WPE_WEB_PROCESS_EXTENSION_API_HEADER_TEMPLATES
${DERIVED_SOURCES_WPE_API_DIR}
Expand Down
69 changes: 0 additions & 69 deletions Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
Expand Up @@ -4489,75 +4489,6 @@ void webkit_web_view_run_javascript_in_world(WebKitWebView* webView, const gchar
webkitWebViewEvaluateJavascriptInternal(webView, script, -1, worldName, nullptr, RunJavascriptReturnType::WebKitJavascriptResult, cancellable, callback, userData);
}

/**
* webkit_web_view_run_async_javascript_function_in_world:
* @web_view: a #WebKitWebView
* @body: the JavaScript function body
* @arguments: a #GVariant with format `{&sv}` storing the function arguments. Function argument values must be one of the following types, or contain only the following GVariant types: number, string, array, and dictionary.
* @world_name (nullable): the name of a #WebKitScriptWorld, if no name (i.e. %NULL) is provided, the default world is used. Any value that is not %NULL is a distinct world.
* @cancellable: (allow-none): a #GCancellable or %NULL to ignore
* @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
* @user_data: the data to pass to callback function
*
* Asynchronously run @body in the script world with name @world_name of the current page context in
* @web_view. If WebKitSettings:enable-javascript is FALSE, this method will do nothing. This API
* differs from webkit_web_view_run_javascript_in_world() in that the JavaScript function can return a
* Promise and its result will be properly passed to the callback.
*
* When the operation is finished, @callback will be called. You can then call
* webkit_web_view_run_javascript_in_world_finish() to get the result of the operation.
*
* For instance here is a dummy example that shows how to pass arguments to a JS function that
* returns a Promise that resolves with the passed argument:
*
* ```c
* static void
* web_view_javascript_finished (GObject *object,
* GAsyncResult *result,
* gpointer user_data)
* {
* WebKitJavascriptResult *js_result;
* JSCValue *value;
* 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;
* }
*
* value = webkit_javascript_result_get_js_value (js_result);
* if (jsc_value_is_number (value)) {
* gint32 int_value = jsc_value_to_string (value);
* JSCException *exception = jsc_context_get_exception (jsc_value_get_context (value));
* if (exception)
* g_warning ("Error running javascript: %s", jsc_exception_get_message (exception));
* else
* g_print ("Script result: %d\n", int_value);
* g_free (str_value);
* } else {
* g_warning ("Error running javascript: unexpected return value");
* }
* webkit_javascript_result_unref (js_result);
* }
*
* static void
* web_view_evaluate_promise (WebKitWebView *web_view)
* {
* GVariantDict dict;
* g_variant_dict_init (&dict, NULL);
* g_variant_dict_insert (&dict, "count", "u", 42);
* GVariant *args = g_variant_dict_end (&dict);
* const gchar *body = "return new Promise((resolve) => { resolve(count); });";
* webkit_web_view_run_async_javascript_function_in_world (web_view, body, arguments, NULL, NULL, web_view_javascript_finished, NULL);
* }
* ```
*
* Since: 2.38
*
* Deprecated: 2.40: Use webkit_web_view_call_async_javascript_function() instead.
*/
void webkit_web_view_run_async_javascript_function_in_world(WebKitWebView* webView, const gchar* body, GVariant* arguments, const char* worldName, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
{
webkitWebViewCallAsyncJavascriptFunctionInternal(webView, body, -1, arguments, worldName, nullptr, RunJavascriptReturnType::WebKitJavascriptResult, cancellable, callback, userData);
Expand Down
142 changes: 142 additions & 0 deletions Source/WebKit/UIProcess/API/glib/WebKitWebView.h.in
Expand Up @@ -905,6 +905,148 @@ webkit_web_view_get_web_extension_mode (WebKitWebView
WEBKIT_API const gchar*
webkit_web_view_get_default_content_security_policy (WebKitWebView *web_view);

#if USE(GI_FINISH_FUNC_ANNOTATION)
/**
* webkit_web_view_run_async_javascript_function_in_world: (finish-func webkit_web_view_run_javascript_in_world_finish)
* @web_view: a #WebKitWebView
* @body: the JavaScript function body
* @arguments: a #GVariant with format `{&sv}` storing the function arguments. Function argument values must be one of the following types, or contain only the following GVariant types: number, string, array, and dictionary.
* @world_name: (nullable): the name of a #WebKitScriptWorld, if no name (i.e. %NULL) is provided, the default world is used. Any value that is not %NULL is a distinct world.
* @cancellable: (allow-none): a #GCancellable or %NULL to ignore
* @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
* @user_data: the data to pass to callback function
*
* Asynchronously run @body in the script world with name @world_name of the current page context in
* @web_view. If WebKitSettings:enable-javascript is FALSE, this method will do nothing. This API
* differs from webkit_web_view_run_javascript_in_world() in that the JavaScript function can return a
* Promise and its result will be properly passed to the callback.
*
* When the operation is finished, @callback will be called. You can then call
* webkit_web_view_run_javascript_in_world_finish() to get the result of the operation.
*
* For instance here is a dummy example that shows how to pass arguments to a JS function that
* returns a Promise that resolves with the passed argument:
*
* ```c
* static void
* web_view_javascript_finished (GObject *object,
* GAsyncResult *result,
* gpointer user_data)
* {
* WebKitJavascriptResult *js_result;
* JSCValue *value;
* 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;
* }
*
* value = webkit_javascript_result_get_js_value (js_result);
* if (jsc_value_is_number (value)) {
* gint32 int_value = jsc_value_to_string (value);
* JSCException *exception = jsc_context_get_exception (jsc_value_get_context (value));
* if (exception)
* g_warning ("Error running javascript: %s", jsc_exception_get_message (exception));
* else
* g_print ("Script result: %d\n", int_value);
* g_free (str_value);
* } else {
* g_warning ("Error running javascript: unexpected return value");
* }
* webkit_javascript_result_unref (js_result);
* }
*
* static void
* web_view_evaluate_promise (WebKitWebView *web_view)
* {
* GVariantDict dict;
* g_variant_dict_init (&dict, NULL);
* g_variant_dict_insert (&dict, "count", "u", 42);
* GVariant *args = g_variant_dict_end (&dict);
* const gchar *body = "return new Promise((resolve) => { resolve(count); });";
* webkit_web_view_run_async_javascript_function_in_world (web_view, body, arguments, NULL, NULL, web_view_javascript_finished, NULL);
* }
* ```
*
* Since: 2.38
*
* Deprecated: 2.40: Use webkit_web_view_call_async_javascript_function() instead.
*/
#else
/**
* webkit_web_view_run_async_javascript_function_in_world:
* @web_view: a #WebKitWebView
* @body: the JavaScript function body
* @arguments: a #GVariant with format `{&sv}` storing the function arguments. Function argument values must be one of the following types, or contain only the following GVariant types: number, string, array, and dictionary.
* @world_name: (nullable): the name of a #WebKitScriptWorld, if no name (i.e. %NULL) is provided, the default world is used. Any value that is not %NULL is a distinct world.
* @cancellable: (allow-none): a #GCancellable or %NULL to ignore
* @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
* @user_data: the data to pass to callback function
*
* Asynchronously run @body in the script world with name @world_name of the current page context in
* @web_view. If WebKitSettings:enable-javascript is FALSE, this method will do nothing. This API
* differs from webkit_web_view_run_javascript_in_world() in that the JavaScript function can return a
* Promise and its result will be properly passed to the callback.
*
* When the operation is finished, @callback will be called. You can then call
* webkit_web_view_run_javascript_in_world_finish() to get the result of the operation.
*
* For instance here is a dummy example that shows how to pass arguments to a JS function that
* returns a Promise that resolves with the passed argument:
*
* ```c
* static void
* web_view_javascript_finished (GObject *object,
* GAsyncResult *result,
* gpointer user_data)
* {
* WebKitJavascriptResult *js_result;
* JSCValue *value;
* 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;
* }
*
* value = webkit_javascript_result_get_js_value (js_result);
* if (jsc_value_is_number (value)) {
* gint32 int_value = jsc_value_to_string (value);
* JSCException *exception = jsc_context_get_exception (jsc_value_get_context (value));
* if (exception)
* g_warning ("Error running javascript: %s", jsc_exception_get_message (exception));
* else
* g_print ("Script result: %d\n", int_value);
* g_free (str_value);
* } else {
* g_warning ("Error running javascript: unexpected return value");
* }
* webkit_javascript_result_unref (js_result);
* }
*
* static void
* web_view_evaluate_promise (WebKitWebView *web_view)
* {
* GVariantDict dict;
* g_variant_dict_init (&dict, NULL);
* g_variant_dict_insert (&dict, "count", "u", 42);
* GVariant *args = g_variant_dict_end (&dict);
* const gchar *body = "return new Promise((resolve) => { resolve(count); });";
* webkit_web_view_run_async_javascript_function_in_world (web_view, body, arguments, NULL, NULL, web_view_javascript_finished, NULL);
* }
* ```
*
* Since: 2.38
*
* Deprecated: 2.40: Use webkit_web_view_call_async_javascript_function() instead.
*/
#endif

G_END_DECLS

#endif

0 comments on commit 910ab18

Please sign in to comment.