From 8eeaeab6af9eca94a0646564d627942d728d9f24 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Thu, 19 Jan 2023 15:24:05 +0100 Subject: [PATCH] wpe: Add 'run-javascript' action signal Introduce way of running a script in the context of the internal webView. Fixes #1722 Part-of: --- .../gst-plugins-bad/ext/wpe/WPEThreadedView.cpp | 21 +++++++++++++++++ .../gst-plugins-bad/ext/wpe/WPEThreadedView.h | 1 + .../gst-plugins-bad/ext/wpe/gstwpesrcbin.cpp | 25 +++++++++++++++++++++ .../gst-plugins-bad/ext/wpe/gstwpevideosrc.cpp | 26 ++++++++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.cpp b/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.cpp index 0ae233d..f81726c 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.cpp +++ b/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.cpp @@ -695,6 +695,27 @@ void WPEView::loadUri(const gchar* uri) }); } +static void s_runJavascriptFinished(GObject* object, GAsyncResult* result, gpointer user_data) +{ + WebKitJavascriptResult* js_result; + GError* error = NULL; + + js_result = webkit_web_view_run_javascript_finish(WEBKIT_WEB_VIEW(object), result, &error); + if (!js_result) { + GST_WARNING("Error running javascript: %s", error->message); + g_error_free(error); + return; + } + webkit_javascript_result_unref(js_result); +} + +void WPEView::runJavascript(const char* script) +{ + s_view->dispatch([&]() { + webkit_web_view_run_javascript(webkit.view, script, nullptr, s_runJavascriptFinished, nullptr); + }); +} + void WPEView::loadData(GBytes* bytes) { s_view->dispatch([this, bytes = g_bytes_ref(bytes)]() { diff --git a/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.h b/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.h index 3329ba0..315cfbf 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.h +++ b/subprojects/gst-plugins-bad/ext/wpe/WPEThreadedView.h @@ -43,6 +43,7 @@ public: void resize(int width, int height); void loadUri(const gchar*); void loadData(GBytes*); + void runJavascript(const gchar*); void setDrawBackground(gboolean); GstEGLImage* image(); diff --git a/subprojects/gst-plugins-bad/ext/wpe/gstwpesrcbin.cpp b/subprojects/gst-plugins-bad/ext/wpe/gstwpesrcbin.cpp index 563411c..9dfc19f 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/gstwpesrcbin.cpp +++ b/subprojects/gst-plugins-bad/ext/wpe/gstwpesrcbin.cpp @@ -150,6 +150,7 @@ enum enum { SIGNAL_LOAD_BYTES, + SIGNAL_RUN_JAVASCRIPT, LAST_SIGNAL }; @@ -342,6 +343,15 @@ gst_wpe_src_load_bytes (GstWpeVideoSrc * src, GBytes * bytes) } static void +gst_wpe_src_run_javascript (GstWpeVideoSrc * src, const gchar * script) +{ + GstWpeSrc *self = GST_WPE_SRC (src); + + if (self->video_src) + g_signal_emit_by_name (self->video_src, "run-javascript", script, NULL); +} + +static void gst_wpe_src_set_location (GstWpeSrc * src, const gchar * location) { g_object_set (src->video_src, "location", location, NULL); @@ -542,6 +552,21 @@ gst_wpe_src_class_init (GstWpeSrcClass * klass) G_CALLBACK (gst_wpe_src_load_bytes), NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BYTES); + /** + * GstWpeSrc::run-javascript: + * @src: the object which received the signal + * @script: the script to run + * + * Asynchronously run script in the context of the current page on the + * internal webView. + * + * Since: 1.22 + */ + gst_wpe_video_src_signals[SIGNAL_RUN_JAVASCRIPT] = + g_signal_new_class_handler ("run-javascript", G_TYPE_FROM_CLASS (klass), + static_cast < GSignalFlags > (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + G_CALLBACK (gst_wpe_src_run_javascript), NULL, NULL, NULL, G_TYPE_NONE, 1, + G_TYPE_STRING); element_class->change_state = GST_DEBUG_FUNCPTR (gst_wpe_src_change_state); gst_element_class_add_static_pad_template (element_class, &video_src_factory); diff --git a/subprojects/gst-plugins-bad/ext/wpe/gstwpevideosrc.cpp b/subprojects/gst-plugins-bad/ext/wpe/gstwpevideosrc.cpp index 48fbe88..fefd2a8 100644 --- a/subprojects/gst-plugins-bad/ext/wpe/gstwpevideosrc.cpp +++ b/subprojects/gst-plugins-bad/ext/wpe/gstwpevideosrc.cpp @@ -111,6 +111,7 @@ enum { SIGNAL_CONFIGURE_WEB_VIEW, SIGNAL_LOAD_BYTES, + SIGNAL_RUN_JAVASCRIPT, LAST_SIGNAL }; static guint gst_wpe_video_src_signals[LAST_SIGNAL] = { 0 }; @@ -460,6 +461,15 @@ gst_wpe_video_src_configure_web_view (GstWpeVideoSrc * src, } static void +gst_wpe_video_src_run_javascript (GstWpeVideoSrc * src, const gchar * script) +{ + if (src->view && GST_STATE (GST_ELEMENT_CAST (src)) > GST_STATE_NULL) { + GST_INFO_OBJECT (src, "running javascript"); + src->view->runJavascript (script); + } +} + +static void gst_wpe_video_src_load_bytes (GstWpeVideoSrc * src, GBytes * bytes) { if (src->view && GST_STATE (GST_ELEMENT_CAST (src)) > GST_STATE_NULL) { @@ -879,4 +889,20 @@ gst_wpe_video_src_class_init (GstWpeVideoSrcClass * klass) static_cast < GSignalFlags > (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), G_CALLBACK (gst_wpe_video_src_load_bytes), NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BYTES); + + /** + * GstWpeSrc::run-javascript: + * @src: the object which received the signal + * @script: the script to run + * + * Asynchronously run script in the context of the current page on the + * internal webView. + * + * Since: 1.22 + */ + gst_wpe_video_src_signals[SIGNAL_RUN_JAVASCRIPT] = + g_signal_new_class_handler ("run-javascript", G_TYPE_FROM_CLASS (klass), + static_cast < GSignalFlags > (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + G_CALLBACK (gst_wpe_video_src_run_javascript), NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_STRING); } -- 2.7.4