[epiphany/pgriffis/web-extension/windows: 8/8] WebExtensions: Implement windows.onCreated and windows.onRemoved




commit d867aac86b26acd1e99db10f8db7aff0a68337b6
Author: Patrick Griffis <pgriffis igalia com>
Date:   Wed Jun 8 12:31:38 2022 -0500

    WebExtensions: Implement windows.onCreated and windows.onRemoved

 src/webextension/api/windows.c                | 29 ++++++++++-----
 src/webextension/api/windows.h                | 15 +++++---
 src/webextension/ephy-web-extension-manager.c | 51 +++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 14 deletions(-)
---
diff --git a/src/webextension/api/windows.c b/src/webextension/api/windows.c
index db02d7a74..9b41a6114 100644
--- a/src/webextension/api/windows.c
+++ b/src/webextension/api/windows.c
@@ -24,8 +24,8 @@
 #include "tabs.h"
 #include "windows.h"
 
-static EphyWindow *
-get_window_for_id (int window_id)
+EphyWindow *
+ephy_web_extension_api_windows_get_window_for_id (gint64 window_id)
 {
   GList *windows;
 
@@ -41,7 +41,7 @@ get_window_for_id (int window_id)
       return window;
   }
 
-  g_debug ("Failed to find window with id %d", window_id);
+  g_debug ("Failed to find window with id %ld", window_id);
   return NULL;
 }
 
@@ -111,6 +111,21 @@ add_window_to_json (EphyWebExtension *self,
   json_builder_end_object (builder);
 }
 
+char *
+ephy_web_extension_api_windows_create_window_json (EphyWebExtension *self,
+                                                   EphyWindow       *window)
+{
+  g_autoptr (JsonBuilder) builder = json_builder_new ();
+  g_autoptr (JsonNode) root = NULL;
+  add_window_to_json (self,
+                      builder,
+                      window,
+                      TRUE);
+  root = json_builder_get_root (builder);
+  return json_to_string (root, FALSE);
+}
+
+
 static char *
 windows_handler_get (EphyWebExtension  *self,
                      char              *name,
@@ -123,7 +138,6 @@ windows_handler_get (EphyWebExtension  *self,
   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)) {
@@ -131,8 +145,7 @@ windows_handler_get (EphyWebExtension  *self,
     return NULL;
   }
 
-  window_id = jsc_value_to_int32 (window_id_value);
-  window = get_window_for_id (window_id);
+  window = ephy_web_extension_api_windows_get_window_for_id (jsc_value_to_int32 (window_id_value));
 
   if (!window) {
     g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, "window.get(): 
Failed to find window by id");
@@ -311,15 +324,13 @@ windows_handler_remove (EphyWebExtension  *self,
 {
   g_autoptr (JSCValue) window_id_value = jsc_value_object_get_property_at_index (args, 0);
   EphyWindow *window;
-  int window_id;
 
   if (!jsc_value_is_number (window_id_value)) {
     g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, "window.remove(): 
First argument is not a windowId");
     return NULL;
   }
 
-  window_id = jsc_value_to_int32 (window_id_value);
-  window = get_window_for_id (window_id);
+  window = ephy_web_extension_api_windows_get_window_for_id (jsc_value_to_int32 (window_id_value));
 
   if (!window) {
     g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, "window.remove(): 
Failed to find window by id");
diff --git a/src/webextension/api/windows.h b/src/webextension/api/windows.h
index e1dcbee54..a89ba50ab 100644
--- a/src/webextension/api/windows.h
+++ b/src/webextension/api/windows.h
@@ -26,10 +26,15 @@
 
 G_BEGIN_DECLS
 
-void ephy_web_extension_api_windows_handler (EphyWebExtension *self,
-                                             char             *name,
-                                             JSCValue         *value,
-                                             WebKitWebView    *web_view,
-                                             GTask            *task);
+void         ephy_web_extension_api_windows_handler                    (EphyWebExtension *self,
+                                                                        char             *name,
+                                                                        JSCValue         *value,
+                                                                        WebKitWebView    *web_view,
+                                                                        GTask            *task);
+
+char        *ephy_web_extension_api_windows_create_window_json          (EphyWebExtension *self,
+                                                                         EphyWindow       *window);
+
+EphyWindow  *ephy_web_extension_api_windows_get_window_for_id           (gint64            window_id);
 
 G_END_DECLS
diff --git a/src/webextension/ephy-web-extension-manager.c b/src/webextension/ephy-web-extension-manager.c
index fd9d331a5..e1710e472 100644
--- a/src/webextension/ephy-web-extension-manager.c
+++ b/src/webextension/ephy-web-extension-manager.c
@@ -1209,6 +1209,52 @@ extension_equal (gconstpointer a,
   return g_strcmp0 (a, b) == 0;
 }
 
+typedef struct {
+  EphyWebExtension *web_extension;
+  guint64 window_id;
+} WindowAddedCallbackData;
+
+static gboolean
+application_window_added_timeout_cb (gpointer user_data)
+{
+  WindowAddedCallbackData *data = user_data;
+  EphyWebExtensionManager *manager = ephy_web_extension_manager_get_default ();
+  EphyWindow *window = ephy_web_extension_api_windows_get_window_for_id (data->window_id);
+  g_autofree char *window_json = NULL;
+
+  /* It is possible the window was removed before this timeout. */
+  if (!window)
+    return G_SOURCE_REMOVE;
+
+  window_json = ephy_web_extension_api_windows_create_window_json (data->web_extension, window);
+  ephy_web_extension_manager_emit_in_extension_views (manager, data->web_extension, "windows.onCreated", 
window_json);
+  return G_SOURCE_REMOVE;
+}
+
+static void
+application_window_added_cb (EphyShell        *shell,
+                             EphyWindow       *window,
+                             EphyWebExtension *web_extension)
+{
+  /* At this point the EphyWindow has no EphyEmbed child so we can't get information from it.
+   * We also can't really know ahead of time if multiple tabs are opening so simply adding a delay
+   * tends to give accurate results. */
+  WindowAddedCallbackData *data = g_new (WindowAddedCallbackData, 1);
+  data->window_id = ephy_window_get_uid (window);
+  data->web_extension = web_extension;
+  g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE, 1, application_window_added_timeout_cb, data, g_free);
+}
+
+static void
+application_window_removed_cb (EphyShell        *shell,
+                               EphyWindow       *window,
+                               EphyWebExtension *web_extension)
+{
+  EphyWebExtensionManager *manager = ephy_web_extension_manager_get_default ();
+  g_autofree char *window_json = g_strdup_printf ("%ld", ephy_window_get_uid (window));
+  ephy_web_extension_manager_emit_in_extension_views (manager, web_extension, "windows.onRemoved", 
window_json);
+}
+
 void
 ephy_web_extension_manager_set_active (EphyWebExtensionManager *self,
                                        EphyWebExtension        *web_extension,
@@ -1248,9 +1294,14 @@ ephy_web_extension_manager_set_active (EphyWebExtensionManager *self,
   }
 
   if (active) {
+    g_signal_connect (shell, "window-added", G_CALLBACK (application_window_added_cb), web_extension);
+    g_signal_connect (shell, "window-removed", G_CALLBACK (application_window_removed_cb), web_extension);
+
     if (ephy_web_extension_has_background_web_view (web_extension))
       run_background_script (self, web_extension);
   } else {
+    g_signal_handlers_disconnect_by_data (shell, web_extension);
+
     g_hash_table_remove (self->browser_action_map, web_extension);
     g_hash_table_remove (self->background_web_views, web_extension);
     g_object_set_data (G_OBJECT (web_extension), "alarms", NULL); /* Set in alarms.c */


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