[epiphany/pgriffis/web-extension-gtask: 10/15] WebExtensions: Add error reporting and ability to define async handlers
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/pgriffis/web-extension-gtask: 10/15] WebExtensions: Add error reporting and ability to define async handlers
- Date: Thu, 26 May 2022 20:46:21 +0000 (UTC)
commit 0327726d61a86eb7fb4ec604eacc12d8e2948587
Author: Patrick Griffis <pgriffis igalia com>
Date: Thu May 26 13:08:53 2022 -0500
WebExtensions: Add error reporting and ability to define async handlers
Now each API handler is backed by a GTask that can get errors.
For now we don't use the async ability but now its possible.
Part-of: <https://gitlab.gnome.org/GNOME/epiphany/-/merge_requests/1119>
src/webextension/api/notifications.c | 39 +++++---
src/webextension/api/notifications.h | 7 +-
src/webextension/api/pageaction.c | 83 +++++++++++------
src/webextension/api/pageaction.h | 7 +-
src/webextension/api/runtime.c | 58 ++++++------
src/webextension/api/runtime.h | 7 +-
src/webextension/api/storage.c | 63 ++++++++-----
src/webextension/api/storage.h | 7 +-
src/webextension/api/tabs.c | 124 +++++++++++++++++---------
src/webextension/api/tabs.h | 7 +-
src/webextension/ephy-web-extension-manager.c | 65 ++++++++++----
src/webextension/ephy-web-extension.h | 19 +++-
12 files changed, 320 insertions(+), 166 deletions(-)
---
diff --git a/src/webextension/api/notifications.c b/src/webextension/api/notifications.c
index 8e33bd783..5a367c174 100644
--- a/src/webextension/api/notifications.c
+++ b/src/webextension/api/notifications.c
@@ -26,9 +26,10 @@
#include "notifications.h"
static char *
-notifications_handler_create (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+notifications_handler_create (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
g_autoptr (JSCValue) value = jsc_value_object_get_property_at_index (args, 0);
g_autofree char *title_str = NULL;
@@ -37,8 +38,10 @@ notifications_handler_create (EphyWebExtension *self,
g_autoptr (JSCValue) message = NULL;
EphyNotification *notify;
- if (!jsc_value_is_object (value))
+ if (!jsc_value_is_object (value)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
title = jsc_value_object_get_property (value, "title");
title_str = jsc_value_to_string (title);
@@ -52,26 +55,36 @@ notifications_handler_create (EphyWebExtension *self,
return NULL;
}
-static EphyWebExtensionApiHandler notifications_handlers[] = {
+static EphyWebExtensionSyncApiHandler notifications_handlers[] = {
{"create", notifications_handler_create},
- {NULL, NULL},
};
-char *
+void
ephy_web_extension_api_notifications_handler (EphyWebExtension *self,
char *name,
- JSCValue *args)
+ JSCValue *args,
+ GTask *task)
{
+ g_autoptr (GError) error = NULL;
guint idx;
for (idx = 0; idx < G_N_ELEMENTS (notifications_handlers); idx++) {
- EphyWebExtensionApiHandler handler = notifications_handlers[idx];
+ EphyWebExtensionSyncApiHandler handler = notifications_handlers[idx];
+ char *ret;
+
+ if (g_strcmp0 (handler.name, name) == 0) {
+ ret = handler.execute (self, name, args, &error);
+
+ if (error)
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_pointer (task, ret, g_free);
- if (g_strcmp0 (handler.name, name) == 0)
- return handler.execute (self, name, args);
+ return;
+ }
}
g_warning ("%s(): '%s' not implemented by Epiphany!", __FUNCTION__, name);
-
- return NULL;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Not Implemented");
+ g_task_return_error (task, g_steal_pointer (&error));
}
diff --git a/src/webextension/api/notifications.h b/src/webextension/api/notifications.h
index f0f5434a7..eb3a455a6 100644
--- a/src/webextension/api/notifications.h
+++ b/src/webextension/api/notifications.h
@@ -25,8 +25,9 @@
G_BEGIN_DECLS
-char *ephy_web_extension_api_notifications_handler (EphyWebExtension *self,
- char *name,
- JSCValue *args);
+void ephy_web_extension_api_notifications_handler (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GTask *task);
G_END_DECLS
diff --git a/src/webextension/api/pageaction.c b/src/webextension/api/pageaction.c
index 70b6df697..aa52a0c56 100644
--- a/src/webextension/api/pageaction.c
+++ b/src/webextension/api/pageaction.c
@@ -54,9 +54,10 @@ pageaction_get_action (EphyWebExtension *self,
}
static char *
-pageaction_handler_seticon (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+pageaction_handler_seticon (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
GtkWidget *action;
g_autoptr (JSCValue) path = NULL;
@@ -64,8 +65,10 @@ pageaction_handler_seticon (EphyWebExtension *self,
g_autoptr (JSCValue) value = jsc_value_object_get_property_at_index (args, 0);
action = pageaction_get_action (self, value);
- if (!action)
+ if (!action) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
path = jsc_value_object_get_property (value, "path");
pixbuf = ephy_web_extension_load_pixbuf (self, jsc_value_to_string (path));
@@ -76,17 +79,20 @@ pageaction_handler_seticon (EphyWebExtension *self,
}
static char *
-pageaction_handler_settitle (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+pageaction_handler_settitle (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
GtkWidget *action;
g_autoptr (JSCValue) title = NULL;
g_autoptr (JSCValue) value = jsc_value_object_get_property_at_index (args, 0);
action = pageaction_get_action (self, value);
- if (!action)
+ if (!action) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
title = jsc_value_object_get_property (value, "title");
gtk_widget_set_tooltip_text (action, jsc_value_to_string (title));
@@ -95,17 +101,20 @@ pageaction_handler_settitle (EphyWebExtension *self,
}
static char *
-pageaction_handler_gettitle (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+pageaction_handler_gettitle (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
g_autoptr (JSCValue) value = jsc_value_object_get_property_at_index (args, 0);
GtkWidget *action;
g_autofree char *title = NULL;
action = pageaction_get_action (self, value);
- if (!action)
+ if (!action) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
title = gtk_widget_get_tooltip_text (action);
@@ -113,16 +122,19 @@ pageaction_handler_gettitle (EphyWebExtension *self,
}
static char *
-pageaction_handler_show (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+pageaction_handler_show (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
g_autoptr (JSCValue) value = jsc_value_object_get_property_at_index (args, 0);
GtkWidget *action;
action = pageaction_get_action (self, value);
- if (!action)
+ if (!action) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
gtk_widget_set_visible (action, TRUE);
@@ -130,46 +142,59 @@ pageaction_handler_show (EphyWebExtension *self,
}
static char *
-pageaction_handler_hide (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+pageaction_handler_hide (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
g_autoptr (JSCValue) value = jsc_value_object_get_property_at_index (args, 0);
GtkWidget *action;
action = pageaction_get_action (self, value);
- if (!action)
+ if (!action) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
gtk_widget_set_visible (action, FALSE);
return NULL;
}
-static EphyWebExtensionApiHandler pageaction_handlers[] = {
+static EphyWebExtensionSyncApiHandler pageaction_handlers[] = {
{"setIcon", pageaction_handler_seticon},
{"setTitle", pageaction_handler_settitle},
{"getTitle", pageaction_handler_gettitle},
{"show", pageaction_handler_show},
{"hide", pageaction_handler_hide},
- {NULL, NULL},
};
-char *
+void
ephy_web_extension_api_pageaction_handler (EphyWebExtension *self,
char *name,
- JSCValue *args)
+ JSCValue *args,
+ GTask *task)
{
+ g_autoptr (GError) error = NULL;
guint idx;
for (idx = 0; idx < G_N_ELEMENTS (pageaction_handlers); idx++) {
- EphyWebExtensionApiHandler handler = pageaction_handlers[idx];
+ EphyWebExtensionSyncApiHandler handler = pageaction_handlers[idx];
+ char *ret;
- if (g_strcmp0 (handler.name, name) == 0)
- return handler.execute (self, name, args);
+ if (g_strcmp0 (handler.name, name) == 0) {
+ ret = handler.execute (self, name, args, &error);
+
+ if (error)
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_pointer (task, ret, g_free);
+
+ return;
+ }
}
g_warning ("%s(): '%s' not implemented by Epiphany!", __FUNCTION__, name);
-
- return NULL;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Not Implemented");
+ g_task_return_error (task, g_steal_pointer (&error));
}
diff --git a/src/webextension/api/pageaction.h b/src/webextension/api/pageaction.h
index af3ce840b..293bf7825 100644
--- a/src/webextension/api/pageaction.h
+++ b/src/webextension/api/pageaction.h
@@ -25,8 +25,9 @@
G_BEGIN_DECLS
-char *ephy_web_extension_api_pageaction_handler (EphyWebExtension *self,
- char *name,
- JSCValue *args);
+void ephy_web_extension_api_pageaction_handler (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GTask *task);
G_END_DECLS
diff --git a/src/webextension/api/runtime.c b/src/webextension/api/runtime.c
index 4f9b1be1e..988cc8799 100644
--- a/src/webextension/api/runtime.c
+++ b/src/webextension/api/runtime.c
@@ -28,9 +28,10 @@
#include "ephy-shell.h"
static char *
-runtime_handler_get_browser_info (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+runtime_handler_get_browser_info (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
g_autoptr (JsonBuilder) builder = json_builder_new ();
g_autoptr (JsonNode) root = NULL;
@@ -46,9 +47,10 @@ runtime_handler_get_browser_info (EphyWebExtension *self,
}
static char *
-runtime_handler_send_message (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+runtime_handler_send_message (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
EphyShell *shell = ephy_shell_get_default ();
EphyWebExtensionManager *manager = ephy_shell_get_web_extension_manager (shell);
@@ -63,9 +65,10 @@ runtime_handler_send_message (EphyWebExtension *self,
}
static char *
-runtime_handler_open_options_page (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+runtime_handler_open_options_page (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
const char *data = ephy_web_extension_get_option_ui_page (self);
@@ -87,37 +90,38 @@ runtime_handler_open_options_page (EphyWebExtension *self,
return NULL;
}
-static char *
-runtime_handler_set_uninstall_url (EphyWebExtension *self,
- char *name,
- JSCValue *args)
-{
- return NULL;
-}
-
-static EphyWebExtensionApiHandler runtime_handlers[] = {
+static EphyWebExtensionSyncApiHandler runtime_handlers[] = {
{"getBrowserInfo", runtime_handler_get_browser_info},
{"sendMessage", runtime_handler_send_message},
{"openOptionsPage", runtime_handler_open_options_page},
- {"setUninstallURL", runtime_handler_set_uninstall_url},
- {NULL, NULL},
};
-char *
+void
ephy_web_extension_api_runtime_handler (EphyWebExtension *self,
char *name,
- JSCValue *args)
+ JSCValue *args,
+ GTask *task)
{
+ g_autoptr (GError) error = NULL;
guint idx;
for (idx = 0; idx < G_N_ELEMENTS (runtime_handlers); idx++) {
- EphyWebExtensionApiHandler handler = runtime_handlers[idx];
+ EphyWebExtensionSyncApiHandler handler = runtime_handlers[idx];
+ char *ret;
- if (g_strcmp0 (handler.name, name) == 0)
- return handler.execute (self, name, args);
+ if (g_strcmp0 (handler.name, name) == 0) {
+ ret = handler.execute (self, name, args, &error);
+
+ if (error)
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_pointer (task, ret, g_free);
+
+ return;
+ }
}
g_warning ("%s(): '%s' not implemented by Epiphany!", __FUNCTION__, name);
-
- return NULL;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Not Implemented");
+ g_task_return_error (task, g_steal_pointer (&error));
}
diff --git a/src/webextension/api/runtime.h b/src/webextension/api/runtime.h
index 207901700..ed90dfb77 100644
--- a/src/webextension/api/runtime.h
+++ b/src/webextension/api/runtime.h
@@ -25,8 +25,9 @@
G_BEGIN_DECLS
-char *ephy_web_extension_api_runtime_handler (EphyWebExtension *self,
- char *name,
- JSCValue *args);
+void ephy_web_extension_api_runtime_handler (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GTask *task);
G_END_DECLS
diff --git a/src/webextension/api/storage.c b/src/webextension/api/storage.c
index 9f048b1df..c4da61a28 100644
--- a/src/webextension/api/storage.c
+++ b/src/webextension/api/storage.c
@@ -58,17 +58,20 @@ strv_from_value (JSCValue *array)
}
static char *
-storage_handler_local_set (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+storage_handler_local_set (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
JsonNode *local_storage = ephy_web_extension_get_local_storage (self);
JsonObject *local_storage_obj = json_node_get_object (local_storage);
g_auto (GStrv) keys = NULL;
g_autoptr (JSCValue) value = jsc_value_object_get_property_at_index (args, 0);
- if (!jsc_value_is_object (value))
+ if (!jsc_value_is_object (value)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
keys = jsc_value_object_enumerate_properties (value);
@@ -83,9 +86,10 @@ storage_handler_local_set (EphyWebExtension *self,
}
static char *
-storage_handler_local_get (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+storage_handler_local_get (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
JsonNode *local_storage = ephy_web_extension_get_local_storage (self);
JsonObject *local_storage_obj = json_node_get_object (local_storage);
@@ -143,9 +147,10 @@ end_get:
}
static char *
-storage_handler_local_remove (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+storage_handler_local_remove (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
JsonNode *local_storage = ephy_web_extension_get_local_storage (self);
JsonObject *local_storage_obj = json_node_get_object (local_storage);
@@ -171,42 +176,56 @@ end_remove:
}
static char *
-storage_handler_local_clear (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+storage_handler_local_clear (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
ephy_web_extension_clear_local_storage (self);
ephy_web_extension_save_local_storage (self);
return NULL;
}
-static EphyWebExtensionApiHandler storage_handlers[] = {
+static EphyWebExtensionSyncApiHandler storage_handlers[] = {
{"local.set", storage_handler_local_set},
{"local.get", storage_handler_local_get},
{"local.remove", storage_handler_local_remove},
{"local.clear", storage_handler_local_clear},
};
-char *
+void
ephy_web_extension_api_storage_handler (EphyWebExtension *self,
char *name,
- JSCValue *args)
+ JSCValue *args,
+ GTask *task)
{
+ g_autoptr (GError) error = NULL;
guint idx;
if (!ephy_web_extension_has_permission (self, "storage")) {
g_warning ("Extension %s tried to use storage without permission.", ephy_web_extension_get_name (self));
- return NULL;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "Permission Denied");
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
}
for (idx = 0; idx < G_N_ELEMENTS (storage_handlers); idx++) {
- EphyWebExtensionApiHandler handler = storage_handlers[idx];
+ EphyWebExtensionSyncApiHandler handler = storage_handlers[idx];
+ char *ret;
+
+ if (g_strcmp0 (handler.name, name) == 0) {
+ ret = handler.execute (self, name, args, &error);
+
+ if (error)
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_pointer (task, ret, g_free);
- if (g_strcmp0 (handler.name, name) == 0)
- return handler.execute (self, name, args);
+ return;
+ }
}
g_warning ("%s(): '%s' not implemented by Epiphany!", __FUNCTION__, name);
-
- return NULL;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Not Implemented");
+ g_task_return_error (task, g_steal_pointer (&error));
}
diff --git a/src/webextension/api/storage.h b/src/webextension/api/storage.h
index 18ff87de9..a7bcbab0e 100644
--- a/src/webextension/api/storage.h
+++ b/src/webextension/api/storage.h
@@ -28,8 +28,9 @@
G_BEGIN_DECLS
-char *ephy_web_extension_api_storage_handler (EphyWebExtension *self,
- char *name,
- JSCValue *value);
+void ephy_web_extension_api_storage_handler (EphyWebExtension *self,
+ char *name,
+ JSCValue *value,
+ GTask *task);
G_END_DECLS
diff --git a/src/webextension/api/tabs.c b/src/webextension/api/tabs.c
index 66d264319..053a87a8d 100644
--- a/src/webextension/api/tabs.c
+++ b/src/webextension/api/tabs.c
@@ -147,9 +147,10 @@ get_number_property (JSCValue *args,
}
static char *
-tabs_handler_query (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+tabs_handler_query (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
g_autoptr (JsonBuilder) builder = json_builder_new ();
g_autoptr (JsonNode) root = NULL;
@@ -223,9 +224,10 @@ tabs_handler_query (EphyWebExtension *self,
}
static char *
-tabs_handler_insert_css (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+tabs_handler_insert_css (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
EphyShell *shell = ephy_shell_get_default ();
WebKitUserContentManager *ucm;
@@ -244,19 +246,25 @@ tabs_handler_insert_css (EphyWebExtension *self,
obj = g_steal_pointer (&tab_id_value);
}
- if (!jsc_value_is_object (obj))
+ if (!jsc_value_is_object (obj)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
if (!tab_id_value)
target_web_view = WEBKIT_WEB_VIEW (ephy_shell_get_active_web_view (shell));
else
target_web_view = get_web_view_for_tab_id (shell, jsc_value_to_int32 (tab_id_value), NULL);
- if (!target_web_view)
+ if (!target_web_view) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
- if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE))
+ if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "Permission Denied");
return NULL;
+ }
ucm = webkit_web_view_get_user_content_manager (target_web_view);
@@ -270,9 +278,10 @@ tabs_handler_insert_css (EphyWebExtension *self,
}
static char *
-tabs_handler_remove_css (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+tabs_handler_remove_css (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
EphyShell *shell = ephy_shell_get_default ();
JSCValue *code;
@@ -291,19 +300,25 @@ tabs_handler_remove_css (EphyWebExtension *self,
obj = g_steal_pointer (&tab_id_value);
}
- if (!jsc_value_is_object (obj))
+ if (!jsc_value_is_object (obj)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
if (!tab_id_value)
target_web_view = WEBKIT_WEB_VIEW (ephy_shell_get_active_web_view (shell));
else
target_web_view = get_web_view_for_tab_id (shell, jsc_value_to_int32 (tab_id_value), NULL);
- if (!target_web_view)
+ if (!target_web_view) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
- if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE))
+ if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "Permission Denied");
return NULL;
+ }
ucm = webkit_web_view_get_user_content_manager (target_web_view);
@@ -316,9 +331,10 @@ tabs_handler_remove_css (EphyWebExtension *self,
}
static char *
-tabs_handler_get (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+tabs_handler_get (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
EphyShell *shell = ephy_shell_get_default ();
g_autoptr (JsonBuilder) builder = json_builder_new ();
@@ -328,12 +344,16 @@ tabs_handler_get (EphyWebExtension *self,
EphyWindow *parent_window;
tab_id_value = jsc_value_object_get_property_at_index (args, 0);
- if (!jsc_value_is_number (tab_id_value))
+ if (!jsc_value_is_number (tab_id_value)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
target_web_view = EPHY_WEB_VIEW (get_web_view_for_tab_id (shell, jsc_value_to_int32 (args),
&parent_window));
- if (!target_web_view)
+ if (!target_web_view) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
add_web_view_to_json (builder, parent_window, target_web_view,
ephy_web_extension_has_tab_or_host_permission (self, target_web_view, TRUE));
@@ -343,9 +363,10 @@ tabs_handler_get (EphyWebExtension *self,
}
static char *
-tabs_handler_execute_script (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+tabs_handler_execute_script (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
g_autoptr (JSCValue) code_value = NULL;
g_autoptr (JSCValue) file_value = NULL;
@@ -364,8 +385,10 @@ tabs_handler_execute_script (EphyWebExtension *self,
obj = g_steal_pointer (&tab_id_value);
}
- if (!jsc_value_is_object (obj))
+ if (!jsc_value_is_object (obj)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
file_value = jsc_value_object_get_property (obj, "file");
code_value = jsc_value_object_get_property (obj, "code");
@@ -376,7 +399,7 @@ tabs_handler_execute_script (EphyWebExtension *self,
g_autofree char *resource_path = jsc_value_to_string (file_value);
code = ephy_web_extension_get_resource_as_string (self, resource_path[0] == '/' ? resource_path + 1 :
resource_path);
} else {
- g_warning ("tabs.executeScript called without usable code");
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
}
@@ -386,8 +409,10 @@ tabs_handler_execute_script (EphyWebExtension *self,
target_web_view = get_web_view_for_tab_id (shell, jsc_value_to_int32 (tab_id_value), NULL);
if (code && target_web_view) {
- if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE))
+ if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "Permission Denied");
return NULL;
+ }
webkit_web_view_run_javascript_in_world (target_web_view,
code,
@@ -401,9 +426,10 @@ tabs_handler_execute_script (EphyWebExtension *self,
}
static char *
-tabs_handler_send_message (EphyWebExtension *self,
- char *name,
- JSCValue *args)
+tabs_handler_send_message (EphyWebExtension *self,
+ char *name,
+ JSCValue *args,
+ GError **error)
{
g_autoptr (JSCValue) tab_id_value = NULL;
g_autoptr (JSCValue) message_value = NULL;
@@ -413,12 +439,16 @@ tabs_handler_send_message (EphyWebExtension *self,
WebKitWebView *target_web_view;
tab_id_value = jsc_value_object_get_property_at_index (args, 0);
- if (!jsc_value_is_number (tab_id_value))
+ if (!jsc_value_is_number (tab_id_value)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
message_value = jsc_value_object_get_property_at_index (args, 1);
- if (jsc_value_is_undefined (message_value))
+ if (jsc_value_is_undefined (message_value)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid Arguments");
return NULL;
+ }
serialized_message = jsc_value_to_json (message_value, 0);
code = g_strdup_printf ("window.browser.runtime.onMessage._emit(JSON.parse('%s'));", serialized_message);
@@ -426,8 +456,10 @@ tabs_handler_send_message (EphyWebExtension *self,
target_web_view = get_web_view_for_tab_id (shell, jsc_value_to_int32 (tab_id_value), NULL);
if (target_web_view) {
- if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE))
+ if (!ephy_web_extension_has_host_permission (self, EPHY_WEB_VIEW (target_web_view), TRUE)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "Permission Denied");
return NULL;
+ }
webkit_web_view_run_javascript_in_world (target_web_view,
code,
@@ -441,31 +473,41 @@ tabs_handler_send_message (EphyWebExtension *self,
return NULL;
}
-static EphyWebExtensionApiHandler tabs_handlers[] = {
+static EphyWebExtensionSyncApiHandler tabs_handlers[] = {
{"query", tabs_handler_query},
{"insertCSS", tabs_handler_insert_css},
{"removeCSS", tabs_handler_remove_css},
{"get", tabs_handler_get},
{"executeScript", tabs_handler_execute_script},
{"sendMessage", tabs_handler_send_message},
- {NULL, NULL},
};
-char *
+void
ephy_web_extension_api_tabs_handler (EphyWebExtension *self,
char *name,
- JSCValue *args)
+ JSCValue *args,
+ GTask *task)
{
+ g_autoptr (GError) error = NULL;
guint idx;
for (idx = 0; idx < G_N_ELEMENTS (tabs_handlers); idx++) {
- EphyWebExtensionApiHandler handler = tabs_handlers[idx];
+ EphyWebExtensionSyncApiHandler handler = tabs_handlers[idx];
+ char *ret;
+
+ if (g_strcmp0 (handler.name, name) == 0) {
+ ret = handler.execute (self, name, args, &error);
- if (g_strcmp0 (handler.name, name) == 0)
- return handler.execute (self, name, args);
+ if (error)
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_pointer (task, ret, g_free);
+
+ return;
+ }
}
g_warning ("%s(): '%s' not implemented by Epiphany!", __FUNCTION__, name);
-
- return NULL;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Not Implemented");
+ g_task_return_error (task, g_steal_pointer (&error));
}
diff --git a/src/webextension/api/tabs.h b/src/webextension/api/tabs.h
index 92ba490cc..d9a85049f 100644
--- a/src/webextension/api/tabs.h
+++ b/src/webextension/api/tabs.h
@@ -27,8 +27,9 @@
G_BEGIN_DECLS
-char *ephy_web_extension_api_tabs_handler (EphyWebExtension *self,
- char *name,
- JSCValue *value);
+void ephy_web_extension_api_tabs_handler (EphyWebExtension *self,
+ char *name,
+ JSCValue *value,
+ GTask *task);
G_END_DECLS
diff --git a/src/webextension/ephy-web-extension-manager.c b/src/webextension/ephy-web-extension-manager.c
index 703fc004c..c08f6e996 100644
--- a/src/webextension/ephy-web-extension-manager.c
+++ b/src/webextension/ephy-web-extension-manager.c
@@ -55,7 +55,7 @@ struct _EphyWebExtensionManager {
G_DEFINE_TYPE (EphyWebExtensionManager, ephy_web_extension_manager, G_TYPE_OBJECT)
-EphyWebExtensionApiHandler api_handlers[] = {
+EphyWebExtensionAsyncApiHandler api_handlers[] = {
{"notifications", ephy_web_extension_api_notifications_handler},
{"pageAction", ephy_web_extension_api_pageaction_handler},
{"runtime", ephy_web_extension_api_runtime_handler},
@@ -446,6 +446,50 @@ respond_with_error (WebKitUserMessage *message,
webkit_user_message_send_reply (message, reply);
}
+typedef struct {
+ WebKitUserMessage *message;
+ JSCValue *args;
+} ApiHandlerData;
+
+static void
+api_handler_data_free (ApiHandlerData *data)
+{
+ g_object_unref (data->message);
+ g_object_unref (data->args);
+ g_free (data);
+}
+
+static ApiHandlerData *
+api_handler_data_new (WebKitUserMessage *message,
+ JSCValue *args)
+{
+ ApiHandlerData *data = g_new (ApiHandlerData, 1);
+ data->message = g_object_ref (message);
+ data->args = g_object_ref (args);
+ return data;
+}
+
+static void
+on_web_extension_api_handler_finish (EphyWebExtension *web_extension,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ g_autoptr (GError) error = NULL;
+ GTask *task = G_TASK (result);
+ ApiHandlerData *data = g_task_get_task_data (task);
+ g_autofree char *json = g_task_propagate_pointer (task, &error);
+ WebKitUserMessage *reply;
+
+ if (error) {
+ respond_with_error (data->message, error->message);
+ } else {
+ reply = webkit_user_message_new ("", g_variant_new_string (json ? json : ""));
+ webkit_user_message_send_reply (data->message, reply);
+ }
+
+ g_object_unref (task);
+}
+
static gboolean
ephy_web_extension_handle_user_message (WebKitWebContext *context,
WebKitUserMessage *message,
@@ -457,8 +501,6 @@ ephy_web_extension_handle_user_message (WebKitWebContext *context,
const char *name = webkit_user_message_get_name (message);
g_auto (GStrv) split = NULL;
-
-
js_context = jsc_context_new ();
args = jsc_value_new_from_json (js_context, g_variant_get_string (webkit_user_message_get_parameters
(message), NULL));
@@ -471,21 +513,14 @@ ephy_web_extension_handle_user_message (WebKitWebContext *context,
}
for (guint idx = 0; idx < G_N_ELEMENTS (api_handlers); idx++) {
- EphyWebExtensionApiHandler handler = api_handlers[idx];
+ EphyWebExtensionAsyncApiHandler handler = api_handlers[idx];
if (g_strcmp0 (handler.name, split[0]) == 0) {
- g_autofree char *ret = NULL;
- g_autofree char *script = NULL;
- WebKitUserMessage *reply;
-
- ret = handler.execute (web_extension, split[1], args);
- if (ret) {
- reply = webkit_user_message_new ("", g_variant_new_take_string (g_steal_pointer (&ret)));
- } else {
- reply = webkit_user_message_new ("", g_variant_new_string (""));
- }
+ /* TODO: Cancellable */
+ GTask *task = g_task_new (web_extension, NULL,
(GAsyncReadyCallback)on_web_extension_api_handler_finish, NULL);
+ g_task_set_task_data (task, api_handler_data_new (message, args),
(GDestroyNotify)api_handler_data_free);
- webkit_user_message_send_reply (message, reply);
+ handler.execute (web_extension, split[1], args, task);
return TRUE;
}
}
diff --git a/src/webextension/ephy-web-extension.h b/src/webextension/ephy-web-extension.h
index 625488c16..9cd9e64fc 100644
--- a/src/webextension/ephy-web-extension.h
+++ b/src/webextension/ephy-web-extension.h
@@ -35,14 +35,25 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (EphyWebExtension, ephy_web_extension, EPHY, WEB_EXTENSION, GObject)
-typedef char *(*executeHandler)(EphyWebExtension *web_extension,
- char *name,
- JSCValue *args);
+typedef void (*executeTaskHandler)(EphyWebExtension *web_extension,
+ char *name,
+ JSCValue *args,
+ GTask *task);
+
+typedef char *(*executeHandler)(EphyWebExtension *web_extension,
+ char *name,
+ JSCValue *args,
+ GError **error);
+
+typedef struct {
+ char *name;
+ executeTaskHandler execute;
+} EphyWebExtensionAsyncApiHandler;
typedef struct {
char *name;
executeHandler execute;
-} EphyWebExtensionApiHandler;
+} EphyWebExtensionSyncApiHandler;
GdkPixbuf *ephy_web_extension_get_icon (EphyWebExtension *self,
gint64 size);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]