diff options
Diffstat (limited to 'embed')
-rw-r--r-- | embed/Makefile.am | 15 | ||||
-rw-r--r-- | embed/ephy-embed-shell.c | 33 | ||||
-rw-r--r-- | embed/ephy-embed-shell.h | 3 | ||||
-rw-r--r-- | embed/ephy-web-view.c | 20 | ||||
-rw-r--r-- | embed/web-extension/Makefile.am | 20 | ||||
-rw-r--r-- | embed/web-extension/ephy-web-extension.c | 169 | ||||
-rw-r--r-- | embed/web-extension/ephy-web-extension.h | 26 |
7 files changed, 279 insertions, 7 deletions
diff --git a/embed/Makefile.am b/embed/Makefile.am index 2df16223d..467cc5453 100644 --- a/embed/Makefile.am +++ b/embed/Makefile.am @@ -1,5 +1,9 @@ NULL = +if WITH_WEBKIT2 +SUBDIRS = web-extension +endif + noinst_LTLIBRARIES = libephyembed.la NOINST_H_FILES = \ @@ -58,11 +62,12 @@ nodist_libephyembed_la_SOURCES = \ $(BUILT_SOURCES) libephyembed_la_CPPFLAGS = \ - -I$(top_builddir)/lib \ - -I$(top_srcdir)/lib \ - -I$(top_srcdir)/lib/egg \ - -I$(top_srcdir)/lib/history \ - -I$(top_srcdir)/lib/widgets \ + -I$(top_srcdir)/embed/web-extension \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/lib/egg \ + -I$(top_srcdir)/lib/history \ + -I$(top_srcdir)/lib/widgets \ $(AM_CPPFLAGS) if WITH_WEBKIT2 diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c index b4366b2f4..7f48f7c2e 100644 --- a/embed/ephy-embed-shell.c +++ b/embed/ephy-embed-shell.c @@ -33,6 +33,9 @@ #include "ephy-history-service.h" #include "ephy-profile-utils.h" #include "ephy-snapshot-service.h" +#ifdef HAVE_WEBKIT2 +#include "ephy-web-extension.h" +#endif #include <glib/gi18n.h> #include <gtk/gtk.h> @@ -55,6 +58,9 @@ struct _EphyEmbedShellPrivate EphyEmbedShellMode mode; EphyFrecentStore *frecent_store; guint single_initialised : 1; +#ifdef HAVE_WEBKIT2 + GDBusProxy *web_extension; +#endif }; enum @@ -93,6 +99,9 @@ ephy_embed_shell_dispose (GObject *object) g_clear_object (&priv->global_history_service); g_clear_object (&priv->embed_single); g_clear_object (&priv->adblock_manager); +#ifdef HAVE_WEBKIT2 + g_clear_object (&priv->web_extension); +#endif G_OBJECT_CLASS (ephy_embed_shell_parent_class)->dispose (object); } @@ -677,3 +686,27 @@ ephy_embed_shell_launch_handler (EphyEmbedShell *shell, return ret; } + +#ifdef HAVE_WEBKIT2 +GDBusProxy * +ephy_embed_shell_get_web_extension_proxy (EphyEmbedShell *shell) +{ + EphyEmbedShellPrivate *priv; + + g_return_val_if_fail (EPHY_IS_EMBED_SHELL (shell), NULL); + + priv = shell->priv; + if (!priv->web_extension) { + priv->web_extension = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + EPHY_WEB_EXTENSION_SERVICE_NAME, + EPHY_WEB_EXTENSION_OBJECT_PATH, + EPHY_WEB_EXTENSION_INTERFACE, + NULL, + NULL); + } + + return priv->web_extension; +} +#endif diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h index 45261e93b..85e7df52c 100644 --- a/embed/ephy-embed-shell.h +++ b/embed/ephy-embed-shell.h @@ -102,6 +102,9 @@ gboolean ephy_embed_shell_launch_handler (EphyEmbedShell GFile *file, const char *mime_type, guint32 user_time); +#ifdef HAVE_WEBKIT2 +GDBusProxy *ephy_embed_shell_get_web_extension_proxy (EphyEmbedShell *shell); +#endif G_END_DECLS diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c index e65358026..eced9f1ad 100644 --- a/embed/ephy-web-view.c +++ b/embed/ephy-web-view.c @@ -3417,7 +3417,23 @@ gboolean ephy_web_view_has_modified_forms (EphyWebView *view) { #ifdef HAVE_WEBKIT2 - /* TODO: DOM Bindings */ + GVariant *result; + gboolean retval = FALSE; + + /* FIXME: This should be async */ + result = g_dbus_proxy_call_sync (ephy_embed_shell_get_web_extension_proxy (ephy_embed_shell_get_default ()), + "HasModifiedForms", + g_variant_new("(t)", webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL); + + + g_variant_get (result, "(b)", &retval); + g_variant_unref (result); + + return retval; #else WebKitDOMHTMLCollection *forms = NULL; WebKitDOMDocument *document = NULL; @@ -3472,8 +3488,8 @@ ephy_web_view_has_modified_forms (EphyWebView *view) } } } -#endif return FALSE; +#endif } /** diff --git a/embed/web-extension/Makefile.am b/embed/web-extension/Makefile.am new file mode 100644 index 000000000..fe7277288 --- /dev/null +++ b/embed/web-extension/Makefile.am @@ -0,0 +1,20 @@ +webextension_LTLIBRARIES = libephywebextension.la + +webextensiondir = \ + $(libdir)/epiphany/$(EPIPHANY_MAJOR)/web-extensions + +libephywebextension_la_SOURCES = \ + ephy-web-extension.c \ + ephy-web-extension.h + +libephywebextension_la_CPPFLAG = \ + $(AM_CPPFLAGS) + +libephywebextension_la_CFLAGS = \ + $(WEB_EXTENSION_CFLAGS) + +libephywebextension_la_LIBADD = \ + $(WEB_EXTENSION_LIBS) + +libephywebextension_la_LDFLAGS = \ + -module -avoid-version -no-undefined diff --git a/embed/web-extension/ephy-web-extension.c b/embed/web-extension/ephy-web-extension.c new file mode 100644 index 000000000..1650026a3 --- /dev/null +++ b/embed/web-extension/ephy-web-extension.c @@ -0,0 +1,169 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * Copyright © 2012 Igalia S.L. + * + * This program 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 2, or (at your option) + * any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "ephy-web-extension.h" + +#include <gio/gio.h> +#include <webkit2/webkit-web-extension.h> + +static const char introspection_xml[] = + "<node>" + " <interface name='org.gnome.Epiphany.WebExtension'>" + " <method name='HasModifiedForms'>" + " <arg type='t' name='page_id' direction='in'/>" + " <arg type='b' name='has_modified_forms' direction='out'/>" + " </method>" + " </interface>" + "</node>"; + +#define MIN_INPUT_LENGTH 50 + +static gboolean +ephy_web_extension_page_has_modified_forms (WebKitWebPage *web_page) +{ + WebKitDOMHTMLCollection *forms = NULL; + WebKitDOMDocument *document = NULL; + gulong forms_n; + int i; + + document = webkit_web_page_get_dom_document (web_page); + forms = webkit_dom_document_get_forms (document); + forms_n = webkit_dom_html_collection_get_length (forms); + + for (i = 0; i < forms_n; i++) { + WebKitDOMHTMLCollection *elements; + WebKitDOMNode *form_element = webkit_dom_html_collection_item (forms, i); + gulong elements_n; + int j; + gboolean modified_input_element = FALSE; + + elements = webkit_dom_html_form_element_get_elements (WEBKIT_DOM_HTML_FORM_ELEMENT (form_element)); + elements_n = webkit_dom_html_collection_get_length (elements); + + for (j = 0; j < elements_n; j++) { + WebKitDOMNode *element; + + element = webkit_dom_html_collection_item (elements, j); + + if (WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT (element)) + if (webkit_dom_html_text_area_element_is_edited (WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (element))) + return TRUE; + + if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element)) + if (webkit_dom_html_input_element_is_edited (WEBKIT_DOM_HTML_INPUT_ELEMENT (element))) { + glong length; + char *text; + + /* A small heuristic here. If there's only one input element + * modified and it does not have a lot of text the user is + * likely not very interested in saving this work, so do + * nothing (eg, google search input). */ + if (modified_input_element) + return TRUE; + + modified_input_element = TRUE; + + text = webkit_dom_html_input_element_get_value (WEBKIT_DOM_HTML_INPUT_ELEMENT (element)); + length = g_utf8_strlen (text, -1); + g_free (text); + + if (length > MIN_INPUT_LENGTH) + return TRUE; + } + } + } + + return FALSE; +} + +static void +handle_method_call (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + WebKitWebExtension *web_extension = WEBKIT_WEB_EXTENSION (user_data); + WebKitWebPage *web_page; + guint64 page_id; + + if (g_strcmp0 (interface_name, EPHY_WEB_EXTENSION_INTERFACE) != 0) + return; + + g_variant_get(parameters, "(t)", &page_id); + web_page = webkit_web_extension_get_page (web_extension, page_id); + if (!web_page) { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "Invalid page ID: %"G_GUINT64_FORMAT, page_id); + return; + } + + if (g_strcmp0 (method_name, "HasModifiedForms") == 0) { + gboolean has_modifed_forms; + + has_modifed_forms = ephy_web_extension_page_has_modified_forms (web_page); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", has_modifed_forms)); + } +} + +static const GDBusInterfaceVTable interface_vtable = { + handle_method_call, + NULL, + NULL +}; + +static void +bus_acquired_cb (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + guint registration_id; + GError *error = NULL; + static GDBusNodeInfo *introspection_data = NULL; + if (!introspection_data) + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); + + registration_id = g_dbus_connection_register_object (connection, + EPHY_WEB_EXTENSION_OBJECT_PATH, + introspection_data->interfaces[0], + &interface_vtable, + g_object_ref (user_data), + (GDestroyNotify)g_object_unref, + &error); + if (!registration_id) { + g_warning ("Failed to register object: %s\n", error->message); + g_error_free (error); + } +} + +G_MODULE_EXPORT void +webkit_web_extension_initialize (WebKitWebExtension *extension) +{ + g_bus_own_name (G_BUS_TYPE_SESSION, + EPHY_WEB_EXTENSION_SERVICE_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired_cb, + NULL, NULL, + g_object_ref (extension), + (GDestroyNotify)g_object_unref); +} diff --git a/embed/web-extension/ephy-web-extension.h b/embed/web-extension/ephy-web-extension.h new file mode 100644 index 000000000..7792480a5 --- /dev/null +++ b/embed/web-extension/ephy-web-extension.h @@ -0,0 +1,26 @@ +/* + * Copyright © 2012 Igalia S.L. + * + * This program 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 2, or (at your option) + * any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef EPHY_WEB_EXTENSION_H +#define EPHY_WEB_EXTENSION_H + +#define EPHY_WEB_EXTENSION_SERVICE_NAME "org.gnome.Epiphany.WebExtension" +#define EPHY_WEB_EXTENSION_OBJECT_PATH "/org/gnome/Epiphany/WebExtension" +#define EPHY_WEB_EXTENSION_INTERFACE "org.gnome.Epiphany.WebExtension" + +#endif /* EPHY_WEB_EXTENSION_H */ |