aboutsummaryrefslogtreecommitdiffstats
path: root/embed/web-extension
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2012-12-29 00:39:40 +0800
committerCarlos Garcia Campos <carlosgc@gnome.org>2013-02-19 19:59:33 +0800
commit86615e3298fa53736a6a2b722be7d45ecffd36db (patch)
tree56a041705b541760e4c04c7a4d7137f790b64d05 /embed/web-extension
parent8acf5ae0ecaf38ce2b0e1529d88a8fde9803b7e4 (diff)
downloadgsoc2013-epiphany-86615e3298fa53736a6a2b722be7d45ecffd36db.tar
gsoc2013-epiphany-86615e3298fa53736a6a2b722be7d45ecffd36db.tar.gz
gsoc2013-epiphany-86615e3298fa53736a6a2b722be7d45ecffd36db.tar.bz2
gsoc2013-epiphany-86615e3298fa53736a6a2b722be7d45ecffd36db.tar.lz
gsoc2013-epiphany-86615e3298fa53736a6a2b722be7d45ecffd36db.tar.xz
gsoc2013-epiphany-86615e3298fa53736a6a2b722be7d45ecffd36db.tar.zst
gsoc2013-epiphany-86615e3298fa53736a6a2b722be7d45ecffd36db.zip
embed: Implement unsubmitted modified forms warning in WebKit2
Installing a web extension to access the DOM. https://bugzilla.gnome.org/show_bug.cgi?id=684437
Diffstat (limited to 'embed/web-extension')
-rw-r--r--embed/web-extension/Makefile.am20
-rw-r--r--embed/web-extension/ephy-web-extension.c169
-rw-r--r--embed/web-extension/ephy-web-extension.h26
3 files changed, 215 insertions, 0 deletions
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 */