[epiphany/pgriffis/web-extension-beastify: 1/6] WebExtensions: Improve implementation of tabs.query




commit ca0ec1ac292da150a8f45e54ccfb189b585f748a
Author: Patrick Griffis <pgriffis igalia com>
Date:   Sun May 22 13:16:52 2022 -0500

    WebExtensions: Improve implementation of tabs.query

 .../resources/js/webextensions.js                  |   4 +
 src/ephy-window.c                                  |  11 +++
 src/ephy-window.h                                  |   2 +
 src/webextension/api/tabs.c                        | 109 +++++++++++++++------
 4 files changed, 96 insertions(+), 30 deletions(-)
---
diff --git a/embed/web-process-extension/resources/js/webextensions.js 
b/embed/web-process-extension/resources/js/webextensions.js
index 3f1eb4ce8..3420889f8 100644
--- a/embed/web-process-extension/resources/js/webextensions.js
+++ b/embed/web-process-extension/resources/js/webextensions.js
@@ -81,3 +81,7 @@ window.browser.browserAction = {
       addListener: function (cb) { browser_listeners.push({callback: cb}); }
     }
 };
+
+window.browser.windows = {
+  WINDOW_ID_CURRENT: -2, /* Matches Firefox, used in tabs.c. */
+};
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 4deeecafe..7c82554e0 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -145,6 +145,8 @@ const struct {
 
 #define SETTINGS_CONNECTION_DATA_KEY    "EphyWindowSettings"
 
+static guint64 window_uid = 1;
+
 struct _EphyWindow {
   HdyApplicationWindow parent_instance;
 
@@ -174,6 +176,7 @@ struct _EphyWindow {
   EphyAdaptiveMode adaptive_mode;
   int last_opened_pos;
   gboolean show_fullscreen_header_bar;
+  guint64 uid;
 
   GList *pending_decisions;
   gulong filters_initialized_id;
@@ -3845,6 +3848,8 @@ static void
 ephy_window_init (EphyWindow *window)
 {
   LOG ("EphyWindow initialising %p", window);
+
+  window->uid = window_uid++;
 }
 
 /**
@@ -4373,3 +4378,9 @@ ephy_window_get_geometry (EphyWindow   *window,
   rectangle->width = window->current_width;
   rectangle->height = window->current_height;
 }
+
+guint64
+ephy_window_get_uid (EphyWindow *window)
+{
+  return window->uid;
+}
diff --git a/src/ephy-window.h b/src/ephy-window.h
index c34b0d474..86099db2a 100644
--- a/src/ephy-window.h
+++ b/src/ephy-window.h
@@ -95,4 +95,6 @@ void              ephy_window_get_geometry               (EphyWindow   *window,
 void              ephy_window_sync_bookmark_state        (EphyWindow            *window,
                                                           EphyBookmarkIconState  state);
 
+guint64           ephy_window_get_uid                    (EphyWindow *window);
+
 G_END_DECLS
diff --git a/src/webextension/api/tabs.c b/src/webextension/api/tabs.c
index 533d4b414..4f7add694 100644
--- a/src/webextension/api/tabs.c
+++ b/src/webextension/api/tabs.c
@@ -25,6 +25,9 @@
 
 #include "tabs.h"
 
+/* Matches Firefox. */
+static const int WINDOW_ID_CURRENT = -2;
+
 static void
 add_web_view_to_json (JsonBuilder *builder,
                       EphyWebView *web_view)
@@ -37,6 +40,36 @@ add_web_view_to_json (JsonBuilder *builder,
   json_builder_end_object (builder);
 }
 
+typedef enum {
+  TAB_QUERY_UNSET = -1,
+  TAB_QUERY_DONT_MATCH = 0,
+  TAB_QUERY_MATCH = 1,
+} TabQuery;
+
+static TabQuery
+get_tab_query_property (JSCValue   *args,
+                      const char *name)
+{
+  g_autoptr (JSCValue) value = jsc_value_object_get_property (args, name);
+
+  if (!value || jsc_value_is_undefined (value))
+    return TAB_QUERY_UNSET;
+
+  return jsc_value_to_boolean (value);
+}
+
+static gint32
+get_number_property (JSCValue   *args,
+                     const char *name)
+{
+  g_autoptr (JSCValue) value = jsc_value_object_get_property (args, name);
+
+  if (!value || jsc_value_is_undefined (value))
+    return -1;
+
+  return jsc_value_to_int32 (value);
+}
+
 static char *
 tabs_handler_query (EphyWebExtension *self,
                     char             *name,
@@ -45,48 +78,64 @@ tabs_handler_query (EphyWebExtension *self,
   g_autoptr (JsonBuilder) builder = json_builder_new ();
   g_autoptr (JsonNode) root = NULL;
   EphyShell *shell = ephy_shell_get_default ();
-  GtkWindow *window;
-  EphyTabView *tab_view;
-  gboolean current_window = TRUE;
-  gboolean active = TRUE;
+  GList *windows;
+  EphyWindow *active_window;
+  TabQuery current_window;
+  TabQuery active;
+  gint32 window_id;
+  gint32 tab_index;
+
+  active = get_tab_query_property (args, "active");
+  current_window = get_tab_query_property (args, "currentWindow");
+  window_id = get_number_property (args, "windowId");
+  tab_index = get_number_property (args, "index");
+
+  if (window_id == WINDOW_ID_CURRENT) {
+    current_window = TRUE;
+    window_id = -1;
+  }
 
-  if (jsc_value_object_has_property (args, "active")) {
-    g_autoptr (JSCValue) value = NULL;
+  active_window = EPHY_WINDOW (gtk_application_get_active_window (GTK_APPLICATION (shell)));
 
-    value = jsc_value_object_get_property (args, "active");
-    active = jsc_value_to_boolean (value);
-  }
+  windows = gtk_application_get_windows (GTK_APPLICATION (shell));
 
-  if (jsc_value_object_has_property (args, "currentWindow")) {
-    g_autoptr (JSCValue) value = NULL;
+  json_builder_begin_array (builder);
 
-    value = jsc_value_object_get_property (args, "currentWindow");
-    current_window = jsc_value_to_boolean (value);
-  }
+  for (GList *win_list = windows; win_list; win_list = g_list_next (win_list)) {
+    EphyWindow *window;
+    EphyTabView *tab_view;
+    EphyWebView *active_web_view;
 
-  if (current_window) {
-    window = gtk_application_get_active_window (GTK_APPLICATION (shell));
-    tab_view = ephy_window_get_tab_view (EPHY_WINDOW (window));
+    g_assert (EPHY_IS_WINDOW (win_list->data));
 
-    json_builder_begin_array (builder);
+    window = EPHY_WINDOW (win_list->data);
+    if (window_id != -1 && (guint64)window_id != ephy_window_get_uid (window))
+      continue;
 
-    if (active) {
-      GtkWidget *page = ephy_tab_view_get_selected_page (tab_view);
-      EphyWebView *tmp_webview = ephy_embed_get_web_view (EPHY_EMBED (page));
+    if (current_window == TRUE && window != active_window)
+      continue;
+    else if (current_window == FALSE && window == active_window)
+      continue;
 
-      add_web_view_to_json (builder, tmp_webview);
-    } else {
-      for (int i = 0; i < ephy_tab_view_get_n_pages (tab_view); i++) {
-        GtkWidget *page = ephy_tab_view_get_nth_page (tab_view, i);
-        EphyWebView *tmp_webview = ephy_embed_get_web_view (EPHY_EMBED (page));
+    tab_view = ephy_window_get_tab_view (window);
+    active_web_view = ephy_embed_get_web_view (EPHY_EMBED (ephy_tab_view_get_selected_page (tab_view)));
+    for (int i = 0; i < ephy_tab_view_get_n_pages (tab_view); i++) {
+      EphyWebView *web_view;
 
-        add_web_view_to_json (builder, tmp_webview);
-      }
-    }
+      if (tab_index != -1 && tab_index != i)
+        continue;
 
-    json_builder_end_array (builder);
+      web_view = ephy_embed_get_web_view (EPHY_EMBED (ephy_tab_view_get_nth_page (tab_view, i)));
+      if (active == TAB_QUERY_MATCH && web_view != active_web_view)
+        continue;
+      else if (active == TAB_QUERY_DONT_MATCH && web_view == active_web_view)
+        continue;
+
+      add_web_view_to_json (builder, web_view);
+    }
   }
 
+  json_builder_end_array (builder);
   root = json_builder_get_root (builder);
 
   return json_to_string (root, FALSE);


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