[epiphany/pgriffis/web-extension/commands: 2/5] WebExtensions: Provide Commands APIs
- From: Patrick Griffis <pgriffis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/pgriffis/web-extension/commands: 2/5] WebExtensions: Provide Commands APIs
- Date: Thu, 7 Jul 2022 01:13:38 +0000 (UTC)
commit f543c8652a5b8a035a219c5009c058e28a6cf9b4
Author: Jamie Murphy <hello itsjamie dev>
Date: Mon Jul 4 11:36:28 2022 -0700
WebExtensions: Provide Commands APIs
src/webextension/api/commands.c | 212 +++++++++++++++++++++++++-
src/webextension/ephy-web-extension-manager.c | 2 -
src/webextension/ephy-web-extension.c | 22 +++
src/webextension/ephy-web-extension.h | 6 +
4 files changed, 238 insertions(+), 4 deletions(-)
---
diff --git a/src/webextension/api/commands.c b/src/webextension/api/commands.c
index b8e2c87cc..a9b329d04 100644
--- a/src/webextension/api/commands.c
+++ b/src/webextension/api/commands.c
@@ -19,9 +19,143 @@
#include "config.h"
+#include "ephy-shell.h"
+
#include "api-utils.h"
#include "commands.h"
+/* Local command struct. */
+typedef struct {
+ EphyWebExtension *web_extension; /* Parent object */
+ char *name;
+ char *accelerator;
+ char *description;
+} Command;
+
+static void
+command_destroy (Command *cmd)
+{
+ //g_clear_pointer (&cmd->name);
+ g_free (cmd);
+}
+
+static void
+on_command_activated (GAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ EphyWebExtensionManager *manager = ephy_web_extension_manager_get_default ();
+ Command *cmd = user_data;
+ JsonNode *node;
+ node = json_node_init_string (json_node_alloc (), cmd->name);
+
+ ephy_web_extension_manager_emit_in_extension_views (manager,
+ cmd->web_extension,
+ "commands.onCommand",
+ json_to_string (node, FALSE));
+}
+
+static void
+setup_actions (Command *cmd)
+{
+ GSimpleAction *action = g_simple_action_new (cmd->name, NULL);
+ g_signal_connect (action, "activate", G_CALLBACK (on_command_activated), cmd);
+ g_action_map_add_action (G_ACTION_MAP (ephy_shell_get_default ()), (GAction *) action);
+ gtk_application_set_accels_for_action (GTK_APPLICATION (ephy_shell_get_default ()),
+ g_strdup_printf ("app.%s", cmd->name),
+ (const char *[]) {
+ cmd->accelerator,
+ NULL,
+ });
+}
+
+static Command *
+create_command (EphyWebExtension *self,
+ guint cmd)
+{
+ char * shortcut;
+ char * suggested_key;
+ char * description;
+ Command *command = g_new0 (Command, 1);
+
+ ephy_web_extension_get_command_data_from_index (self,
+ cmd,
+ &shortcut,
+ &suggested_key,
+ &description);
+
+ command->web_extension = self;
+ command->name = g_strdup(shortcut);
+ command->accelerator = g_strdup(suggested_key);
+ command->description = g_strdup(description);
+
+ setup_actions (command);
+
+ return command;
+}
+
+static GHashTable *
+get_commands (EphyWebExtension *self)
+{
+ GList *commands = ephy_web_extension_get_commands (self);
+ Command *cmd = NULL;
+
+ GHashTable *cmds = g_object_get_data (G_OBJECT (self), "commands");
+ if (cmds)
+ return cmds;
+
+ cmds = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)command_destroy);
+ g_object_set_data_full (G_OBJECT (self), "commands", cmds, (GDestroyNotify)g_hash_table_destroy);
+
+ for (GList *list = commands; list && list->data; list = list->next) {
+ cmd = create_command (self, g_list_index (list, list->data));
+
+ g_hash_table_replace (cmds, cmd->name, cmd);
+ }
+ return cmds;
+}
+
+static JsonNode *
+command_to_node (Command *cmd)
+{
+ JsonNode *node;
+ JsonObject *obj;
+
+ if (!cmd)
+ return NULL;
+
+ node = json_node_init_object (json_node_alloc (), json_object_new ());
+ obj = json_node_get_object (node);
+ json_object_set_string_member (obj, "name", cmd->name);
+ json_object_set_string_member (obj, "shortcut", cmd->accelerator);
+ json_object_set_string_member (obj, "description", cmd->description);
+
+ return node;
+}
+
+char *
+create_accelerator (char *orig_string)
+{
+ char ** accelerator_keys = NULL;
+ char * accelerator = "";
+
+ if (strchr(orig_string, '<') != NULL || strchr (orig_string, '>') != NULL)
+ return orig_string;
+
+ accelerator_keys = g_strsplit((const gchar *) orig_string, "+", 0);
+
+ for (int i = 0; accelerator_keys[i]; i++) {
+ // We have to use 2 here, as F# keys are treated like normal keys.
+ if (strlen (accelerator_keys[i]) > 3) {
+ accelerator = g_strdup_printf ("%s<%s>", accelerator, accelerator_keys[i]);
+ } else {
+ accelerator = g_strdup_printf ("%s%s", accelerator, accelerator_keys[i]);
+ }
+ }
+
+ return accelerator;
+}
+
static char *
commands_handler_get_all (EphyWebExtension *self,
char *name,
@@ -29,7 +163,17 @@ commands_handler_get_all (EphyWebExtension *self,
WebKitWebView *web_view,
GError **error)
{
- return NULL;
+ GHashTable *commands = get_commands (self);
+ g_autoptr (JsonNode) node = json_node_init_array (json_node_alloc (), json_array_new ());
+ JsonArray *rel = json_node_get_array (node);
+ GHashTableIter iter;
+ Command *cmd;
+
+ g_hash_table_iter_init (&iter, commands);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&cmd))
+ json_array_add_element (rel, command_to_node (cmd));
+
+ return json_to_string (node, FALSE);
}
static char *
@@ -39,6 +183,32 @@ commands_handler_reset (EphyWebExtension *self,
WebKitWebView *web_view,
GError **error)
{
+ GHashTable *commands = get_commands (self);
+ g_autoptr (JSCValue) name_value = jsc_value_object_get_property_at_index (args, 0);
+ g_autofree char *name_str = NULL;
+ Command *cmd = NULL;
+ char * shortcut;
+ char * suggested_key;
+ char * description;
+
+ if (!jsc_value_is_string (name_value))
+ name_str = g_strdup ("");
+ else
+ name_str = jsc_value_to_string (name_value);
+
+ if (g_hash_table_lookup (commands, name_str)) {
+ cmd = g_hash_table_lookup (commands, name_str);
+ ephy_web_extension_get_command_data_from_name (self,
+ name_str,
+ &shortcut,
+ &suggested_key,
+ &description);
+
+ cmd->name = g_strdup(shortcut);
+ cmd->accelerator = g_strdup(suggested_key);
+ cmd->description = g_strdup(description);
+ }
+
return NULL;
}
@@ -49,6 +219,44 @@ commands_handler_update (EphyWebExtension *self,
WebKitWebView *web_view,
GError **error)
{
+ GHashTable *commands = get_commands (self);
+ g_autoptr (JSCValue) obj = jsc_value_object_get_property_at_index (args, 0);
+ Command *cmd = NULL;
+ g_autofree char *name_str = NULL;
+ g_autofree char *desc_str = NULL;
+ g_autofree char *shortcut_str = NULL;
+
+ if (!jsc_value_is_object (obj))
+ return NULL;
+ else {
+ if (!jsc_value_object_has_property (obj, "name"))
+ return NULL;
+ else
+ name_str = jsc_value_to_string (jsc_value_object_get_property (obj, "name"));
+
+ if (jsc_value_object_has_property (obj, "description"))
+ desc_str = jsc_value_to_string (jsc_value_object_get_property (obj, "description"));
+
+ if (jsc_value_object_has_property (obj, "shortcut")) {
+ shortcut_str = jsc_value_to_string (jsc_value_object_get_property (obj, "shortcut"));
+ shortcut_str = create_accelerator (shortcut_str);
+ }
+ }
+
+ if (g_hash_table_lookup (commands, name_str)) {
+ cmd = g_hash_table_lookup (commands, name_str);
+ cmd->name = g_strdup(name_str);
+ cmd->accelerator = g_strdup(shortcut_str);
+ cmd->description = g_strdup(desc_str);
+ }
+
+ gtk_application_set_accels_for_action (GTK_APPLICATION (ephy_shell_get_default ()),
+ g_strdup_printf ("app.%s", cmd->name),
+ (const char *[]) {
+ cmd->accelerator,
+ NULL,
+ });
+
return NULL;
}
@@ -86,4 +294,4 @@ ephy_web_extension_api_commands_handler (EphyWebExtension *self,
g_warning ("%s(): '%s' not implemented by Epiphany!", __FUNCTION__, name);
error = g_error_new_literal (WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_NOT_IMPLEMENTED, "Not Implemented");
g_task_return_error (task, g_steal_pointer (&error));
-}
\ No newline at end of file
+}
diff --git a/src/webextension/ephy-web-extension-manager.c b/src/webextension/ephy-web-extension-manager.c
index ef26374d1..40ded52c9 100644
--- a/src/webextension/ephy-web-extension-manager.c
+++ b/src/webextension/ephy-web-extension-manager.c
@@ -671,8 +671,6 @@ extension_view_handle_user_message (WebKitWebView *web_view,
for (guint idx = 0; idx < G_N_ELEMENTS (api_handlers); idx++) {
EphyWebExtensionApiHandler handler = api_handlers[idx];
- g_warning ("%s, %s", handler.name, split[0]);
-
if (g_strcmp0 (handler.name, split[0]) == 0) {
/* TODO: Cancellable */
GTask *task = g_task_new (web_extension, NULL,
(GAsyncReadyCallback)on_web_extension_api_handler_finish, NULL);
diff --git a/src/webextension/ephy-web-extension.c b/src/webextension/ephy-web-extension.c
index ca1ae90b6..66210a8b6 100644
--- a/src/webextension/ephy-web-extension.c
+++ b/src/webextension/ephy-web-extension.c
@@ -848,6 +848,28 @@ ephy_web_extension_get_command_data_from_index (EphyWebExtension *self,
return NULL;
}
+void *
+ephy_web_extension_get_command_data_from_name (EphyWebExtension *self,
+ const char *name,
+ char** shortcut,
+ char** suggested_key,
+ char** description)
+{
+ WebExtensionCommand *cmd = NULL;
+
+ for (GList *list = self->commands; list && list->data; list = list->next) {
+ cmd = list->data;
+
+ if (strcmp (cmd->shortcut, name) == 0) {
+ *shortcut = strdup(cmd->shortcut);
+ *suggested_key = strdup(cmd->suggested_key);
+ *description = strdup(cmd->description);
+ }
+ }
+
+ return NULL;
+}
+
GList *
ephy_web_extension_get_commands (EphyWebExtension *self)
{
diff --git a/src/webextension/ephy-web-extension.h b/src/webextension/ephy-web-extension.h
index 5d34a0226..7b280fa8b 100644
--- a/src/webextension/ephy-web-extension.h
+++ b/src/webextension/ephy-web-extension.h
@@ -156,6 +156,12 @@ void *ephy_web_extension_get_command_data_from_index (EphyW
char
**suggested_key,
char **description);
+void *ephy_web_extension_get_command_data_from_name (EphyWebExtension *self,
+ const char *name,
+ char **shortcut,
+ char
**suggested_key,
+ char **description);
+
gboolean ephy_web_extension_has_tab_or_host_permission (EphyWebExtension *self,
EphyWebView *web_view,
gboolean
is_user_interaction);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]