[evolution/wip-webkit2: 3/11] Prepare environment for WK2 WebExtensions and do initial implementation (reuse Epiphany's implementa



commit 60b6d716d3ea0312ed0cec660ab28bca4c411922
Author: Tomas Popela <tpopela redhat com>
Date:   Fri Oct 18 08:00:03 2013 +0200

    Prepare environment for WK2 WebExtensions and do initial implementation (reuse Epiphany's implementation)

 Makefile.am                              |    1 +
 configure.ac                             |   10 ++
 shell/Makefile.am                        |    1 +
 shell/main.c                             |    5 +
 web-extensions/Makefile.am               |   20 +++
 web-extensions/evolution-web-extension.c |  250 ++++++++++++++++++++++++++++++
 web-extensions/evolution-web-extension.h |   26 +++
 7 files changed, 313 insertions(+), 0 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 856e459..c5bd6d3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -65,6 +65,7 @@ SUBDIRS =                     \
        art                     \
        plugins                 \
        modules                 \
+       web-extensions          \
        $(MAINT_SUBDIR)         \
        doc                     \
        ui                      \
diff --git a/configure.ac b/configure.ac
index 34b3b5e..a8b9d68 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1144,6 +1144,16 @@ AC_SUBST(viewsdir)
 dnl For evolution-alarm-notify.desktop
 AS_AC_EXPAND(PRIVLIBEXECDIR, "$privlibexecdir")
 
+dnl **********************************
+dnl WebKit2 Web Extensions
+dnl **********************************
+webextensionsdir="$privlibdir/web-extensions"
+AC_SUBST(webextensionsdir)
+
+PKG_CHECK_MODULES(WEB_EXTENSION, [webkit2gtk-3.0 >= webkit2gtk_minimum_version])
+AC_SUBST(WEB_EXTENSIONS_CFLAGS)
+AC_SUBST(WEB_EXTENSIONS_LIBS)
+
 dnl ************************
 dnl Plugins
 dnl ************************
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 7d42a68..d7bf9db 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -114,6 +114,7 @@ evolution_CPPFLAGS =                                                \
        -DEVOLUTION_RULEDIR=\""$(privdatadir)"\"                \
        -DEVOLUTION_TOOLSDIR=\""$(privlibexecdir)"\"            \
        -DEVOLUTION_UIDIR=\""$(uidir)"\"                        \
+       -DEVOLUTION_WEB_EXTENSIONS_DIR=\""$(privwebextensions)"\" \
        -DPREFIX=\""$(prefix)"\"                                \
        -DEVOLUTION_MX_THEMEDIR=\"$(privdatadir)/theme\"        \
        -DSYSCONFDIR=\""$(sysconfdir)"\"                        \
diff --git a/shell/main.c b/shell/main.c
index bfee350..5689f82 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -609,6 +609,11 @@ main (gint argc,
        if (setup_only)
                exit (0);
 
+       /* Set the web extensions dir before the process is launched */
+       webkit_web_context_set_web_extensions_directory (
+               webkit_web_context_get_default (),
+               EVOLUTION_WEB_EXTENSIONS_DIR);
+
        categories_icon_theme_hack ();
        gtk_accel_map_load (e_get_accels_filename ());
 
diff --git a/web-extensions/Makefile.am b/web-extensions/Makefile.am
new file mode 100644
index 0000000..93d31d1
--- /dev/null
+++ b/web-extensions/Makefile.am
@@ -0,0 +1,20 @@
+webextension_LTLIBRARIES = libevolutionwebextension.la
+
+libevolutionwebextension_la_SOURCES = \
+       evolution-web-extension.c \
+       evolution-web-extension.h \
+       $(top_srcdir)/e-utils/e-dom-utils.c \
+       $(top_srcdir)/e-utils/e-dom-utils.h
+
+libevolutionwebextension_la_CPPFLAGS = \
+       -I$(top_srcdir)/e-util \
+       $(AM_CPPFLAGS)
+
+libevolutionwebextension_la_CFLAGS = \
+       $(WEB_EXTENSIONS_CFLAGS)
+
+libevolutionwebextension_la_LIBADD = \
+       $(WEB_EXTENSIONS_LIBS)
+
+libevolutionwebextension_la_LDFLAGS = \
+       -module -avoid-version -no-undefined
diff --git a/web-extensions/evolution-web-extension.c b/web-extensions/evolution-web-extension.c
new file mode 100644
index 0000000..9c4fc76
--- /dev/null
+++ b/web-extensions/evolution-web-extension.c
@@ -0,0 +1,250 @@
+/*
+ * evolution-web-extension.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "config.h"
+#include "evolution-web-extension.h"
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <libsoup/soup.h>
+#include <webkit2/webkit-web-extension.h>
+
+static const char introspection_xml[] =
+"<node>"
+"  <interface name='org.gnome.Evolution.WebExtension'>"
+"    <method name='ReplaceLocalImageLinks'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"    </method>"
+"    <method name='GetDocumentContentHtml'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='html_content' direction='out'/>"
+"    </method>"
+"    <method name='GetSelectionContentHtml'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='html_content' direction='out'/>"
+"    </method>"
+"    <method name='GetSelectionContentText'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='text_content' direction='out'/>"
+"    </method>"
+"    <method name='CreateAndAddCSSStyleSheet'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='style_sheet_id' direction='in'/>"
+"    </method>"
+"    <method name='AddCSSRuleIntoStyleSheet'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='style_sheet_id' direction='in'/>"
+"      <arg type='s' name='selector' direction='in'/>"
+"      <arg type='s' name='style' direction='in'/>"
+"    </method>"
+"    <method name='EABContactFormatterBindDOM'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"    </method>"
+"  </interface>"
+"</node>";
+
+static void
+web_page_created_callback (WebKitWebExtension *extension,
+                           WebKitWebPage *web_page,
+                           gpointer user_data)
+{
+       g_signal_connect_object (
+               web_page, "document-loaded",
+               G_CALLBACK (web_page_document_loaded),
+               NULL, 0);
+}
+
+static WebKitWebPage *
+get_webkit_web_page_or_return_dbus_error (GDBusMethodInvocation *invocation,
+                                          WebKitWebExtension *web_extension,
+                                          guint64 page_id)
+{
+       WebKitWebPage *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 web_page;
+}
+
+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;
+       WebKitDOMDocument *document;
+       guint64 page_id;
+
+       if (g_strcmp0 (interface_name, EVOLUTION_WEB_EXTENSION_INTERFACE) != 0)
+               return;
+
+       if (g_strcmp0 (method_name, "ReplaceLocalImageLinks") == 0) {
+               g_variant_get (parameters, "(t)", &page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               e_dom_utils_replace_local_image_links (document);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "GetDocumentContentHtml") == 0) {
+               gchar *html_content;
+
+               g_variant_get (parameters, "(t)", &page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               html_content = e_dom_utils_get_document_content_html (document);
+
+               g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", html_content));
+       } else if (g_strcmp0 (method_name, "GetSelectionContentHtml") == 0) {
+               gchar *html_content;
+
+               g_variant_get (parameters, "(t)", &page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               html_content = e_dom_utils_get_selection_content_html (document);
+
+               g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", html_content));
+       } else if (g_strcmp0 (method_name, "GetSelectionContentText") == 0) {
+               gchar *text_content;
+
+               g_variant_get (parameters, "(t)", &page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               text_content = e_dom_utils_get_selection_content_html (document);
+
+               g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", text_content));
+       } else if (g_strcmp0 (method_name, "AddCSSRuleIntoStyleSheet") == 0) {
+               gchar *style_sheet_id, *selector, *style;
+
+               g_variant_get (parameters, "(tsss)", &page_id, &style_sheet_id, &selector, &style);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               e_dom_utils_add_css_rule_into_style_sheet (document, style_sheet_id, selector, style);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "CreateAndAddCSSStyleSheet") == 0) {
+               gchar *style_sheet_id;
+
+               g_variant_get (parameters, "(ts)", &page_id, &style_sheet_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               e_dom_utils_create_and_add_css_style_sheet (document, style_sheet_id);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "EABContactFormatterBindDOM") == 0) {
+               g_variant_get (parameters, "(t)", &page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               e_dom_utils_eab_contact_formatter_bind_dom (document);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       }
+}
+
+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,
+                       EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+                       introspection_data->interfaces[0],
+                       &interface_vtable,
+                       g_object_ref (user_data),
+                       g_object_unref,
+                       &error);
+
+       if (!registration_id) {
+               g_warning ("Failed to register object: %s\n", error->message);
+               g_error_free (error);
+       } else {
+               dbus_connection = connection;
+               g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&dbus_connection);
+       }
+}
+
+G_MODULE_EXPORT void
+webkit_web_extension_initialize (WebKitWebExtension *extension)
+{
+       char *service_name;
+
+       g_signal_connect (
+               extension, "page-created",
+               G_CALLBACK (web_page_created_callback),
+               NULL);
+
+       service_name =
+               g_strdup_printf (
+                       "%s-%s",
+                       EVOLUTION_WEB_EXTENSION_SERVICE_NAME,
+                       g_getenv ("EVOLUTION_WEB_EXTENSION_ID"));
+
+       g_bus_own_name (
+               G_BUS_TYPE_SESSION,
+               service_name,
+               G_BUS_NAME_OWNER_FLAGS_NONE,
+               bus_acquired_cb,
+               NULL, NULL,
+               g_object_ref (extension),
+               g_object_unref);
+
+       g_free (service_name);
+}
diff --git a/web-extensions/evolution-web-extension.h b/web-extensions/evolution-web-extension.h
new file mode 100644
index 0000000..ccee49f
--- /dev/null
+++ b/web-extensions/evolution-web-extension.h
@@ -0,0 +1,26 @@
+/*
+ * evolution-web-extension.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef EVOLUTION_WEB_EXTENSION_H
+#define EVOLUTION_WEB_EXTENSION_H
+
+#define EVOLUTION_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.WebExtension"
+#define EVOLUTION_WEB_EXTENSION_OBJECT_PATH  "/org/gnome/Evolution/WebExtension"
+#define EVOLUTION_WEB_EXTENSION_INTERFACE    "org.gnome.Evolution.WebExtension"
+
+#endif /* EVOLUTION_WEB_EXTENSION_H */


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