[epiphany/pgriffis/web-extension/windows: 2/9] WebExtensions: Implement windows.get()




commit 9273b92c621ae1e090b83034f70c0af453d0f6b4
Author: Patrick Griffis <pgriffis igalia com>
Date:   Tue Jun 7 14:40:11 2022 -0500

    WebExtensions: Implement windows.get()

 src/webextension/api/tabs.c                   |  39 +++---
 src/webextension/api/tabs.h                   |   8 +-
 src/webextension/api/windows.c                | 185 ++++++++++++++++++++++++++
 src/webextension/api/windows.h                |  35 +++++
 src/webextension/ephy-web-extension-manager.c |   3 +
 src/webextension/ephy-web-extension.c         |   2 +-
 src/webextension/meson.build                  |   1 +
 7 files changed, 255 insertions(+), 18 deletions(-)
---
diff --git a/src/webextension/api/tabs.c b/src/webextension/api/tabs.c
index d2db07fe9..e58c37159 100644
--- a/src/webextension/api/tabs.c
+++ b/src/webextension/api/tabs.c
@@ -67,16 +67,17 @@ get_web_view_for_tab_id (EphyShell   *shell,
 }
 
 static void
-add_web_view_to_json (JsonBuilder *builder,
-                      EphyWindow  *window,
-                      EphyWebView *web_view,
-                      gboolean     has_tab_permission)
+add_web_view_to_json (EphyWebExtension *self,
+                      JsonBuilder      *builder,
+                      EphyWindow       *window,
+                      EphyWebView      *web_view)
 {
   EphyTabView *tab_view = ephy_window_get_tab_view (window);
   GtkWidget *page = gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (web_view)));
   gboolean is_active = ephy_tab_view_get_current_page (tab_view) == page;
   WebKitFaviconDatabase *favicon_db = webkit_web_context_get_favicon_database (webkit_web_view_get_context 
(WEBKIT_WEB_VIEW (web_view)));
   const char *favicon_uri = webkit_favicon_database_get_favicon_uri (favicon_db, ephy_web_view_get_address 
(web_view));
+  gboolean has_tab_permission = ephy_web_extension_has_tab_or_host_permission (self, web_view, TRUE);
 
   json_builder_begin_object (builder);
   if (has_tab_permission) {
@@ -119,14 +120,24 @@ add_web_view_to_json (JsonBuilder *builder,
   json_builder_end_object (builder);
 }
 
+void
+ephy_web_extension_api_tabs_add_tab_to_json (EphyWebExtension *self,
+                                             JsonBuilder      *builder,
+                                             EphyWindow       *window,
+                                             EphyWebView      *web_view)
+{
+  add_web_view_to_json (self, builder, window, web_view);
+}
+
 JsonNode *
-ephy_web_extension_api_tabs_create_tab_object (EphyWebView *web_view)
+ephy_web_extension_api_tabs_create_tab_object (EphyWebExtension *self,
+                                               EphyWebView      *web_view)
 {
   g_autoptr (JsonBuilder) builder = json_builder_new ();
-  add_web_view_to_json (builder,
+  add_web_view_to_json (self,
+                        builder,
                         EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (web_view))),
-                        web_view,
-                        FALSE);
+                        web_view);
   return json_builder_get_root (builder);
 }
 
@@ -270,8 +281,7 @@ tabs_handler_query (EphyWebExtension  *self,
       else if (active == TAB_QUERY_DONT_MATCH && web_view == active_web_view)
         continue;
 
-      add_web_view_to_json (builder, window, web_view,
-                            ephy_web_extension_has_tab_or_host_permission (self, web_view, TRUE));
+      add_web_view_to_json (self, builder, window, web_view);
     }
   }
 
@@ -416,8 +426,7 @@ tabs_handler_get (EphyWebExtension  *self,
     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));
+  add_web_view_to_json (self, builder, parent_window, target_web_view);
   root = json_builder_get_root (builder);
 
   return json_to_string (root, FALSE);
@@ -647,8 +656,7 @@ tabs_handler_create (EphyWebExtension  *self,
     ephy_web_view_load_new_tab_page (new_web_view);
 
   builder = json_builder_new ();
-  add_web_view_to_json (builder, parent_window, new_web_view,
-                        ephy_web_extension_has_tab_or_host_permission (self, new_web_view, TRUE));
+  add_web_view_to_json (self, builder, parent_window, new_web_view);
   root = json_builder_get_root (builder);
   return json_to_string (root, FALSE);
 }
@@ -712,8 +720,7 @@ tabs_handler_update (EphyWebExtension  *self,
     webkit_web_view_load_uri (target_web_view, new_url);
 
   builder = json_builder_new ();
-  add_web_view_to_json (builder, parent_window, EPHY_WEB_VIEW (target_web_view),
-                        ephy_web_extension_has_tab_or_host_permission (self, EPHY_WEB_VIEW 
(target_web_view), TRUE));
+  add_web_view_to_json (self, builder, parent_window, EPHY_WEB_VIEW (target_web_view));
   root = json_builder_get_root (builder);
   return json_to_string (root, FALSE);
 }
diff --git a/src/webextension/api/tabs.h b/src/webextension/api/tabs.h
index a8d526100..ab9cc7d34 100644
--- a/src/webextension/api/tabs.h
+++ b/src/webextension/api/tabs.h
@@ -33,6 +33,12 @@ void ephy_web_extension_api_tabs_handler (EphyWebExtension *self,
                                           WebKitWebView    *web_view,
                                           GTask            *task);
 
-JsonNode *ephy_web_extension_api_tabs_create_tab_object (EphyWebView *web_view);
+JsonNode *ephy_web_extension_api_tabs_create_tab_object (EphyWebExtension *self,
+                                                         EphyWebView      *web_view);
+
+void      ephy_web_extension_api_tabs_add_tab_to_json   (EphyWebExtension *self,
+                                                         JsonBuilder      *builder,
+                                                         EphyWindow       *window,
+                                                         EphyWebView      *web_view);
 
 G_END_DECLS
diff --git a/src/webextension/api/windows.c b/src/webextension/api/windows.c
new file mode 100644
index 000000000..422de6213
--- /dev/null
+++ b/src/webextension/api/windows.c
@@ -0,0 +1,185 @@
+/*
+ *  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 "ephy-shell.h"
+
+#include "windows.h"
+#include "tabs.h"
+
+static EphyWindow *
+get_window_for_id (int window_id)
+{
+  GList *windows;
+
+  if (window_id < 0)
+    return NULL;
+
+  windows = gtk_application_get_windows (GTK_APPLICATION (ephy_shell_get_default ()));
+
+  for (GList *win_list = windows; win_list; win_list = g_list_next (win_list)) {
+    EphyWindow *window = EPHY_WINDOW (win_list->data);
+
+    if (ephy_window_get_uid (window) == (guint64)window_id)
+      return window;
+  }
+
+  g_debug ("Failed to find window with id %d", window_id);
+  return NULL;
+}
+
+static const char *
+get_window_state (EphyWindow *window)
+{
+  if (ephy_window_is_fullscreen (window))
+    return "fullscreen";
+  if (ephy_window_is_maximized (window))
+    return "maximized";
+  /* TODO: minimized */
+  return "normal";
+}
+
+static void
+add_tabs_to_json (EphyWebExtension *self,
+                  JsonBuilder      *builder,
+                  EphyWindow       *window)
+{
+  EphyTabView *tab_view = ephy_window_get_tab_view (window);
+
+  json_builder_begin_array (builder);
+
+  for (int i = 0; i < ephy_tab_view_get_n_pages (tab_view); i++) {
+    EphyWebView *web_view = ephy_embed_get_web_view (EPHY_EMBED (ephy_tab_view_get_nth_page (tab_view, i)));
+
+    ephy_web_extension_api_tabs_add_tab_to_json (self, builder, window, web_view);
+  }
+
+  json_builder_end_array (builder);
+}
+
+static void
+add_window_to_json (EphyWebExtension *self,
+                    JsonBuilder      *builder,
+                    EphyWindow       *window,
+                    gboolean          populate_tabs)
+{
+  gboolean is_focused = EPHY_WINDOW (gtk_application_get_active_window (GTK_APPLICATION 
(ephy_shell_get_default ()))) == window;
+  EphyTabView *tab_view = ephy_window_get_tab_view (window);
+  EphyEmbed *embed = EPHY_EMBED (ephy_tab_view_get_selected_page (tab_view));
+  EphyWebView *active_web_view = ephy_embed_get_web_view (embed);
+  gboolean has_tab_permission = ephy_web_extension_has_tab_or_host_permission (self, active_web_view, TRUE);
+
+  json_builder_begin_object (builder);
+  json_builder_set_member_name (builder, "id");
+  json_builder_add_int_value (builder, ephy_window_get_uid (window));
+  /* TODO: Get the Title if we have permissions for the active tab. */
+  json_builder_set_member_name (builder, "focused");
+  json_builder_add_boolean_value (builder, is_focused);
+  json_builder_set_member_name (builder, "alwaysOnTop");
+  json_builder_add_boolean_value (builder, FALSE); /* TODO: Do we have a way to figure this out? */
+  json_builder_set_member_name (builder, "type");
+  json_builder_add_string_value (builder, "normal"); /* We don't show any non-normal windows. */
+  json_builder_set_member_name (builder, "state");
+  json_builder_add_string_value (builder, get_window_state (window));
+  json_builder_set_member_name (builder, "incognito");
+  json_builder_add_boolean_value (builder, ephy_embed_shell_get_mode (ephy_embed_shell_get_default ()) == 
EPHY_EMBED_SHELL_MODE_INCOGNITO);
+  if (has_tab_permission) {
+    json_builder_set_member_name (builder, "title");
+    json_builder_add_string_value (builder, ephy_embed_get_title (embed));
+  }
+  if (populate_tabs) {
+    json_builder_set_member_name (builder, "tabs");
+    add_tabs_to_json (self, builder, window);
+  }
+  json_builder_end_object (builder);
+}
+
+static char *
+windows_handler_get (EphyWebExtension  *self,
+                     char              *name,
+                     JSCValue          *args,
+                     WebKitWebView     *web_view,
+                     GError           **error)
+{
+  g_autoptr (JSCValue) window_id_value = jsc_value_object_get_property_at_index (args, 0);
+  g_autoptr (JSCValue) get_info_value = jsc_value_object_get_property_at_index (args, 1);
+  g_autoptr (JsonBuilder) builder = json_builder_new ();
+  g_autoptr (JsonNode) root = NULL;
+  EphyWindow *window;
+  int window_id;
+  gboolean populate_tabs = FALSE;
+
+  if (!jsc_value_is_number (window_id_value)) {
+    g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, "window.get(): 
First argument is not a windowId");
+    return NULL;
+  }
+
+  window_id = jsc_value_to_int32 (window_id_value);
+  window = get_window_for_id (window_id);
+
+  if (!window) {
+    g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, "window.get(): 
Failed to find window by id");
+    return NULL;
+  }
+
+  if (jsc_value_is_object (get_info_value)) {
+    g_autoptr (JSCValue) populate = jsc_value_object_get_property (get_info_value, "populate");
+    populate_tabs = jsc_value_to_boolean (populate);
+  }
+
+  add_window_to_json (self, builder, window, populate_tabs);
+  root = json_builder_get_root (builder);
+  return json_to_string (root, FALSE);
+}
+
+static EphyWebExtensionSyncApiHandler windows_handlers[] = {
+  {"get", windows_handler_get},
+};
+
+void
+ephy_web_extension_api_windows_handler (EphyWebExtension *self,
+                                              char             *name,
+                                              JSCValue         *args,
+                                              WebKitWebView    *web_view,
+                                              GTask            *task)
+{
+  g_autoptr (GError) error = NULL;
+  guint idx;
+
+  for (idx = 0; idx < G_N_ELEMENTS (windows_handlers); idx++) {
+    EphyWebExtensionSyncApiHandler handler = windows_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));
+}
diff --git a/src/webextension/api/windows.h b/src/webextension/api/windows.h
new file mode 100644
index 000000000..e1dcbee54
--- /dev/null
+++ b/src/webextension/api/windows.h
@@ -0,0 +1,35 @@
+/*
+ *  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_windows_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 523e3b7b8..12c6fd5db 100644
--- a/src/webextension/ephy-web-extension-manager.c
+++ b/src/webextension/ephy-web-extension-manager.c
@@ -41,6 +41,7 @@
 #include "api/runtime.h"
 #include "api/storage.h"
 #include "api/tabs.h"
+#include "api/windows.h"
 
 #include <json-glib/json-glib.h>
 
@@ -70,6 +71,7 @@ EphyWebExtensionAsyncApiHandler api_handlers[] = {
   {"runtime", ephy_web_extension_api_runtime_handler},
   {"storage", ephy_web_extension_api_storage_handler},
   {"tabs", ephy_web_extension_api_tabs_handler},
+  {"windows", ephy_web_extension_api_windows_handler},
   {NULL, NULL},
 };
 
@@ -881,6 +883,7 @@ create_web_extensions_webview (EphyWebExtension *web_extension)
 
   settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view));
   webkit_settings_set_enable_write_console_messages_to_stdout (settings, TRUE);
+  webkit_settings_set_user_agent_with_application_details (settings, "Epiphany", "42");
 
   g_signal_connect (web_view, "decide-policy", G_CALLBACK (decide_policy_cb), web_extension);
 
diff --git a/src/webextension/ephy-web-extension.c b/src/webextension/ephy-web-extension.c
index 2a71f79d8..d4ed01e38 100644
--- a/src/webextension/ephy-web-extension.c
+++ b/src/webextension/ephy-web-extension.c
@@ -1515,7 +1515,7 @@ ephy_web_extension_create_sender_object (EphyWebExtension *self,
 
     /* For now these are always regular views and not extension views. */
     if (EPHY_IS_WEB_VIEW (web_view)) {
-      json_object_set_member (obj, "tab", ephy_web_extension_api_tabs_create_tab_object (EPHY_WEB_VIEW 
(web_view)));
+      json_object_set_member (obj, "tab", ephy_web_extension_api_tabs_create_tab_object (self, EPHY_WEB_VIEW 
(web_view)));
     }
   }
 
diff --git a/src/webextension/meson.build b/src/webextension/meson.build
index 671ded29b..80ee092e6 100644
--- a/src/webextension/meson.build
+++ b/src/webextension/meson.build
@@ -5,6 +5,7 @@ ephywebextension_src = [
   'webextension/api/runtime.c',
   'webextension/api/storage.c',
   'webextension/api/tabs.c',
+  'webextension/api/windows.c',
   'webextension/ephy-web-extension-manager.c',
   'webextension/ephy-web-extension.c',
 ]


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