[epiphany/pgriffis/web-extension/commands: 1/5] WebExtensions: Add Commands parsing




commit 11e7efb3fc27222f3b9b1ede7e5cf0f9e5f5ce72
Author: Jamie Murphy <hello jamiethalacker dev>
Date:   Thu Jun 30 19:50:33 2022 -0700

    WebExtensions: Add Commands parsing

 .../resources/js/webextensions.js                  |   7 ++
 src/webextension/api/commands.c                    |  89 ++++++++++++++++
 src/webextension/api/commands.h                    |  36 +++++++
 src/webextension/ephy-web-extension-manager.c      |   4 +
 src/webextension/ephy-web-extension.c              | 115 +++++++++++++++++++++
 src/webextension/ephy-web-extension.h              |   8 ++
 src/webextension/meson.build                       |   1 +
 7 files changed, 260 insertions(+)
---
diff --git a/embed/web-process-extension/resources/js/webextensions.js 
b/embed/web-process-extension/resources/js/webextensions.js
index de6454ab6..b63bb1078 100644
--- a/embed/web-process-extension/resources/js/webextensions.js
+++ b/embed/web-process-extension/resources/js/webextensions.js
@@ -13,6 +13,13 @@ window.browser.alarms = {
     onAlarm: new EphyEventListener (),
 };
 
+window.browser.commands = {
+    getAll: function (...args) { return ephy_message ('commands.getAll', args); },
+    reset: function (...args) { return ephy_message ('commands.reset', args); },
+    update: function (...args) { return ephy_message ('commands.update', args); },
+    onCommand: new EphyEventListener (),
+};
+
 window.browser.windows = {
     onRemoved: new EphyEventListener (),
 };
diff --git a/src/webextension/api/commands.c b/src/webextension/api/commands.c
new file mode 100644
index 000000000..b8e2c87cc
--- /dev/null
+++ b/src/webextension/api/commands.c
@@ -0,0 +1,89 @@
+/*
+ *  Copyright © 2022 Igalia S.L.
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "api-utils.h"
+#include "commands.h"
+
+static char *
+commands_handler_get_all (EphyWebExtension *self,
+                          char             *name,
+                          JSCValue         *args,
+                          WebKitWebView    *web_view,
+                          GError          **error)
+{
+  return NULL;
+}
+
+static char *
+commands_handler_reset (EphyWebExtension *self,
+                        char             *name,
+                        JSCValue         *args,
+                        WebKitWebView    *web_view,
+                        GError          **error)
+{
+  return NULL;
+}
+
+static char *
+commands_handler_update (EphyWebExtension *self,
+                         char             *name,
+                         JSCValue         *args,
+                         WebKitWebView    *web_view,
+                         GError          **error)
+{
+  return NULL;
+}
+
+static EphyWebExtensionSyncApiHandler commands_handlers[] = {
+  {"getAll", commands_handler_get_all},
+  {"reset", commands_handler_reset},
+  {"update", commands_handler_update}
+};
+
+void
+ephy_web_extension_api_commands_handler (EphyWebExtension *self,
+                                         char             *name,
+                                         JSCValue         *args,
+                                         WebKitWebView    *web_view,
+                                         GTask            *task)
+{
+  g_autoptr (GError) error = NULL;
+
+  for (guint idx = 0; idx < G_N_ELEMENTS (commands_handlers); idx++) {
+    EphyWebExtensionSyncApiHandler handler = commands_handlers[idx];
+    char *ret;
+
+    if (g_strcmp0 (handler.name, name) == 0) {
+      ret = handler.execute (self, name, args, web_view, &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);
+  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/api/commands.h b/src/webextension/api/commands.h
new file mode 100644
index 000000000..0cb315883
--- /dev/null
+++ b/src/webextension/api/commands.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2022 Igalia S.L.
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+#include "ephy-web-extension.h"
+
+#include <webkit2/webkit2.h>
+
+G_BEGIN_DECLS
+
+void ephy_web_extension_api_commands_handler (EphyWebExtension *self,
+                                              char            *name,
+                                              JSCValue        *value,
+                                              WebKitWebView   *web_view,
+                                              GTask           *task);
+
+G_END_DECLS
diff --git a/src/webextension/ephy-web-extension-manager.c b/src/webextension/ephy-web-extension-manager.c
index 4ca8033d2..ef26374d1 100644
--- a/src/webextension/ephy-web-extension-manager.c
+++ b/src/webextension/ephy-web-extension-manager.c
@@ -36,6 +36,7 @@
 #include "ephy-web-view.h"
 
 #include "api/alarms.h"
+#include "api/commands.h"
 #include "api/cookies.h"
 #include "api/downloads.h"
 #include "api/menus.h"
@@ -71,6 +72,7 @@ G_DEFINE_TYPE (EphyWebExtensionManager, ephy_web_extension_manager, G_TYPE_OBJEC
 
 EphyWebExtensionApiHandler api_handlers[] = {
   {"alarms", ephy_web_extension_api_alarms_handler},
+  {"commands", ephy_web_extension_api_commands_handler},
   {"cookies", ephy_web_extension_api_cookies_handler},
   {"downloads", ephy_web_extension_api_downloads_handler},
   {"menus", ephy_web_extension_api_menus_handler},
@@ -669,6 +671,8 @@ 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 9ddb28081..ca1ae90b6 100644
--- a/src/webextension/ephy-web-extension.c
+++ b/src/webextension/ephy-web-extension.c
@@ -75,6 +75,12 @@ typedef struct {
   WebKitUserStyleSheet *style;
 } WebExtensionCustomCSS;
 
+typedef struct {
+  char *shortcut;
+  char *suggested_key;
+  char *description;
+} WebExtensionCommand;
+
 struct _EphyWebExtension {
   GObject parent_instance;
 
@@ -105,6 +111,7 @@ struct _EphyWebExtension {
   char *local_storage_path;
   JsonNode *local_storage;
   GHashTable *web_accessible_resources;
+  GList *commands;
 };
 
 G_DEFINE_QUARK (web - extension - error - quark, web_extension_error)
@@ -752,6 +759,110 @@ web_extension_add_web_accessible_resource (JsonArray *array,
   g_hash_table_add (self->web_accessible_resources, g_strdup (web_accessible_resource));
 }
 
+char *
+ephy_web_extension_get_command_accelerator (JsonObject *suggested_key_object)
+{
+  const char * orig_string = NULL;
+  char ** accelerator_keys = NULL;
+  char * accelerator = "";
+
+  if (!ephy_json_object_get_string (suggested_key_object, "default") &&
+      !ephy_json_object_get_string (suggested_key_object, "linux"))
+    {
+      return NULL;
+    } else if (ephy_json_object_get_string (suggested_key_object, "default")) {
+      orig_string = ephy_json_object_get_string (suggested_key_object, "default");
+    } else if (ephy_json_object_get_string (suggested_key_object, "linux")) {
+      orig_string = ephy_json_object_get_string (suggested_key_object, "linux");
+    }
+
+    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]) > 2) {
+        accelerator = g_strdup_printf ("%s<%s>", accelerator, accelerator_keys[i]);
+      } else {
+        accelerator = g_strdup_printf ("%s%s", accelerator, accelerator_keys[i]);
+      }
+    }
+
+  return accelerator;
+}
+
+static void
+web_extension_parse_commands (EphyWebExtension *self,
+                              JsonObject       *object)
+{
+  JsonNode *node = NULL;
+  JsonObject *cmd_object = NULL;
+  JsonObject *key_object = NULL;
+  WebExtensionCommand *cmd = g_malloc0 (sizeof (WebExtensionCommand));
+  const char *description;
+  const char *shortcut;
+  const char *suggested_key;
+
+  for (GList *list = json_object_get_members (object); list && list->data; list = list->next) {
+    node = json_object_get_member (object, (gchar *) list->data);
+    cmd_object = ephy_json_node_get_object (node);
+    key_object = ephy_json_object_get_object (cmd_object, "suggested_key");
+
+    if (!cmd_object) {
+      LOG ("Skipping command as value is invalid");
+      return;
+    }
+
+    description = ephy_json_object_get_string (cmd_object, "description");
+
+    shortcut = (gchar *) list->data;
+    if (!shortcut) {
+      LOG ("Skipping command as value is invalid");
+      return;
+    }
+
+    cmd->description = g_strdup(description);
+    cmd->shortcut = g_strdup(shortcut);
+
+    suggested_key = ephy_web_extension_get_command_accelerator (key_object);
+
+    if (!g_strcmp0 (suggested_key, "") == 0)
+      cmd->suggested_key = g_strdup(suggested_key);
+
+    self->commands = g_list_append (self->commands, cmd);
+  }
+}
+
+void *
+ephy_web_extension_get_command_data_from_index (EphyWebExtension    *self,
+                                                guint                command,
+                                                char**               shortcut,
+                                                char**               suggested_key,
+                                                char**               description)
+{
+  WebExtensionCommand *cmd = g_list_nth_data (self->commands, command);
+
+  *shortcut =  strdup(cmd->shortcut);
+  *suggested_key = strdup(cmd->suggested_key);
+  *description = strdup(cmd->description);
+
+  return NULL;
+}
+
+GList *
+ephy_web_extension_get_commands (EphyWebExtension *self)
+{
+  return self->commands;
+}
+
+static void
+web_extension_commands_free (WebExtensionCommand *cmd)
+{
+  g_clear_pointer (&cmd->shortcut, g_free);
+  g_clear_pointer (&cmd->suggested_key, g_free);
+  g_clear_pointer (&cmd->description, g_free);
+  g_free (cmd);
+}
+
 static void
 ephy_web_extension_dispose (GObject *object)
 {
@@ -781,6 +892,7 @@ ephy_web_extension_dispose (GObject *object)
   g_clear_pointer (&self->page_action, web_extension_page_action_free);
   g_clear_pointer (&self->browser_action, web_extension_browser_action_free);
   g_clear_list (&self->custom_css, (GDestroyNotify)webkit_user_style_sheet_unref);
+  g_clear_list (&self->commands, (GDestroyNotify)web_extension_commands_free);
 
   g_hash_table_destroy (self->page_action_map);
 
@@ -906,6 +1018,9 @@ ephy_web_extension_parse_manifest (EphyWebExtension  *self,
   if ((child_array = ephy_json_object_get_array (root_object, "web_accessible_resources")))
     json_array_foreach_element (child_array, web_extension_add_web_accessible_resource, self);
 
+  if ((child_object = ephy_json_object_get_object (root_object, "commands")))
+    web_extension_parse_commands (self, child_object);
+
   return TRUE;
 }
 
diff --git a/src/webextension/ephy-web-extension.h b/src/webextension/ephy-web-extension.h
index 8fbd140bc..5d34a0226 100644
--- a/src/webextension/ephy-web-extension.h
+++ b/src/webextension/ephy-web-extension.h
@@ -148,6 +148,14 @@ const char            *ephy_web_extension_get_option_ui_page              (EphyW
 
 const char            *ephy_web_extension_get_guid                        (EphyWebExtension *self);
 
+GList                 *ephy_web_extension_get_commands                    (EphyWebExtension *self);
+
+void                  *ephy_web_extension_get_command_data_from_index     (EphyWebExtension    *self,
+                                                                           guint                command,
+                                                                           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);
diff --git a/src/webextension/meson.build b/src/webextension/meson.build
index 3d7fda2df..c4ad72c50 100644
--- a/src/webextension/meson.build
+++ b/src/webextension/meson.build
@@ -1,5 +1,6 @@
 ephywebextension_src = [
   'webextension/api/alarms.c',
+  'webextension/api/commands.c',
   'webextension/api/cookies.c',
   'webextension/api/downloads.c',
   'webextension/api/menus.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]