summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Griffis <pgriffis@igalia.com>2022-06-07 14:40:11 -0500
committerPatrick Griffis <pgriffis@igalia.com>2022-06-08 15:13:59 -0500
commitd0c051ed56b8701335a685a6d993b0c45bce0022 (patch)
treed99fd917175037ed6121724bab0182c221798135
parent62472de40777b050cc37920269d61dab86a78abf (diff)
downloadepiphany-d0c051ed56b8701335a685a6d993b0c45bce0022.tar.gz
WebExtensions: Implement windows.get()
Part-of: <https://gitlab.gnome.org/GNOME/epiphany/-/merge_requests/1137>
-rw-r--r--src/webextension/api/tabs.c39
-rw-r--r--src/webextension/api/tabs.h8
-rw-r--r--src/webextension/api/windows.c184
-rw-r--r--src/webextension/api/windows.h35
-rw-r--r--src/webextension/ephy-web-extension-manager.c2
-rw-r--r--src/webextension/ephy-web-extension.c2
-rw-r--r--src/webextension/meson.build1
7 files changed, 253 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..6ad86ca5c
--- /dev/null
+++ b/src/webextension/api/windows.c
@@ -0,0 +1,184 @@
+/*
+ * 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 "tabs.h"
+#include "windows.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);
+ 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..fd9d331a5 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},
};
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',
]