[evolution/wip-webkit2] Move ItipFormatter module to WK2 API



commit dd7ce260eecc575eff4951bceb982dffc3057d22
Author: Tomas Popela <tpopela redhat com>
Date:   Tue Oct 29 16:04:46 2013 +0100

    Move ItipFormatter module to WK2 API

 configure.ac                                       |    1 +
 modules/itip-formatter/Makefile.am                 |    3 +-
 modules/itip-formatter/e-mail-part-itip.c          |   31 +-
 .../itip-formatter/itip-view-elements-defines.h    |   65 +
 modules/itip-formatter/itip-view.c                 | 1619 +++++++++-----------
 modules/itip-formatter/itip-view.h                 |    8 +-
 .../module-itip-formatter-dom-utils.c              |  710 +++++++++
 .../module-itip-formatter-dom-utils.h              |  112 ++
 modules/itip-formatter/web-extension/Makefile.am   |   23 +
 .../module-itip-formatter-web-extension.c          |  628 ++++++++
 .../module-itip-formatter-web-extension.h          |   26 +
 11 files changed, 2340 insertions(+), 886 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a24ddc9..d1ed324 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1537,6 +1537,7 @@ modules/contact-photos/Makefile
 modules/gravatar/Makefile
 modules/itip-formatter/Makefile
 modules/itip-formatter/plugin/Makefile
+modules/itip-formatter/web-extension/Makefile
 modules/mail-config/Makefile
 modules/mail/Makefile
 modules/mailto-handler/Makefile
diff --git a/modules/itip-formatter/Makefile.am b/modules/itip-formatter/Makefile.am
index b38989d..1062b13 100644
--- a/modules/itip-formatter/Makefile.am
+++ b/modules/itip-formatter/Makefile.am
@@ -26,7 +26,8 @@ module_itip_formatter_la_SOURCES =                                    \
        e-source-conflict-search.h                                      \
        itip-view.c                                                     \
        itip-view.h                                                     \
-       evolution-module-itip-formatter.c
+       evolution-module-itip-formatter.c                               \
+       itip-view-elements-defines.h
 
 module_itip_formatter_la_LIBADD =                                      \
        $(top_builddir)/e-util/libevolution-util.la                     \
diff --git a/modules/itip-formatter/e-mail-part-itip.c b/modules/itip-formatter/e-mail-part-itip.c
index e4e6302..cd58929 100644
--- a/modules/itip-formatter/e-mail-part-itip.c
+++ b/modules/itip-formatter/e-mail-part-itip.c
@@ -77,45 +77,34 @@ mail_part_itip_finalize (GObject *object)
 
 static void
 mail_part_itip_bind_dom_element (EMailPart *part,
-                                 WebKitDOMElement *element)
+                                 const gchar *element_id)
 {
-       GString *buffer;
-       WebKitDOMDocument *document;
        ItipView *view;
        EMailPartItip *pitip;
 
        pitip = E_MAIL_PART_ITIP (part);
 
-       if (!WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) {
-               WebKitDOMNodeList *nodes;
-               guint ii, length;
-
-               nodes = webkit_dom_element_get_elements_by_tag_name (
-                       element, "iframe");
-               length = webkit_dom_node_list_get_length (nodes);
-               for (ii = 0; ii < length; ii++) {
-                       element = WEBKIT_DOM_ELEMENT (
-                               webkit_dom_node_list_item (nodes, ii));
-                       break;
-               }
-       }
+       /* FIXME XXX Checks */
+#if 0
+       if (!WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element))
+               element = webkit_dom_element_query_selector (
+                       element, "iframe", NULL);
 
        g_return_if_fail (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element));
 
-       buffer = g_string_new ("");
        document = webkit_dom_html_iframe_element_get_content_document (
                WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
+#endif
 
        view = itip_view_new (pitip, pitip->client_cache);
+#if 0
        g_object_set_data_full (
                G_OBJECT (element), "view", view,
                (GDestroyNotify) g_object_unref);
-
-       itip_view_create_dom_bindings (
-               view, webkit_dom_document_get_document_element (document));
+#endif
+       itip_view_create_dom_bindings (view, element_id);
 
        itip_view_init_view (view);
-       g_string_free (buffer, TRUE);
 }
 
 static void
diff --git a/modules/itip-formatter/itip-view-elements-defines.h 
b/modules/itip-formatter/itip-view-elements-defines.h
new file mode 100644
index 0000000..35bf653
--- /dev/null
+++ b/modules/itip-formatter/itip-view-elements-defines.h
@@ -0,0 +1,65 @@
+/*
+ * itip-view-elements-defines.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 ITIP_VIEW_ELEMENTS_DEFINES_H
+#define ITIP_VIEW_ELEMENTS_DEFINES_H
+
+#define TEXT_ROW_SENDER "text_row_sender"
+#define TABLE_ROW_SUMMARY "table_row_summary"
+#define TABLE_ROW_LOCATION "table_row_location"
+#define TABLE_ROW_START_DATE "table_row_start_time"
+#define TABLE_ROW_END_DATE "table_row_end_time"
+#define TABLE_ROW_STATUS "table_row_status"
+#define TABLE_ROW_COMMENT "table_row_comment"
+#define TABLE_ROW_DESCRIPTION "table_row_description"
+#define TABLE_ROW_RSVP_COMMENT "table_row_rsvp_comment"
+#define TABLE_ROW_ESCB "table_row_escb"
+#define TABLE_ROW_BUTTONS "table_row_buttons"
+#define TABLE_ROW_ESCB_LABEL "table_row_escb_label"
+
+#define TABLE_BUTTONS "table_buttons"
+
+#define SELECT_ESOURCE "select_esource"
+#define TEXTAREA_RSVP_COMMENT "textarea_rsvp_comment"
+
+#define CHECKBOX_RSVP "checkbox_rsvp"
+#define CHECKBOX_RECUR "checkbox_recur"
+#define CHECKBOX_UPDATE "checkbox_update"
+#define CHECKBOX_FREE_TIME "checkbox_free_time"
+#define CHECKBOX_KEEP_ALARM "checkbox_keep_alarm"
+#define CHECKBOX_INHERIT_ALARM "checkbox_inherit_alarm"
+
+#define BUTTON_OPEN_CALENDAR "button_open_calendar"
+#define BUTTON_DECLINE "button_decline"
+#define BUTTON_DECLINE_ALL "button_decline_all"
+#define BUTTON_ACCEPT "button_accept"
+#define BUTTON_ACCEPT_ALL "button_accept_all"
+#define BUTTON_TENTATIVE "button_tentative"
+#define BUTTON_TENTATIVE_ALL "button_tentative_all"
+#define BUTTON_SEND_INFORMATION "button_send_information"
+#define BUTTON_UPDATE "button_update"
+#define BUTTON_UPDATE_ATTENDEE_STATUS "button_update_attendee_status"
+#define BUTTON_SAVE "button_save"
+
+#define TABLE_UPPER_ITIP_INFO "table_upper_itip_info"
+#define TABLE_LOWER_ITIP_INFO "table_lower_itip_info"
+
+#define DIV_ITIP_CONTENT "div_itip_content"
+#define DIV_ITIP_ERROR "div_itip_error"
+
+#endif /* ITIP_VIEW_ELEMENTS_DEFINES_H */
diff --git a/modules/itip-formatter/itip-view.c b/modules/itip-formatter/itip-view.c
index 45f0b1d..16a508a 100644
--- a/modules/itip-formatter/itip-view.c
+++ b/modules/itip-formatter/itip-view.c
@@ -48,6 +48,9 @@
 #include "e-source-conflict-search.h"
 #include "itip-view.h"
 #include "e-mail-part-itip.h"
+#include "itip-view-elements-defines.h"
+
+#include "web-extension/module-itip-formatter-web-extension.h"
 
 #define d(x)
 
@@ -114,55 +117,17 @@ struct _ItipViewPrivate {
 
        gint needs_decline : 1;
 
-        WebKitDOMDocument *dom_document;
         EMailPartItip *itip_part;
 
+       GDBusProxy *web_extension;
+       guint web_extension_watch_name_id;
+       guint web_extension_source_changed_signal_id;
+       guint web_extension_button_clicked_signal_id;
+       guint web_extension_recur_toggled_signal_id;
+
         gchar *error;
 };
 
-#define TEXT_ROW_SENDER "text_row_sender"
-#define TABLE_ROW_SUMMARY "table_row_summary"
-#define TABLE_ROW_LOCATION "table_row_location"
-#define TABLE_ROW_START_DATE "table_row_start_time"
-#define TABLE_ROW_END_DATE "table_row_end_time"
-#define TABLE_ROW_STATUS "table_row_status"
-#define TABLE_ROW_COMMENT "table_row_comment"
-#define TABLE_ROW_DESCRIPTION "table_row_description"
-#define TABLE_ROW_RSVP_COMMENT "table_row_rsvp_comment"
-#define TABLE_ROW_ESCB "table_row_escb"
-#define TABLE_ROW_BUTTONS "table_row_buttons"
-#define TABLE_ROW_ESCB_LABEL "table_row_escb_label"
-
-#define TABLE_BUTTONS "table_buttons"
-
-#define SELECT_ESOURCE "select_esource"
-#define TEXTAREA_RSVP_COMMENT "textarea_rsvp_comment"
-
-#define CHECKBOX_RSVP "checkbox_rsvp"
-#define CHECKBOX_RECUR "checkbox_recur"
-#define CHECKBOX_UPDATE "checkbox_update"
-#define CHECKBOX_FREE_TIME "checkbox_free_time"
-#define CHECKBOX_KEEP_ALARM "checkbox_keep_alarm"
-#define CHECKBOX_INHERIT_ALARM "checkbox_inherit_alarm"
-
-#define BUTTON_OPEN_CALENDAR "button_open_calendar"
-#define BUTTON_DECLINE "button_decline"
-#define BUTTON_DECLINE_ALL "button_decline_all"
-#define BUTTON_ACCEPT "button_accept"
-#define BUTTON_ACCEPT_ALL "button_accept_all"
-#define BUTTON_TENTATIVE "button_tentative"
-#define BUTTON_TENTATIVE_ALL "button_tentative_all"
-#define BUTTON_SEND_INFORMATION "button_send_information"
-#define BUTTON_UPDATE "button_update"
-#define BUTTON_UPDATE_ATTENDEE_STATUS "button_update_attendee_status"
-#define BUTTON_SAVE "button_save"
-
-#define TABLE_UPPER_ITIP_INFO "table_upper_itip_info"
-#define TABLE_LOWER_ITIP_INFO "table_lower_itip_info"
-
-#define DIV_ITIP_CONTENT "div_itip_content"
-#define DIV_ITIP_ERROR "div_itip_error"
-
 enum {
        PROP_0,
        PROP_CLIENT_CACHE,
@@ -621,6 +586,227 @@ set_journal_sender_text (ItipView *view)
 }
 
 static void
+enable_button (ItipView *view,
+              const gchar *button_id,
+               gboolean enable)
+{
+       GVariant *result;
+
+       if (!view->priv->web_extension)
+               return;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "EnableButton",
+                       g_variant_new ("(sb)", button_id, enable),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+}
+
+static void
+show_button (ItipView *view,
+             const gchar *id)
+{
+       GVariant *result;
+
+       if (!view->priv->web_extension)
+                       return;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "ShowButton",
+                       g_variant_new ("(s)", id),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+}
+
+static void
+hide_element (ItipView *view,
+             const gchar *element_id,
+              gboolean hide)
+{
+       GVariant *result;
+
+       if (!view->priv->web_extension)
+               return;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "HideElement",
+                       g_variant_new ("(sb)", element_id, hide),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+}
+
+static gboolean
+element_is_hidden (ItipView *view,
+                   const gchar *element_id)
+{
+       GVariant *result;
+       gboolean hidden;
+
+       if (!view->priv->web_extension)
+               return FALSE;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "InputIsChecked",
+                       g_variant_new ("(s)", element_id),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &hidden);
+               g_variant_unref (result);
+               return hidden;
+       }
+
+       return FALSE;
+}
+
+static void
+set_inner_html (ItipView *view,
+               const gchar *element_id,
+                const gchar *inner_html)
+{
+       GVariant *result;
+
+       if (!view->priv->web_extension)
+               return;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "ElementSetInnerHTML",
+                       g_variant_new ("(ss)", element_id, inner_html),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+}
+
+static void
+input_set_checked (ItipView *view,
+                   const gchar *input_id,
+                   gboolean checked)
+{
+       GVariant *result;
+
+       if (!view->priv->web_extension)
+               return;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "InputSetChecked",
+                       g_variant_new ("(sb)", input_id, checked),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result) {
+               g_variant_unref (result);
+       }
+}
+
+static gboolean
+input_is_checked (ItipView *view,
+                  const gchar *input_id)
+{
+       GVariant *result;
+       gboolean checked;
+
+       if (!view->priv->web_extension)
+               return FALSE;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "InputIsChecked",
+                       g_variant_new ("(s)", input_id),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &checked);
+               g_variant_unref (result);
+               return checked;
+       }
+
+       return FALSE;
+}
+
+static void
+show_checkbox (ItipView *view,
+               const gchar *id,
+               gboolean show,
+              gboolean update_second)
+{
+       GVariant *result;
+
+       g_return_if_fail (ITIP_IS_VIEW (view));
+
+       if (!view->priv->web_extension)
+               return;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "ShowCheckbox",
+                       g_variant_new ("(sbb)", id, show, update_second),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+}
+
+static void
+set_area_text (ItipView *view,
+               const gchar *id,
+               const gchar *text)
+{
+       GVariant *result;
+
+       g_return_if_fail (ITIP_IS_VIEW (view));
+
+       if (!view->priv->web_extension)
+               return;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "SetAreaText",
+                       g_variant_new ("(ss)", id, text ? text : ""),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+}
+static void
 set_sender_text (ItipView *view)
 {
        ItipViewPrivate *priv;
@@ -644,21 +830,15 @@ set_sender_text (ItipView *view)
                break;
        }
 
-       if (priv->sender && priv->dom_document) {
-               WebKitDOMElement *div;
-
-               div = webkit_dom_document_get_element_by_id (
-                       priv->dom_document, TEXT_ROW_SENDER);
-               webkit_dom_html_element_set_inner_html (
-                       WEBKIT_DOM_HTML_ELEMENT (div), priv->sender, NULL);
-       }
+       if (priv->sender && priv->web_extension)
+               set_inner_html (view, TEXT_ROW_SENDER, priv->sender);
 }
 
 static void
 update_start_end_times (ItipView *view)
 {
        ItipViewPrivate *priv;
-       WebKitDOMElement *row, *col;
+       GVariant *result;
        gchar buffer[256];
        time_t now;
        struct tm *now_tm;
@@ -703,122 +883,96 @@ update_start_end_times (ItipView *view)
        }
        #undef is_same
 
-       if (priv->dom_document) {
-               row = webkit_dom_document_get_element_by_id (
-                       priv->dom_document, TABLE_ROW_START_DATE);
-               if (priv->start_header && priv->start_label) {
-                       webkit_dom_html_element_set_hidden (
-                               WEBKIT_DOM_HTML_ELEMENT (row), FALSE);
-
-                       col = webkit_dom_element_get_first_element_child (row);
-                       webkit_dom_html_element_set_inner_html (
-                               WEBKIT_DOM_HTML_ELEMENT (col), priv->start_header, NULL);
-
-                       col = webkit_dom_element_get_last_element_child (row);
-                       webkit_dom_html_element_set_inner_html (
-                               WEBKIT_DOM_HTML_ELEMENT (col), priv->start_label, NULL);
-               } else {
-                       webkit_dom_html_element_set_hidden (
-                               WEBKIT_DOM_HTML_ELEMENT (row), TRUE);
-               }
+       if (!priv->web_extension)
+               return;
 
-               row = webkit_dom_document_get_element_by_id (
-                       priv->dom_document, TABLE_ROW_END_DATE);
-               if (priv->end_header && priv->end_label) {
-                       webkit_dom_html_element_set_hidden (
-                               WEBKIT_DOM_HTML_ELEMENT (row), FALSE);
+       if (priv->start_header && priv->start_label) {
+               result = g_dbus_proxy_call_sync (
+                               priv->web_extension,
+                               "UpdateTimes",
+                               g_variant_new (
+                                       "(sss)",
+                                       TABLE_ROW_START_DATE,
+                                       priv->start_header,
+                                       priv->start_label),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
 
-                       col = webkit_dom_element_get_first_element_child (row);
-                       webkit_dom_html_element_set_inner_html (
-                               WEBKIT_DOM_HTML_ELEMENT (col), priv->end_header, NULL);
+               if (result)
+                       g_variant_unref (result);
+       } else
+               hide_element (view, TABLE_ROW_START_DATE, TRUE);
+
+       if (priv->start_header && priv->start_label) {
+               result = g_dbus_proxy_call_sync (
+                               priv->web_extension,
+                               "UpdateTimes",
+                               g_variant_new (
+                                       "(sss)",
+                                       TABLE_ROW_END_DATE,
+                                       priv->end_header,
+                                       priv->end_label),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
 
-                       col = webkit_dom_element_get_last_element_child (row);
-                       webkit_dom_html_element_set_inner_html (
-                               WEBKIT_DOM_HTML_ELEMENT (col), priv->end_label, NULL);
-               } else {
-                       webkit_dom_html_element_set_hidden (
-                               WEBKIT_DOM_HTML_ELEMENT (row), TRUE);
-               }
-       }
+               if (result)
+                       g_variant_unref (result);
+       } else
+               hide_element (view, TABLE_ROW_END_DATE, TRUE);
 }
 
 static void
-button_clicked_cb (WebKitDOMElement *element,
-                   WebKitDOMEvent *event,
-                   gpointer data)
+button_clicked (const gchar *button_value,
+                   ItipView *view)
 {
        ItipViewResponse response;
-       gchar *responseStr;
-
-       responseStr = webkit_dom_html_button_element_get_value (
-               WEBKIT_DOM_HTML_BUTTON_ELEMENT (element));
 
-       response = atoi (responseStr);
+       response = atoi (button_value);
 
-       g_signal_emit (data, signals[RESPONSE], 0, response);
+       g_signal_emit (view, signals[RESPONSE], 0, response);
 }
 
 static void
-rsvp_toggled_cb (WebKitDOMHTMLInputElement *input,
-                 WebKitDOMEvent *event,
-                 gpointer data)
+button_clicked_signal_cb (GDBusConnection *connection,
+                          const gchar *sender_name,
+                          const gchar *object_path,
+                          const gchar *interface_name,
+                          const gchar *signal_name,
+                          GVariant *parameters,
+                          ItipView *view)
 {
-       WebKitDOMElement *el;
+       const gchar *button_value;
 
-       ItipView *view = data;
-       gboolean rsvp;
+       if (g_strcmp0 (signal_name, "ButtonClicked") != 0)
+               return;
 
-       rsvp = webkit_dom_html_input_element_get_checked (input);
+       if (parameters)
+               button_value = g_variant_get_string (parameters, NULL);
 
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
-       webkit_dom_html_text_area_element_set_disabled (
-               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp);
+       button_clicked (button_value, view);
 }
 
 static void
-recur_toggled_cb (WebKitDOMHTMLInputElement *input,
-                  WebKitDOMEvent *event,
-                  gpointer data)
-{
-       ItipView *view = data;
+recur_toggled_signal_cb (GDBusConnection *connection,
+                         const gchar *sender_name,
+                         const gchar *object_path,
+                         const gchar *interface_name,
+                         const gchar *signal_name,
+                         GVariant *parameters,
+                         ItipView *view)
+{
+       if (g_strcmp0 (signal_name, "RecurToggled") != 0)
+               return;
 
        itip_view_set_mode (view, view->priv->mode);
 }
 
-/*
-  alarm_check_toggled_cb
-  check1 was changed, so make the second available based on state of the first check.
-*/
 static void
-alarm_check_toggled_cb (WebKitDOMHTMLInputElement *check1,
-                        WebKitDOMEvent *event,
-                        ItipView *view)
-{
-       WebKitDOMElement *check2;
-       gchar *id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (check1));
-
-       if (g_strcmp0 (id, CHECKBOX_INHERIT_ALARM)) {
-               check2 = webkit_dom_document_get_element_by_id (
-                       view->priv->dom_document, CHECKBOX_KEEP_ALARM);
-       } else {
-               check2 = webkit_dom_document_get_element_by_id (
-                       view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
-       }
-
-       g_free (id);
-
-       webkit_dom_html_input_element_set_disabled (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (check2),
-               (webkit_dom_html_element_get_hidden (
-                               WEBKIT_DOM_HTML_ELEMENT (check1)) &&
-                       webkit_dom_html_input_element_get_checked (check1)));
-}
-
-static void
-source_changed_cb (WebKitDOMElement *select,
-                   WebKitDOMEvent *event,
-                   ItipView *view)
+source_changed (ItipView *view)
 {
        ESource *source;
 
@@ -831,6 +985,21 @@ source_changed_cb (WebKitDOMElement *select,
 }
 
 static void
+source_changed_signal_cb (GDBusConnection *connection,
+                          const gchar *sender_name,
+                          const gchar *object_path,
+                          const gchar *interface_name,
+                          const gchar *signal_name,
+                          GVariant *parameters,
+                          ItipView *view)
+{
+       if (g_strcmp0 (signal_name, "SourceChanged") != 0)
+               return;
+
+       source_changed (view);
+}
+
+static void
 append_checkbox_table_row (GString *buffer,
                            const gchar *name,
                            const gchar *label)
@@ -894,19 +1063,9 @@ append_info_item_row (ItipView *view,
                       const gchar *table_id,
                       ItipViewInfoItem *item)
 {
-       WebKitDOMElement *table;
-       WebKitDOMHTMLElement *row, *cell;
+       GVariant *result;
        const gchar *icon_name;
-       gchar *id;
-
-       table = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, table_id);
-       row = webkit_dom_html_table_element_insert_row (
-               WEBKIT_DOM_HTML_TABLE_ELEMENT (table), -1, NULL);
-
-       id = g_strdup_printf ("%s_row_%d", table_id, item->id);
-       webkit_dom_html_element_set_id (row, id);
-       g_free (id);
+       gchar *row_id;
 
        switch (item->type) {
                case ITIP_VIEW_INFO_ITEM_TYPE_INFO:
@@ -926,31 +1085,29 @@ append_info_item_row (ItipView *view,
                        icon_name = NULL;
        }
 
-       cell = webkit_dom_html_table_row_element_insert_cell (
-               (WebKitDOMHTMLTableRowElement *) row, -1, NULL);
-
-       if (icon_name) {
-               WebKitDOMElement *image;
-               gchar *icon_uri;
-
-               image = webkit_dom_document_create_element (
-                       view->priv->dom_document, "IMG", NULL);
+       row_id = g_strdup_printf ("%s_row_%d", table_id, item->id);
 
-               icon_uri = g_strdup_printf ("gtk-stock://%s", icon_name);
-               webkit_dom_html_image_element_set_src (
-                       WEBKIT_DOM_HTML_IMAGE_ELEMENT (image), icon_uri);
-               g_free (icon_uri);
+       if (!view->priv->web_extension)
+                       return;
 
-               webkit_dom_node_append_child (
-                       WEBKIT_DOM_NODE (cell),
-                       WEBKIT_DOM_NODE (image),
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "AppendInfoItemRow",
+                       g_variant_new (
+                               "(ssss)",
+                               table_id,
+                               row_id,
+                               icon_name,
+                               item->message),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
                        NULL);
-       }
 
-       cell = webkit_dom_html_table_row_element_insert_cell (
-               (WebKitDOMHTMLTableRowElement *) row, -1, NULL);
+       if (result)
+               g_variant_unref (result);
 
-       webkit_dom_html_element_set_inner_html (cell, item->message, NULL);
+       g_free (row_id);
 
        d (printf ("Added row %s_row_%d ('%s')\n", table_id, item->id, item->message));
 }
@@ -960,18 +1117,27 @@ remove_info_item_row (ItipView *view,
                       const gchar *table_id,
                       guint id)
 {
-       WebKitDOMElement *row;
+       GVariant *result;
        gchar *row_id;
 
        row_id = g_strdup_printf ("%s_row_%d", table_id, id);
-       row = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, row_id);
-       g_free (row_id);
 
-       webkit_dom_node_remove_child (
-               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (row)),
-               WEBKIT_DOM_NODE (row),
-               NULL);
+       if (!view->priv->web_extension)
+                       return;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "RemoveElement",
+                       g_variant_new ("(s)", row_id),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+
+       g_free (row_id);
 
        d (printf ("Removed row %s_row_%d\n", table_id, id));
 }
@@ -1050,106 +1216,66 @@ static void
 itip_view_rebuild_source_list (ItipView *view)
 {
        ESourceRegistry *registry;
-       WebKitDOMElement *select;
+       GVariant *result;
        GList *list, *link;
        const gchar *extension_name;
-       GHashTable *groups;
 
        d (printf ("Assigning a new source list!\n"));
 
-       if (!view->priv->dom_document)
-               return;
+       if (!view->priv->web_extension)
+                       return;
 
        registry = view->priv->registry;
        extension_name = itip_view_get_extension_name (view);
 
-       select = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, SELECT_ESOURCE);
-
-       while (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (select))) {
-               webkit_dom_node_remove_child (
-                       WEBKIT_DOM_NODE (select),
-                       webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (select)),
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "ElementRemoveChildNodes",
+                       g_variant_new ("(s)", SELECT_ESOURCE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
                        NULL);
-       }
+
+       if (result)
+               g_variant_unref (result);
 
        if (extension_name == NULL)
                return;
 
        list = e_source_registry_list_sources (registry, extension_name);
-       groups = g_hash_table_new_full (
-               g_str_hash, g_str_equal,
-               (GDestroyNotify) g_free, NULL);
 
        for (link = list; link != NULL; link = g_list_next (link)) {
                ESource *source = E_SOURCE (link->data);
                ESource *parent;
-               WebKitDOMElement *option;
-               WebKitDOMHTMLOptGroupElement *optgroup;
 
                parent = e_source_registry_ref_source (
                        registry, e_source_get_parent (source));
 
-               optgroup = g_hash_table_lookup (groups, e_source_get_uid (parent));
-               if (!optgroup) {
-                       optgroup = WEBKIT_DOM_HTML_OPT_GROUP_ELEMENT (
-                                       webkit_dom_document_create_element (
-                                               view->priv->dom_document,
-                                               "OPTGROUP", NULL));
-                       webkit_dom_html_opt_group_element_set_label (
-                               optgroup, e_source_get_display_name (parent));
-                       g_hash_table_insert (
-                               groups, g_strdup (e_source_get_uid (parent)), optgroup);
-               }
-               g_object_unref (parent);
+               result = g_dbus_proxy_call_sync (
+                               view->priv->web_extension,
+                               "RebuildSourceList",
+                               g_variant_new (
+                                       "(ssssb)",
+                                       e_source_get_uid (parent),
+                                       e_source_get_display_name (parent),
+                                       e_source_get_uid (source),
+                                       e_source_get_display_name (source),
+                                       e_source_get_writable (source)),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
 
-               option = webkit_dom_document_create_element (
-                       view->priv->dom_document, "OPTION", NULL);
-               webkit_dom_html_option_element_set_value (
-                       WEBKIT_DOM_HTML_OPTION_ELEMENT (option),
-                       e_source_get_uid (source));
-               webkit_dom_html_option_element_set_label (
-                       WEBKIT_DOM_HTML_OPTION_ELEMENT (option),
-                       e_source_get_display_name (source));
-               webkit_dom_html_element_set_inner_html (
-                       WEBKIT_DOM_HTML_ELEMENT (option),
-                       e_source_get_display_name (source), NULL);
-
-               /* See https://bugzilla.gnome.org/show_bug.cgi?id=681400
-                * FIXME: This can be removed once we require WebKitGtk 1.10+ */
-               #if WEBKIT_CHECK_VERSION (1, 9, 6)
-                       webkit_dom_element_set_class_name (
-                               WEBKIT_DOM_ELEMENT (option), "calendar");
-               #else
-                       webkit_dom_html_element_set_class_name (
-                               WEBKIT_DOM_HTML_ELEMENT (option), "calendar");
-               #endif
-
-               if (!e_source_get_writable (source)) {
-                       webkit_dom_html_option_element_set_disabled (
-                               WEBKIT_DOM_HTML_OPTION_ELEMENT (option), TRUE);
-               }
+               if (result)
+                       g_variant_unref (result);
 
-               webkit_dom_node_append_child (
-                       WEBKIT_DOM_NODE (optgroup),
-                       WEBKIT_DOM_NODE (option),
-                       NULL);
+               g_object_unref (parent);
        }
 
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
 
-       list = g_hash_table_get_values (groups);
-       for (link = list; link != NULL; link = g_list_next (link)) {
-               WebKitDOMNode *optgroup = link->data;
-
-               webkit_dom_node_append_child (
-                       WEBKIT_DOM_NODE (select), optgroup, NULL);
-       }
-       g_list_free (list);
-
-       g_hash_table_destroy (groups);
-
-       source_changed_cb (select, NULL, view);
+       source_changed (view);
 }
 
 static void
@@ -1270,6 +1396,34 @@ itip_view_dispose (GObject *object)
        g_clear_object (&priv->client_cache);
        g_clear_object (&priv->registry);
 
+       if (priv->web_extension_watch_name_id > 0) {
+               g_bus_unwatch_name (priv->web_extension_watch_name_id);
+               priv->web_extension_watch_name_id = 0;
+       }
+
+       if (priv->web_extension_recur_toggled_signal_id > 0) {
+               g_dbus_connection_signal_unsubscribe (
+                       g_dbus_proxy_get_connection (priv->web_extension),
+                       priv->web_extension_recur_toggled_signal_id);
+               priv->web_extension_recur_toggled_signal_id = 0;
+       }
+
+       if (priv->web_extension_source_changed_signal_id > 0) {
+               g_dbus_connection_signal_unsubscribe (
+                       g_dbus_proxy_get_connection (priv->web_extension),
+                       priv->web_extension_source_changed_signal_id);
+               priv->web_extension_source_changed_signal_id = 0;
+       }
+
+       if (priv->web_extension_button_clicked_signal_id > 0) {
+               g_dbus_connection_signal_unsubscribe (
+                       g_dbus_proxy_get_connection (priv->web_extension),
+                       priv->web_extension_button_clicked_signal_id);
+               priv->web_extension_button_clicked_signal_id = 0;
+       }
+
+       g_clear_object (&priv->web_extension);
+
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (itip_view_parent_class)->dispose (object);
 }
@@ -1284,7 +1438,6 @@ itip_view_finalize (GObject *object)
 
        d (printf ("Itip view finalized!\n"));
 
-       g_clear_object (&priv->dom_document);
        g_free (priv->extension_name);
        g_free (priv->sender);
        g_free (priv->organizer);
@@ -1627,118 +1780,147 @@ itip_view_write_for_printing (ItipView *view,
 
 void
 itip_view_create_dom_bindings (ItipView *view,
-                               WebKitDOMElement *element)
+                               const gchar *element_id)
 {
-       WebKitDOMElement *el;
-       WebKitDOMDocument *doc;
+       GVariant *result;
 
-       doc = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
-       view->priv->dom_document = g_object_ref (doc);
+       if (!view->priv->web_extension)
+               return;
 
-       el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_RECUR);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (recur_toggled_cb), FALSE, view);
-       }
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "SaveDocumentFromElement",
+                       g_variant_new (
+                               "(ts)",
+                               webkit_web_view_get_page_id (
+                                       WEBKIT_WEB_VIEW (view)),
+                               element_id),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
 
-       el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_RSVP);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (rsvp_toggled_cb), FALSE, view);
-       }
+       if (result)
+               g_variant_unref (result);
 
-       el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_INHERIT_ALARM);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (alarm_check_toggled_cb), FALSE, view);
-       }
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "CreateDOMBindings",
+                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
 
-       el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_KEEP_ALARM);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (alarm_check_toggled_cb), FALSE, view);
-       }
+       if (result)
+               g_variant_unref (result);
+}
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_OPEN_CALENDAR);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+static void
+web_extension_proxy_created_cb (GDBusProxy *proxy,
+                                GAsyncResult *result,
+                                ItipView *view)
+{
+       GError *error = NULL;
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_ACCEPT);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
+       view->priv->web_extension = g_dbus_proxy_new_finish (result, &error);
+       if (!view->priv->web_extension) {
+               g_warning ("Error creating web extension proxy: %s\n", error->message);
+               g_error_free (error);
        }
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_ACCEPT_ALL);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+       view->priv->web_extension_source_changed_signal_id =
+               g_dbus_connection_signal_subscribe (
+                       g_dbus_proxy_get_connection (view->priv->web_extension),
+                       g_dbus_proxy_get_name (view->priv->web_extension),
+                       MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+                       "SourceChanged",
+                       MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       (GDBusSignalCallback) source_changed_signal_cb,
+                       view,
+                       NULL);
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_TENTATIVE);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+       view->priv->web_extension_button_clicked_signal_id =
+               g_dbus_connection_signal_subscribe (
+                       g_dbus_proxy_get_connection (view->priv->web_extension),
+                       g_dbus_proxy_get_name (view->priv->web_extension),
+                       MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+                       "ButtonClicked",
+                       MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       (GDBusSignalCallback) button_clicked_signal_cb,
+                       view,
+                       NULL);
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_TENTATIVE_ALL);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+       view->priv->web_extension_recur_toggled_signal_id =
+               g_dbus_connection_signal_subscribe (
+                       g_dbus_proxy_get_connection (view->priv->web_extension),
+                       g_dbus_proxy_get_name (view->priv->web_extension),
+                       MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+                       "RecurToggled",
+                       MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       (GDBusSignalCallback) recur_toggled_signal_cb,
+                       view,
+                       NULL);
+}
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_DECLINE);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+static void
+web_extension_appeared_cb (GDBusConnection *connection,
+                           const gchar *name,
+                           const gchar *name_owner,
+                           ItipView *view)
+{
+       g_dbus_proxy_new (
+               connection,
+               G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
+               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+               G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+               NULL,
+               name,
+               MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+               MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+               NULL,
+               (GAsyncReadyCallback)web_extension_proxy_created_cb,
+               view);
+}
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_DECLINE_ALL);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+static void
+web_extension_vanished_cb (GDBusConnection *connection,
+                           const gchar *name,
+                           ItipView *view)
+{
+       g_clear_object (&view->priv->web_extension);
+}
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_UPDATE);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+static void
+itip_view_watch_web_extension (ItipView *view)
+{
+       char *service_name;
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_UPDATE_ATTENDEE_STATUS);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+       service_name = g_strdup_printf ("%s-%u", MODULE_ITIP_FORMATTER_WEB_EXTENSION_SERVICE_NAME, getpid ());
+       view->priv->web_extension_watch_name_id =
+               g_bus_watch_name (
+                       G_BUS_TYPE_SESSION,
+                       service_name,
+                       G_BUS_NAME_WATCHER_FLAGS_NONE,
+                       (GBusNameAppearedCallback) web_extension_appeared_cb,
+                       (GBusNameVanishedCallback) web_extension_vanished_cb,
+                       view, NULL);
 
-       el = webkit_dom_document_get_element_by_id (doc, BUTTON_SEND_INFORMATION);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
-       }
+       g_free (service_name);
+}
 
-       el = webkit_dom_document_get_element_by_id (doc, SELECT_ESOURCE);
-       if (el) {
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "change",
-                       G_CALLBACK (source_changed_cb), FALSE, view);
-       }
+GDBusProxy *
+itip_view_get_web_extension_proxy (ItipView *view)
+{
+       g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
+
+       return view->priv->web_extension;
 }
 
 static void
@@ -1746,6 +1928,7 @@ itip_view_init (ItipView *view)
 {
        view->priv = ITIP_VIEW_GET_PRIVATE (view);
 
+       itip_view_watch_web_extension (view);
 }
 
 ItipView *
@@ -1765,24 +1948,11 @@ itip_view_new (EMailPartItip *puri,
        return view;
 }
 
-static void
-show_button (ItipView *view,
-             const gchar *id)
-{
-       WebKitDOMElement *button;
-
-       button = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, id);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (button), FALSE);
-}
-
 void
 itip_view_set_mode (ItipView *view,
                     ItipViewMode mode)
 {
-       WebKitDOMElement *row, *cell;
-       WebKitDOMElement *button;
+       GVariant *result;
 
        g_return_if_fail (ITIP_IS_VIEW (view));
 
@@ -1790,17 +1960,20 @@ itip_view_set_mode (ItipView *view,
 
        set_sender_text (view);
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return;
 
-       row = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_BUTTONS);
-       cell = webkit_dom_element_get_first_element_child (row);
-       do {
-               button = webkit_dom_element_get_first_element_child (cell);
-               webkit_dom_html_element_set_hidden (
-                       WEBKIT_DOM_HTML_ELEMENT (button), TRUE);
-       } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL);
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "ElementHideChildNodes",
+                       g_variant_new ("(s)", TABLE_ROW_BUTTONS),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
 
        view->priv->is_recur_set = itip_view_get_recur_check_state (view);
 
@@ -1858,7 +2031,7 @@ void
 itip_view_set_item_type (ItipView *view,
                          ECalClientSourceType type)
 {
-       WebKitDOMElement *label;
+       GVariant *result;
        const gchar *header;
        gchar *access_key, *html_label;
 
@@ -1866,12 +2039,9 @@ itip_view_set_item_type (ItipView *view,
 
        view->priv->type = type;
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return;
 
-       label = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_ESCB_LABEL);
-
        switch (view->priv->type) {
                case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
                        header = _("_Calendar:");
@@ -1894,10 +2064,19 @@ itip_view_set_item_type (ItipView *view,
 
        html_label = e_mail_formatter_parse_html_mnemonics (header, &access_key);
 
-       webkit_dom_html_element_set_access_key (
-               WEBKIT_DOM_HTML_ELEMENT (label), access_key);
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (label), html_label, NULL);
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "ElementSetAccessKey",
+                       g_variant_new ("(ss)", TABLE_ROW_ESCB_LABEL, access_key),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+
+       set_inner_html (view, TABLE_ROW_ESCB_LABEL, html_label);
 
        g_free (html_label);
 
@@ -2051,8 +2230,6 @@ void
 itip_view_set_summary (ItipView *view,
                        const gchar *summary)
 {
-       WebKitDOMElement *row, *col;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
        if (view->priv->summary)
@@ -2060,19 +2237,7 @@ itip_view_set_summary (ItipView *view,
 
        view->priv->summary = summary ? g_strstrip (e_utf8_ensure_valid (summary)) : NULL;
 
-       if (!view->priv->dom_document)
-               return;
-
-       row = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_SUMMARY);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->summary == NULL));
-
-       col = webkit_dom_element_get_last_element_child (row);
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (col),
-               view->priv->summary ? view->priv->summary : "",
-               NULL);
+       set_area_text (view, TABLE_ROW_SUMMARY, view->priv->summary);
 }
 
 const gchar *
@@ -2087,8 +2252,6 @@ void
 itip_view_set_location (ItipView *view,
                         const gchar *location)
 {
-       WebKitDOMElement *row, *col;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
        if (view->priv->location)
@@ -2096,19 +2259,7 @@ itip_view_set_location (ItipView *view,
 
        view->priv->location = location ? g_strstrip (e_utf8_ensure_valid (location)) : NULL;
 
-       if (!view->priv->dom_document)
-               return;
-
-       row = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_LOCATION);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->location == NULL));
-
-       col = webkit_dom_element_get_last_element_child (row);
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (col),
-               view->priv->location ? view->priv->location : "",
-               NULL);
+       set_area_text (view, TABLE_ROW_LOCATION, view->priv->location);
 }
 
 const gchar *
@@ -2123,8 +2274,6 @@ void
 itip_view_set_status (ItipView *view,
                       const gchar *status)
 {
-       WebKitDOMElement *row, *col;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
        if (view->priv->status)
@@ -2132,19 +2281,7 @@ itip_view_set_status (ItipView *view,
 
        view->priv->status = status ? g_strstrip (e_utf8_ensure_valid (status)) : NULL;
 
-       if (!view->priv->dom_document)
-               return;
-
-       row = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_STATUS);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->status == NULL));
-
-       col = webkit_dom_element_get_last_element_child (row);
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (col),
-               view->priv->status ? view->priv->status : "",
-               NULL);
+       set_area_text (view, TABLE_ROW_STATUS, view->priv->status);
 }
 
 const gchar *
@@ -2159,8 +2296,6 @@ void
 itip_view_set_comment (ItipView *view,
                        const gchar *comment)
 {
-       WebKitDOMElement *row, *col;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
        if (view->priv->comment)
@@ -2168,19 +2303,7 @@ itip_view_set_comment (ItipView *view,
 
        view->priv->comment = comment ? g_strstrip (e_utf8_ensure_valid (comment)) : NULL;
 
-       if (!view->priv->dom_document)
-               return;
-
-       row = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_COMMENT);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->comment == NULL));
-
-       col = webkit_dom_element_get_last_element_child (row);
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (col),
-               view->priv->comment ? view->priv->comment : "",
-               NULL);
+       set_area_text (view, TABLE_ROW_COMMENT, view->priv->comment);
 }
 
 const gchar *
@@ -2195,8 +2318,6 @@ void
 itip_view_set_description (ItipView *view,
                            const gchar *description)
 {
-       WebKitDOMElement *div;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
        if (view->priv->description)
@@ -2204,18 +2325,11 @@ itip_view_set_description (ItipView *view,
 
        view->priv->description = description ? g_strstrip (e_utf8_ensure_valid (description)) : NULL;
 
-       if (!view->priv->dom_document)
-               return;
-
-       div = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_DESCRIPTION);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (div), (view->priv->description == NULL));
-
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (div),
-               view->priv->description ? view->priv->description : "",
-               NULL);
+       hide_element (view, TABLE_ROW_DESCRIPTION, (view->priv->description == NULL));
+       set_inner_html (
+               view,
+               TABLE_ROW_DESCRIPTION,
+               view->priv->description ? view->priv->description : "");
 }
 
 const gchar *
@@ -2322,7 +2436,7 @@ itip_view_add_upper_info_item (ItipView *view,
 
        priv->upper_info_items = g_slist_append (priv->upper_info_items, item);
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return item->id;
 
        append_info_item_row (view, TABLE_UPPER_ITIP_INFO, item);
@@ -2372,8 +2486,7 @@ itip_view_remove_upper_info_item (ItipView *view,
                        g_free (item->message);
                        g_free (item);
 
-                       if (!view->priv->dom_document)
-                               remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, id);
+                       remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, id);
 
                        return;
                }
@@ -2393,8 +2506,7 @@ itip_view_clear_upper_info_items (ItipView *view)
        for (l = priv->upper_info_items; l; l = l->next) {
                ItipViewInfoItem *item = l->data;
 
-               if (view->priv->dom_document)
-                       remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, item->id);
+               remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, item->id);
 
                g_free (item->message);
                g_free (item);
@@ -2424,7 +2536,7 @@ itip_view_add_lower_info_item (ItipView *view,
 
        priv->lower_info_items = g_slist_append (priv->lower_info_items, item);
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return item->id;
 
        append_info_item_row (view, TABLE_LOWER_ITIP_INFO, item);
@@ -2474,8 +2586,7 @@ itip_view_remove_lower_info_item (ItipView *view,
                        g_free (item->message);
                        g_free (item);
 
-                       if (view->priv->dom_document)
-                               remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, id);
+                       remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, id);
 
                        return;
                }
@@ -2495,8 +2606,7 @@ itip_view_clear_lower_info_items (ItipView *view)
        for (l = priv->lower_info_items; l; l = l->next) {
                ItipViewInfoItem *item = l->data;
 
-               if (view->priv->dom_document)
-                       remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, item->id);
+               remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, item->id);
 
                g_free (item->message);
                g_free (item);
@@ -2510,105 +2620,131 @@ void
 itip_view_set_source (ItipView *view,
                       ESource *source)
 {
-       WebKitDOMElement *select;
-       WebKitDOMElement *row;
+       GVariant *result;
        ESource *selected_source;
-       gulong i, len;
 
        g_return_if_fail (ITIP_IS_VIEW (view));
 
        d (printf ("Settings default source '%s'\n", e_source_get_display_name (source)));
 
-       if (!view->priv->dom_document)
-               return;
+       hide_element (view, TABLE_ROW_ESCB, (source == NULL));
 
-       row = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_ESCB);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (row), (source == NULL));
        if (source == NULL)
                return;
 
-       select = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, SELECT_ESOURCE);
-
         /* <select> does not emit 'change' event when already selected
         * <option> is re-selected, but we need to notify itip formatter,
         * so that it would make all the buttons sensitive */
        selected_source = itip_view_ref_source (view);
        if (source == selected_source) {
-               source_changed_cb (select, NULL, view);
+               source_changed (view);
                return;
        }
 
        if (selected_source != NULL)
                g_object_unref (selected_source);
 
-       if (webkit_dom_html_select_element_get_disabled (
-                       WEBKIT_DOM_HTML_SELECT_ELEMENT (select))) {
-               webkit_dom_html_select_element_set_disabled (
-                       WEBKIT_DOM_HTML_SELECT_ELEMENT (select), FALSE);
-       }
-
-       len = webkit_dom_html_select_element_get_length (
-               WEBKIT_DOM_HTML_SELECT_ELEMENT (select));
-       for (i = 0; i < len; i++) {
-
-               WebKitDOMNode *node;
-               WebKitDOMHTMLOptionElement *option;
-               gchar *value;
-
-               node = webkit_dom_html_select_element_item (
-                       WEBKIT_DOM_HTML_SELECT_ELEMENT (select), i);
-               option = WEBKIT_DOM_HTML_OPTION_ELEMENT (node);
+       if (!view->priv->web_extension)
+               return;
 
-               value = webkit_dom_html_option_element_get_value (option);
-               if (g_strcmp0 (value, e_source_get_uid (source)) == 0) {
-                       webkit_dom_html_option_element_set_selected (
-                               option, TRUE);
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "EnableSelect",
+                       g_variant_new ("(sb)", SELECT_ESOURCE, TRUE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
 
-                       g_free (value);
-                       break;
-               }
+       if (result)
+               g_variant_unref (result);
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "SelectSetSelected",
+                       g_variant_new (
+                               "(ss)",
+                               SELECT_ESOURCE, e_source_get_uid (source)),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
 
-               g_free (value);
-       }
+       if (result)
+               g_variant_unref (result);
 
-       source_changed_cb (select, NULL, view);
+       source_changed (view);
 }
 
 ESource *
 itip_view_ref_source (ItipView *view)
 {
-       WebKitDOMElement *select;
-       gchar *uid;
+       GVariant *result;
+       const gchar *uid;
        ESource *source;
+       gboolean enabled = FALSE;
        gboolean disable = FALSE;
 
        g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return NULL;
 
-       select = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, SELECT_ESOURCE);
-       if (webkit_dom_html_select_element_get_disabled (
-                       WEBKIT_DOM_HTML_SELECT_ELEMENT (select))) {
-               webkit_dom_html_select_element_set_disabled (
-               WEBKIT_DOM_HTML_SELECT_ELEMENT (select), FALSE);
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "SelectIsEnabled",
+                       g_variant_new ("(s)", SELECT_ESOURCE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &enabled);
+               g_variant_unref (result);
+       }
+
+       if (enabled) {
+               result = g_dbus_proxy_call_sync (
+                               view->priv->web_extension,
+                               "EnableSelect",
+                               g_variant_new ("(sb)", SELECT_ESOURCE, TRUE),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
+
+               if (result)
+                       g_variant_unref (result);
+
                disable = TRUE;
        }
 
-       uid = webkit_dom_html_select_element_get_value (
-               WEBKIT_DOM_HTML_SELECT_ELEMENT (select));
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "SelectGetValue",
+                       g_variant_new ("(s)", SELECT_ESOURCE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
 
-       source = e_source_registry_ref_source (view->priv->registry, uid);
+       if (result) {
+               uid = g_variant_get_string (result, NULL);
+               g_variant_unref (result);
+       }
 
-       g_free (uid);
+       source = e_source_registry_ref_source (view->priv->registry, uid);
 
        if (disable) {
-               webkit_dom_html_select_element_set_disabled (
-                       WEBKIT_DOM_HTML_SELECT_ELEMENT (select), TRUE);
+               result = g_dbus_proxy_call_sync (
+                               view->priv->web_extension,
+                               "EnableSelect",
+                               g_variant_new ("(sb)", SELECT_ESOURCE, FALSE),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
        }
 
        return source;
@@ -2618,201 +2754,150 @@ void
 itip_view_set_rsvp (ItipView *view,
                     gboolean rsvp)
 {
-       WebKitDOMElement *el;
+       GVariant *result;
 
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return;
 
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_RSVP);
-       webkit_dom_html_input_element_set_checked (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), rsvp);
+       input_set_checked (view, CHECKBOX_RSVP, rsvp);
 
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
-       webkit_dom_html_text_area_element_set_disabled (
-               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp);
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "EnableTextArea",
+                       g_variant_new ("(sb)", TEXTAREA_RSVP_COMMENT, !rsvp),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
 }
 
 gboolean
 itip_view_get_rsvp (ItipView *view)
 {
-       WebKitDOMElement *el;
-
        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-       if (!view->priv->dom_document)
-               return FALSE;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_RSVP);
-       return webkit_dom_html_input_element_get_checked (WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
+       return input_is_checked (view, CHECKBOX_RSVP);
 }
 
 void
 itip_view_set_show_rsvp_check (ItipView *view,
                                gboolean show)
 {
-       WebKitDOMElement *label;
-       WebKitDOMElement *el;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
-               return;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, "table_row_" CHECKBOX_RSVP);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_RSVP);
-       label = webkit_dom_element_get_next_element_sibling (el);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
-
-       if (!show) {
-               webkit_dom_html_input_element_set_checked (
-                       WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
-       }
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_RSVP_COMMENT);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
+       show_checkbox (view, CHECKBOX_RSVP, show, FALSE);
+       hide_element (view, TABLE_ROW_RSVP_COMMENT, !show);
 }
 
 gboolean
 itip_view_get_show_rsvp_check (ItipView *view)
 {
-       WebKitDOMElement *el;
-
        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-       if (!view->priv->dom_document)
-               return FALSE;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_RSVP);
-       return !webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el));
+       return !element_is_hidden (view, CHECKBOX_RSVP);
 }
 
 void
 itip_view_set_update (ItipView *view,
                       gboolean update)
 {
-       WebKitDOMElement *el;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
-               return;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_UPDATE);
-
-       webkit_dom_html_input_element_set_checked (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), update);
+       input_set_checked (view, CHECKBOX_UPDATE, update);
 }
 
 gboolean
 itip_view_get_update (ItipView *view)
 {
-       WebKitDOMElement *el;
 
        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-       if (!view->priv->dom_document)
-               return FALSE;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_UPDATE);
-       return webkit_dom_html_input_element_get_checked (WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
+       return input_is_checked (view, CHECKBOX_UPDATE);
 }
 
 void
 itip_view_set_show_update_check (ItipView *view,
                                  gboolean show)
 {
-       WebKitDOMElement *label;
-       WebKitDOMElement *el;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
-               return;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, "table_row_" CHECKBOX_UPDATE);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_UPDATE);
-       label = webkit_dom_element_get_next_element_sibling (el);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
-
-       if (!show) {
-               webkit_dom_html_input_element_set_checked (
-                       WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
-       }
+       show_checkbox (view, CHECKBOX_UPDATE, show, FALSE);
 }
 
 gboolean
 itip_view_get_show_update_check (ItipView *view)
 {
-       WebKitDOMElement *el;
-
        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-       if (!view->priv->dom_document)
-               return FALSE;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_UPDATE);
-       return !webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el));
+       return !element_is_hidden (view, CHECKBOX_UPDATE);
 }
 
 void
 itip_view_set_rsvp_comment (ItipView *view,
                             const gchar *comment)
 {
-       WebKitDOMElement *el;
+       GVariant *result;
 
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return;
 
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (el), (comment == NULL));
+       hide_element (view, TEXTAREA_RSVP_COMMENT, (comment == NULL));
 
        if (comment) {
-               webkit_dom_html_text_area_element_set_value (
-                       WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), comment);
+               result = g_dbus_proxy_call_sync (
+                               view->priv->web_extension,
+                               "TextAreaSetValue",
+                               g_variant_new (
+                                       "(ss)", TEXTAREA_RSVP_COMMENT, comment),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
+
+               if (result)
+                       g_variant_unref (result);
        }
 }
 
-gchar *
+const gchar *
 itip_view_get_rsvp_comment (ItipView *view)
 {
-       WebKitDOMElement *el;
+       GVariant *result;
 
        g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return NULL;
 
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
-
-       if (webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el))) {
+       if (element_is_hidden (view, TEXTAREA_RSVP_COMMENT))
                return NULL;
+
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "TextAreaGetValue",
+                       g_variant_new (
+                               "(s)", TEXTAREA_RSVP_COMMENT),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result) {
+               const gchar *value;
+
+               value = g_variant_get_string (result, NULL);
+               g_variant_unref (result);
+               return value;
        }
 
-       return webkit_dom_html_text_area_element_get_value (
-               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el));
+       return NULL;
 }
 
 void
@@ -2828,7 +2913,7 @@ void
 itip_view_set_buttons_sensitive (ItipView *view,
                                  gboolean sensitive)
 {
-       WebKitDOMElement *el, *cell;
+       GVariant *result;
 
        g_return_if_fail (ITIP_IS_VIEW (view));
 
@@ -2836,56 +2921,20 @@ itip_view_set_buttons_sensitive (ItipView *view,
 
        view->priv->buttons_sensitive = sensitive;
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return;
 
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_UPDATE);
-       webkit_dom_html_input_element_set_disabled (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_RECUR);
-       webkit_dom_html_input_element_set_disabled (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_FREE_TIME);
-       webkit_dom_html_input_element_set_disabled (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_KEEP_ALARM);
-       webkit_dom_html_input_element_set_disabled (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
-       webkit_dom_html_input_element_set_disabled (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_RSVP);
-       webkit_dom_html_input_element_set_disabled (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
-       webkit_dom_html_text_area_element_set_disabled (
-               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !sensitive);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, TABLE_ROW_BUTTONS);
-       cell = webkit_dom_element_get_first_element_child (el);
-       do {
-               WebKitDOMElement *btn;
-               btn = webkit_dom_element_get_first_element_child (cell);
-               if (!webkit_dom_html_element_get_hidden (
-                       WEBKIT_DOM_HTML_ELEMENT (btn))) {
-                       webkit_dom_html_button_element_set_disabled (
-                               WEBKIT_DOM_HTML_BUTTON_ELEMENT (btn), !sensitive);
-               }
-       } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL);
+       result = g_dbus_proxy_call_sync (
+                       view->priv->web_extension,
+                       "SetButtonsSensitive",
+                       g_variant_new ("(b)", sensitive),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
 }
 
 gboolean
@@ -2899,193 +2948,69 @@ itip_view_get_buttons_sensitive (ItipView *view)
 gboolean
 itip_view_get_recur_check_state (ItipView *view)
 {
-       WebKitDOMElement *el;
-
        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-       if (!view->priv->dom_document)
-               return FALSE;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_RECUR);
-       return webkit_dom_html_input_element_get_checked (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
+       return input_is_checked (view, CHECKBOX_RECUR);
 }
 
 void
 itip_view_set_show_recur_check (ItipView *view,
                                 gboolean show)
 {
-       WebKitDOMElement *label;
-       WebKitDOMElement *el;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
-               return;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, "table_row_" CHECKBOX_RECUR);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_RECUR);
-       label = webkit_dom_element_get_next_element_sibling (el);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
-
-       if (!show) {
-               webkit_dom_html_input_element_set_checked (
-                       WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
-       }
-
-        /* and update state of the second check */
-       alarm_check_toggled_cb (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
-               NULL, view);
+       show_checkbox (view, CHECKBOX_RECUR, show, TRUE);
 }
 
 void
 itip_view_set_show_free_time_check (ItipView *view,
                                     gboolean show)
 {
-       WebKitDOMElement *label;
-       WebKitDOMElement *el;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
-               return;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, "table_row_" CHECKBOX_FREE_TIME);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_FREE_TIME);
-       label = webkit_dom_element_get_next_element_sibling (el);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
-
-       if (!show) {
-               webkit_dom_html_input_element_set_checked (
-                       WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
-       }
-
-        /* and update state of the second check */
-       alarm_check_toggled_cb (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
-               NULL, view);
+       show_checkbox (view, CHECKBOX_FREE_TIME, show, TRUE);
 }
 
 gboolean
 itip_view_get_free_time_check_state (ItipView *view)
 {
-       WebKitDOMElement *el;
-
        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-       if (!view->priv->dom_document)
-               return FALSE;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_FREE_TIME);
-       return webkit_dom_html_input_element_get_checked (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
+       return input_is_checked (view, CHECKBOX_FREE_TIME);
 }
 
 void
 itip_view_set_show_keep_alarm_check (ItipView *view,
                                      gboolean show)
 {
-       WebKitDOMElement *label;
-       WebKitDOMElement *el;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
-               return;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, "table_row_" CHECKBOX_KEEP_ALARM);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_KEEP_ALARM);
-       label = webkit_dom_element_get_next_element_sibling (el);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
-
-       if (!show) {
-               webkit_dom_html_input_element_set_checked (
-                       WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
-       }
-
-        /* and update state of the second check */
-       alarm_check_toggled_cb (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
-               NULL, view);
+       show_checkbox (view, CHECKBOX_KEEP_ALARM, show, TRUE);
 }
 
 gboolean
 itip_view_get_keep_alarm_check_state (ItipView *view)
 {
-       WebKitDOMElement *el;
-
        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-       if (!view->priv->dom_document)
-               return FALSE;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_KEEP_ALARM);
-       return webkit_dom_html_input_element_get_checked (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
+       return input_is_checked (view, CHECKBOX_KEEP_ALARM);
 }
 
 void
 itip_view_set_show_inherit_alarm_check (ItipView *view,
                                         gboolean show)
 {
-       WebKitDOMElement *label;
-       WebKitDOMElement *el;
-
        g_return_if_fail (ITIP_IS_VIEW (view));
 
-       if (!view->priv->dom_document)
-               return;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, "table_row_" CHECKBOX_INHERIT_ALARM);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
-       label = webkit_dom_element_get_next_element_sibling (el);
-       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
-
-       if (!show) {
-               webkit_dom_html_input_element_set_checked (
-                       WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
-       }
-
-       /* and update state of the second check */
-       alarm_check_toggled_cb (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
-               NULL, view);
+       show_checkbox (view, CHECKBOX_INHERIT_ALARM, show, TRUE);
 }
 
 gboolean
 itip_view_get_inherit_alarm_check_state (ItipView *view)
 {
-       WebKitDOMElement *el;
-
        g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
 
-       if (!view->priv->dom_document)
-               return FALSE;
-
-       el = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
-       return webkit_dom_html_input_element_get_checked (
-               WEBKIT_DOM_HTML_INPUT_ELEMENT (el));
+       return input_is_checked (view, CHECKBOX_INHERIT_ALARM);
 }
 
 void
@@ -3093,7 +3018,6 @@ itip_view_set_error (ItipView *view,
                      const gchar *error_html,
                      gboolean show_save_btn)
 {
-       WebKitDOMElement *content, *error;
        GString *str;
 
        g_return_if_fail (ITIP_IS_VIEW (view));
@@ -3117,34 +3041,30 @@ itip_view_set_error (ItipView *view,
        view->priv->error = str->str;
        g_string_free (str, FALSE);
 
-       if (!view->priv->dom_document)
+       if (!view->priv->web_extension)
                return;
 
-       content = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, DIV_ITIP_CONTENT);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (content), TRUE);
-
-       error = webkit_dom_document_get_element_by_id (
-               view->priv->dom_document, DIV_ITIP_ERROR);
-       webkit_dom_html_element_set_hidden (
-               WEBKIT_DOM_HTML_ELEMENT (error), FALSE);
-
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (error), view->priv->error, NULL);
+       hide_element (view, DIV_ITIP_CONTENT, TRUE);
+       hide_element (view, DIV_ITIP_ERROR, FALSE);
+       set_inner_html (view, DIV_ITIP_ERROR, view->priv->error);
 
        if (show_save_btn) {
-               WebKitDOMElement *el;
+               GVariant *result;
 
                show_button (view, BUTTON_SAVE);
+               enable_button (view, BUTTON_SAVE, TRUE);
+
+               result = g_dbus_proxy_call_sync (
+                               view->priv->web_extension,
+                               "BindSaveButton",
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
 
-               el = webkit_dom_document_get_element_by_id (
-                       view->priv->dom_document, BUTTON_SAVE);
-               webkit_dom_html_button_element_set_disabled (
-                       WEBKIT_DOM_HTML_BUTTON_ELEMENT (el), FALSE);
-               webkit_dom_event_target_add_event_listener (
-                       WEBKIT_DOM_EVENT_TARGET (el), "click",
-                       G_CALLBACK (button_clicked_cb), FALSE, view);
+               if (result)
+                       g_variant_unref (result);
        }
 }
 
@@ -3570,14 +3490,7 @@ set_buttons_sensitive (EMailPartItip *pitip,
                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
                        _("Attendee status updated"));
 
-               if (view->priv->dom_document) {
-                       WebKitDOMElement *el;
-
-                       el = webkit_dom_document_get_element_by_id (
-                               view->priv->dom_document, BUTTON_UPDATE_ATTENDEE_STATUS);
-                       webkit_dom_html_button_element_set_disabled (
-                               WEBKIT_DOM_HTML_BUTTON_ELEMENT (el), TRUE);
-               }
+               enable_button (view, BUTTON_UPDATE_ATTENDEE_STATUS, FALSE);
        }
 }
 
@@ -4544,7 +4457,7 @@ finish_message_delete_with_rsvp (EMailPartItip *pitip,
                icalproperty *prop;
                icalvalue *value;
                const gchar *attendee;
-               gchar *comment;
+               const gchar *comment;
                GSList *l, *list = NULL;
                gboolean found;
 
@@ -4603,8 +4516,6 @@ finish_message_delete_with_rsvp (EMailPartItip *pitip,
                        comments.next = NULL;
 
                        e_cal_component_set_comment_list (comp, &comments);
-
-                       g_free (comment);
                }
 
                e_cal_component_rescan (comp);
@@ -5015,14 +4926,7 @@ modify_object_cb (GObject *ecalclient,
                        view, ITIP_VIEW_INFO_ITEM_TYPE_INFO,
                        _("Attendee status updated"));
 
-               if (view->priv->dom_document) {
-                       WebKitDOMElement *el;
-
-                       el = webkit_dom_document_get_element_by_id (
-                               view->priv->dom_document, BUTTON_UPDATE_ATTENDEE_STATUS);
-                       webkit_dom_html_button_element_set_disabled (
-                               WEBKIT_DOM_HTML_BUTTON_ELEMENT (el), TRUE);
-               }
+               enable_button (view, BUTTON_UPDATE_ATTENDEE_STATUS, FALSE);
 
                if (pitip->delete_message && pitip->folder)
                        camel_folder_delete_message (pitip->folder, pitip->uid);
@@ -6255,13 +6159,8 @@ itip_view_init_view (ItipView *view)
                        find_server (info, view, info->comp);
                        set_buttons_sensitive (info, view);
                }
-       } else if (view->priv->dom_document) {
+       } else if (view->priv->web_extension) {
                /* The Open Calendar button can be shown, thus enable it */
-               WebKitDOMElement *el;
-
-               el = webkit_dom_document_get_element_by_id (
-                       view->priv->dom_document, BUTTON_OPEN_CALENDAR);
-               webkit_dom_html_button_element_set_disabled (
-                       WEBKIT_DOM_HTML_BUTTON_ELEMENT (el), FALSE);
+               enable_button (view, BUTTON_OPEN_CALENDAR, TRUE);
        }
 }
diff --git a/modules/itip-formatter/itip-view.h b/modules/itip-formatter/itip-view.h
index 3dac415..07aa7ea 100644
--- a/modules/itip-formatter/itip-view.h
+++ b/modules/itip-formatter/itip-view.h
@@ -28,7 +28,6 @@
 #include <unistd.h>
 
 #include <gtk/gtk.h>
-#include <webkit/webkitdom.h>
 
 #include <libecal/libecal.h>
 
@@ -118,7 +117,7 @@ void                itip_view_write                 (EMailFormatter *formatter,
 void           itip_view_write_for_printing    (ItipView *view,
                                                 GString *buffer);
 void           itip_view_create_dom_bindings   (ItipView *view,
-                                                WebKitDOMElement *element);
+                                                const gchar *element_id);
 struct _EMailPartItip *
                itip_view_get_mail_part         (ItipView *view);
 EClientCache * itip_view_get_client_cache      (ItipView *view);
@@ -218,7 +217,7 @@ void                itip_view_set_update            (ItipView *view,
 gboolean       itip_view_get_show_update_check (ItipView *view);
 void           itip_view_set_show_update_check (ItipView *view,
                                                 gboolean show);
-gchar *                itip_view_get_rsvp_comment      (ItipView *view);
+const gchar *  itip_view_get_rsvp_comment      (ItipView *view);
 void           itip_view_set_rsvp_comment      (ItipView *view,
                                                 const gchar *comment);
 gboolean       itip_view_get_buttons_sensitive (ItipView *view);
@@ -247,7 +246,8 @@ void                itip_view_set_show_inherit_alarm_check
 void           itip_view_set_error             (ItipView *view,
                                                 const gchar *error_html,
                                                 gboolean show_save_btn);
-
+GDBusProxy *   itip_view_get_web_extension_proxy
+                                               (ItipView *view);
 G_END_DECLS
 
 #endif /* ITIP_VIEW_H */
diff --git a/modules/itip-formatter/module-itip-formatter-dom-utils.c 
b/modules/itip-formatter/module-itip-formatter-dom-utils.c
new file mode 100644
index 0000000..5ff322a
--- /dev/null
+++ b/modules/itip-formatter/module-itip-formatter-dom-utils.c
@@ -0,0 +1,710 @@
+/*
+ * module-itip-formatter-dom-utils.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 "module-itip-formatter-dom-utils.h"
+
+#include "web-extension/module-itip-formatter-web-extension.h"
+#include "itip-view-elements-defines.h"
+
+#include "../../e-util/e-dom-utils.h"
+
+void
+module_itip_formatter_dom_utils_show_button (WebKitDOMDocument *document,
+                                             const gchar *button_id)
+{
+       WebKitDOMElement *button;
+
+       button = webkit_dom_document_get_element_by_id (document, button_id);
+       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (button), FALSE);
+}
+
+void
+module_itip_formatter_dom_utils_enable_button (WebKitDOMDocument *document,
+                                               const gchar *button_id,
+                                               gboolean enable)
+{
+       WebKitDOMElement *el;
+
+       el = webkit_dom_document_get_element_by_id (document, button_id);
+       webkit_dom_html_button_element_set_disabled (
+               WEBKIT_DOM_HTML_BUTTON_ELEMENT (el), !enable);
+}
+
+static void
+recur_toggled_cb (WebKitDOMHTMLInputElement *input,
+                  WebKitDOMEvent *event,
+                  GDBusConnection *connection)
+{
+       GError *error = NULL;
+
+       g_dbus_connection_emit_signal (
+               connection,
+               NULL,
+               MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+               MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+               "RecurToggled",
+               NULL,
+               &error);
+
+       if (error) {
+               g_warning ("Error emitting signal RecurToggled: %s\n", error->message);
+               g_error_free (error);
+       }
+}
+
+static void
+source_changed_cb (WebKitDOMElement *element,
+                   WebKitDOMEvent *event,
+                   GDBusConnection *connection)
+{
+       GError *error = NULL;
+
+       g_dbus_connection_emit_signal (
+               connection,
+               NULL,
+               MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+               MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+               "SourceChanged",
+               NULL,
+               &error);
+
+       if (error) {
+               g_warning ("Error emitting signal SourceChanged: %s\n", error->message);
+               g_error_free (error);
+       }
+}
+
+static void
+button_clicked_cb (WebKitDOMElement *element,
+                   WebKitDOMEvent *event,
+                   GDBusConnection *connection)
+{
+       GError *error = NULL;
+       gchar *button_value;
+
+       button_value = webkit_dom_html_button_element_get_value (
+               WEBKIT_DOM_HTML_BUTTON_ELEMENT (element));
+
+       g_dbus_connection_emit_signal (
+               connection,
+               NULL,
+               MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH,
+               MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE,
+               "ButtonClicked",
+               g_variant_new ("(s)", button_value),
+               &error);
+
+       if (error) {
+               g_warning ("Error emitting signal ButtonClicked: %s\n", error->message);
+               g_error_free (error);
+       }
+
+       g_free (button_value);
+}
+
+static void
+rsvp_toggled_cb (WebKitDOMHTMLInputElement *input,
+                 WebKitDOMEvent *event,
+                 GDBusConnection *connection)
+{
+       WebKitDOMElement *el;
+       WebKitDOMDocument *document;
+       gboolean rsvp;
+
+               document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (input));
+       rsvp = webkit_dom_html_input_element_get_checked (input);
+       el = webkit_dom_document_get_element_by_id (
+               document, TEXTAREA_RSVP_COMMENT);
+       webkit_dom_html_text_area_element_set_disabled (
+               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp);
+}
+
+/**
+  alarm_check_toggled_cb
+  check1 was changed, so make the second available based on state of the first check.
+*/
+static void
+alarm_check_toggled_cb (WebKitDOMHTMLInputElement *check1,
+                        WebKitDOMEvent *event,
+                        GDBusConnection *connection)
+{
+       WebKitDOMDocument *document;
+       WebKitDOMElement *check2;
+       gchar *id;
+
+               document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (check1));
+
+       id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (check1));
+
+       if (g_strcmp0 (id, CHECKBOX_INHERIT_ALARM)) {
+               check2 = webkit_dom_document_get_element_by_id (
+                       document, CHECKBOX_KEEP_ALARM);
+       } else {
+               check2 = webkit_dom_document_get_element_by_id (
+                       document, CHECKBOX_INHERIT_ALARM);
+       }
+
+       g_free (id);
+
+       webkit_dom_html_input_element_set_disabled (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (check2),
+               (webkit_dom_html_element_get_hidden (
+                               WEBKIT_DOM_HTML_ELEMENT (check1)) &&
+                       webkit_dom_html_input_element_get_checked (check1)));
+}
+
+void
+module_itip_formatter_dom_utils_create_dom_bindings (WebKitDOMDocument *document,
+                                                     GDBusConnection *connection)
+{
+       WebKitDOMElement *el;
+
+       el = webkit_dom_document_get_element_by_id (document, CHECKBOX_RECUR);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (recur_toggled_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, CHECKBOX_RSVP);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (rsvp_toggled_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, CHECKBOX_INHERIT_ALARM);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (alarm_check_toggled_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, CHECKBOX_KEEP_ALARM);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (alarm_check_toggled_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_OPEN_CALENDAR);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_ACCEPT);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_ACCEPT_ALL);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_TENTATIVE);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_TENTATIVE_ALL);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_DECLINE);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_DECLINE_ALL);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_UPDATE);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_UPDATE_ATTENDEE_STATUS);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_SEND_INFORMATION);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+
+       el = webkit_dom_document_get_element_by_id (document, SELECT_ESOURCE);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "change",
+                       G_CALLBACK (source_changed_cb), FALSE, connection);
+       }
+}
+
+void
+module_itip_formatter_dom_utils_bind_save_button (WebKitDOMDocument *document,
+                                                  GDBusConnection *connection)
+{
+       WebKitDOMElement *el;
+
+       el = webkit_dom_document_get_element_by_id (document, BUTTON_SAVE);
+       if (el) {
+               webkit_dom_event_target_add_event_listener (
+                       WEBKIT_DOM_EVENT_TARGET (el), "click",
+                       G_CALLBACK (button_clicked_cb), FALSE, connection);
+       }
+}
+
+gboolean
+module_itip_formatter_dom_utils_input_is_checked (WebKitDOMDocument *document,
+                                                  const gchar *input_id)
+{
+       WebKitDOMElement *element;
+
+       element = webkit_dom_document_get_element_by_id (document, input_id);
+
+       if (!element)
+               return FALSE;
+
+       return webkit_dom_html_input_element_get_checked (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (element));
+}
+
+void
+module_itip_formatter_dom_utils_input_set_checked (WebKitDOMDocument *document,
+                                                   const gchar *input_id,
+                                                   gboolean checked)
+{
+       WebKitDOMElement *element;
+
+       element = webkit_dom_document_get_element_by_id (document, input_id);
+
+       if (!element)
+               return;
+
+       webkit_dom_html_input_element_set_checked (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (element), checked);
+}
+
+void
+module_itip_formatter_dom_utils_show_checkbox (WebKitDOMDocument *document,
+                                               const gchar *id,
+                                               gboolean show,
+                                              gboolean update_second)
+{
+       WebKitDOMElement *label;
+       WebKitDOMElement *el;
+
+       el = webkit_dom_document_get_element_by_id (
+               document, id);
+       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
+
+       el = webkit_dom_document_get_element_by_id (
+               document, id);
+       label = webkit_dom_element_get_next_element_sibling (el);
+       webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show);
+
+       if (!show) {
+               webkit_dom_html_input_element_set_checked (
+                       WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE);
+       }
+
+       if (update_second) {
+               /* and update state of the second check */
+               alarm_check_toggled_cb (
+                       WEBKIT_DOM_HTML_INPUT_ELEMENT (el),
+                       NULL, NULL);
+       }
+}
+
+void
+module_itip_formatter_dom_utils_set_buttons_sensitive (WebKitDOMDocument *document,
+                                                       gboolean sensitive)
+{
+       WebKitDOMElement *el, *cell;
+
+       el = webkit_dom_document_get_element_by_id (
+               document, CHECKBOX_UPDATE);
+       webkit_dom_html_input_element_set_disabled (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+       el = webkit_dom_document_get_element_by_id (
+               document, CHECKBOX_RECUR);
+       webkit_dom_html_input_element_set_disabled (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+       el = webkit_dom_document_get_element_by_id (
+               document, CHECKBOX_FREE_TIME);
+       webkit_dom_html_input_element_set_disabled (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+       el = webkit_dom_document_get_element_by_id (
+               document, CHECKBOX_KEEP_ALARM);
+       webkit_dom_html_input_element_set_disabled (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+       el = webkit_dom_document_get_element_by_id (
+               document, CHECKBOX_INHERIT_ALARM);
+       webkit_dom_html_input_element_set_disabled (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+       el = webkit_dom_document_get_element_by_id (
+               document, CHECKBOX_RSVP);
+       webkit_dom_html_input_element_set_disabled (
+               WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive);
+
+       el = webkit_dom_document_get_element_by_id (
+               document, TEXTAREA_RSVP_COMMENT);
+       webkit_dom_html_text_area_element_set_disabled (
+               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !sensitive);
+
+       el = webkit_dom_document_get_element_by_id (
+               document, TABLE_ROW_BUTTONS);
+       cell = webkit_dom_element_get_first_element_child (el);
+       do {
+               WebKitDOMElement *btn;
+               btn = webkit_dom_element_get_first_element_child (cell);
+               if (!webkit_dom_html_element_get_hidden (
+                       WEBKIT_DOM_HTML_ELEMENT (btn))) {
+                       webkit_dom_html_button_element_set_disabled (
+                               WEBKIT_DOM_HTML_BUTTON_ELEMENT (btn), !sensitive);
+               }
+       } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL);
+}
+
+void
+module_itip_formatter_dom_utils_set_area_text (WebKitDOMDocument *document,
+                                               const gchar *area_id,
+                                               const gchar *text)
+{
+       WebKitDOMElement *row, *col;
+
+       row = webkit_dom_document_get_element_by_id (document, area_id);
+       webkit_dom_html_element_set_hidden (
+               WEBKIT_DOM_HTML_ELEMENT (row), (g_strcmp0 (text, "") == 0));
+
+       col = webkit_dom_element_get_last_element_child (row);
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (col),
+               text,
+               NULL);
+}
+
+void
+module_itip_formatter_dom_utils_element_set_access_key (WebKitDOMDocument *document,
+                                                        const gchar *element_id,
+                                                        const gchar *access_key)
+{
+       WebKitDOMElement *element;
+
+       element = webkit_dom_document_get_element_by_id (document, element_id);
+
+       if (!element)
+               return;
+
+       webkit_dom_html_element_set_access_key (
+               WEBKIT_DOM_HTML_ELEMENT (element), access_key);
+}
+
+void
+module_itip_formatter_dom_utils_element_hide_child_nodes (WebKitDOMDocument *document,
+                                                          const gchar *element_id)
+{
+       WebKitDOMElement *element, *cell, *button;
+
+       element = webkit_dom_document_get_element_by_id (document, element_id);
+
+       if (!element)
+               return;
+
+       element = webkit_dom_document_get_element_by_id (document, element_id);
+       cell = webkit_dom_element_get_first_element_child (element);
+       do {
+               button = webkit_dom_element_get_first_element_child (cell);
+               webkit_dom_html_element_set_hidden (
+                       WEBKIT_DOM_HTML_ELEMENT (button), TRUE);
+       } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL);
+}
+
+void
+module_itip_formatter_dom_utils_enable_select (WebKitDOMDocument *document,
+                                               const gchar *select_id,
+                                               gboolean enabled)
+{
+       WebKitDOMElement *element;
+
+       element = webkit_dom_document_get_element_by_id (document, select_id);
+
+       if (!element)
+               return;
+
+       webkit_dom_html_select_element_set_disabled (
+               WEBKIT_DOM_HTML_SELECT_ELEMENT (element), !enabled);
+}
+
+gboolean
+module_itip_formatter_dom_utils_select_is_enabled (WebKitDOMDocument *document,
+                                                   const gchar *select_id)
+{
+       WebKitDOMElement *element;
+
+       element = webkit_dom_document_get_element_by_id (document, select_id);
+
+       if (!element)
+               return FALSE;
+
+       return !webkit_dom_html_select_element_get_disabled (
+               WEBKIT_DOM_HTML_SELECT_ELEMENT (element));
+}
+
+gchar *
+module_itip_formatter_dom_utils_select_get_value (WebKitDOMDocument *document,
+                                                  const gchar *select_id)
+{
+       WebKitDOMElement *element;
+
+       element = webkit_dom_document_get_element_by_id (document, select_id);
+
+       if (!element)
+               return NULL;
+
+       return webkit_dom_html_select_element_get_value (
+               WEBKIT_DOM_HTML_SELECT_ELEMENT (element));
+}
+
+void
+module_itip_formatter_dom_utils_select_set_selected (WebKitDOMDocument *document,
+                                                     const gchar *select_id,
+                                                     const gchar *option)
+{
+       WebKitDOMElement *element;
+       gint length, ii;
+
+       element = webkit_dom_document_get_element_by_id (document, select_id);
+
+       if (!element)
+               return;
+
+       length = webkit_dom_html_select_element_get_length (
+               WEBKIT_DOM_HTML_SELECT_ELEMENT (select));
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *node;
+               WebKitDOMHTMLOptionElement *option_element;
+               gchar *value;
+
+               node = webkit_dom_html_select_element_item (
+                       WEBKIT_DOM_HTML_SELECT_ELEMENT (select), ii);
+               option_element = WEBKIT_DOM_HTML_OPTION_ELEMENT (node);
+
+               value = webkit_dom_html_option_element_get_value (option_element);
+               if (g_strcmp0 (value, option) == 0) {
+                       webkit_dom_html_option_element_set_selected (
+                               option_element, TRUE);
+
+                       g_free (value);
+                       break;
+               }
+
+               g_free (value);
+       }
+}
+
+void
+module_itip_formatter_dom_utils_update_times (WebKitDOMDocument *document,
+                                              const gchar *element_id,
+                                              const gchar *header,
+                                              const gchar *label)
+{
+       WebKitDOMElement *element, *col;
+
+       element = webkit_dom_document_get_element_by_id (document, element_id);
+
+       if (!element)
+               return;
+
+       webkit_dom_html_element_set_hidden (
+               WEBKIT_DOM_HTML_ELEMENT (element), FALSE);
+
+       col = webkit_dom_element_get_first_element_child (element);
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (col), header, NULL);
+
+       col = webkit_dom_element_get_last_element_child (element);
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (col), label, NULL);
+}
+
+void
+module_itip_formatter_dom_utils_append_info_item_row (WebKitDOMDocument *document,
+                                                      const gchar *table_id,
+                                                      const gchar *row_id,
+                                                      const gchar *icon_name,
+                                                      const gchar *message)
+{
+       WebKitDOMElement *table;
+        WebKitDOMHTMLElement *cell, *row;
+
+       table = webkit_dom_document_get_element_by_id (document, table_id);
+
+       if (!table)
+               return;
+
+       table = webkit_dom_document_get_element_by_id (document, table_id);
+       row = webkit_dom_html_table_element_insert_row (
+               WEBKIT_DOM_HTML_TABLE_ELEMENT (table), -1, NULL);
+
+       webkit_dom_html_element_set_id (row, row_id);
+
+       cell = webkit_dom_html_table_row_element_insert_cell (
+               WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row), -1, NULL);
+
+       if (icon_name) {
+               WebKitDOMElement *image;
+               gchar *icon_uri;
+
+               image = webkit_dom_document_create_element (
+                       document, "IMG", NULL);
+
+               icon_uri = g_strdup_printf ("gtk-stock://%s", icon_name);
+               webkit_dom_html_image_element_set_src (
+                       WEBKIT_DOM_HTML_IMAGE_ELEMENT (image), icon_uri);
+               g_free (icon_uri);
+
+               webkit_dom_node_append_child (
+                       WEBKIT_DOM_NODE (cell),
+                       WEBKIT_DOM_NODE (image),
+                       NULL);
+       }
+
+       cell = webkit_dom_html_table_row_element_insert_cell (
+               WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row), -1, NULL);
+
+       webkit_dom_html_element_set_inner_html (cell, message, NULL);
+}
+
+void
+module_itip_formatter_dom_utils_enable_text_area (WebKitDOMDocument *document,
+                                                  const gchar *area_id,
+                                                  gboolean enable)
+{
+       WebKitDOMElement *el;
+
+       el = webkit_dom_document_get_element_by_id (document, area_id);
+       webkit_dom_html_text_area_element_set_disabled (
+               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !enable);
+}
+
+void
+module_itip_formatter_dom_utils_text_area_set_value (WebKitDOMDocument *document,
+                                                     const gchar *area_id,
+                                                     const gchar *value)
+{
+       WebKitDOMElement *el;
+
+       el = webkit_dom_document_get_element_by_id (document, area_id);
+       webkit_dom_html_text_area_element_set_value (
+               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), value);
+}
+
+gchar *
+module_itip_formatter_dom_utils_text_area_get_value (WebKitDOMDocument *document,
+                                                     const gchar *area_id)
+{
+       WebKitDOMElement *el;
+
+       el = webkit_dom_document_get_element_by_id (document, area_id);
+       return webkit_dom_html_text_area_element_get_value (
+               WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el));
+}
+
+void
+module_itip_formatter_dom_utils_rebuild_source_list (WebKitDOMDocument *document,
+                                                     const gchar *optgroup_id,
+                                                     const gchar *optgroup_label,
+                                                     const gchar *option_id,
+                                                     const gchar *option_label,
+                                                    gboolean writable)
+{
+       WebKitDOMElement *option;
+       WebKitDOMElement *select;
+       WebKitDOMHTMLOptGroupElement *optgroup;
+
+       select = webkit_dom_document_get_element_by_id (document, SELECT_ESOURCE);
+
+       if (!select)
+               return;
+
+       optgroup = WEBKIT_DOM_HTML_OPT_GROUP_ELEMENT (
+                       webkit_dom_document_get_element_by_id (
+                               document, optgroup_id));
+
+       if (!optgroup) {
+               optgroup = WEBKIT_DOM_HTML_OPT_GROUP_ELEMENT (
+                               webkit_dom_document_create_element (
+                                       document, "OPTGROUP", NULL));
+               webkit_dom_html_opt_group_element_set_label (
+                       optgroup, optgroup_label);
+               webkit_dom_node_append_child (
+                       WEBKIT_DOM_NODE (select), WEBKIT_DOM_NODE (optgroup), NULL);
+       }
+
+       option = webkit_dom_document_create_element (document, "OPTION", NULL);
+       webkit_dom_html_option_element_set_value (
+               WEBKIT_DOM_HTML_OPTION_ELEMENT (option), option_id);
+       webkit_dom_html_option_element_set_label (
+               WEBKIT_DOM_HTML_OPTION_ELEMENT (option), option_label);
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (option), option_label, NULL);
+
+       webkit_dom_element_set_class_name (
+               WEBKIT_DOM_ELEMENT (option), "calendar");
+
+       if (!writable) {
+               webkit_dom_html_option_element_set_disabled (
+                       WEBKIT_DOM_HTML_OPTION_ELEMENT (option), TRUE);
+       }
+
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (optgroup),
+               WEBKIT_DOM_NODE (option),
+               NULL);
+}
diff --git a/modules/itip-formatter/module-itip-formatter-dom-utils.h 
b/modules/itip-formatter/module-itip-formatter-dom-utils.h
new file mode 100644
index 0000000..b34e2d2
--- /dev/null
+++ b/modules/itip-formatter/module-itip-formatter-dom-utils.h
@@ -0,0 +1,112 @@
+/*
+ * module-itip-formatter-dom-utils.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 MODULE_ITIP_FORMATTER_DOM_UTILS_H
+#define MODULE_ITIP_FORMATTER_DOM_UTILS_H
+
+#include <webkitdom/webkitdom.h>
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void           module_itip_formatter_dom_utils_show_button
+                                               (WebKitDOMDocument *document,
+                                                const gchar *button_id);
+void           module_itip_formatter_dom_utils_enable_button
+                                               (WebKitDOMDocument *document,
+                                                const gchar *button_id,
+                                                gboolean enable);
+void           module_itip_formatter_dom_utils_create_dom_bindings
+                                               (WebKitDOMDocument *document,
+                                                GDBusConnection *connection);
+void           module_itip_formatter_dom_utils_bind_save_button
+                                               (WebKitDOMDocument *document,
+                                                 GDBusConnection *connection);
+void           module_itip_formatter_dom_utils_input_set_checked
+                                               (WebKitDOMDocument *document,
+                                                const gchar *input_id,
+                                                gboolean checked);
+gboolean       module_itip_formatter_dom_utils_input_is_checked
+                                               (WebKitDOMDocument *document,
+                                                const gchar *input_id);
+void           module_itip_formatter_dom_utils_show_checkbox
+                                               (WebKitDOMDocument *document,
+                                                const gchar *id,
+                                                gboolean show,
+                                                gboolean update_second);
+void           module_itip_formatter_dom_utils_set_buttons_sensitive
+                                               (WebKitDOMDocument *document,
+                                                gboolean sensitive);
+void           module_itip_formatter_dom_utils_set_area_text
+                                               (WebKitDOMDocument *document,
+                                                const gchar *area_id,
+                                                const gchar *text);
+void           module_itip_formatter_dom_utils_element_set_access_key
+                                               (WebKitDOMDocument *document,
+                                                const gchar *element_id,
+                                                const gchar *access_key);
+void           module_itip_formatter_dom_utils_element_hide_child_nodes
+                                               (WebKitDOMDocument *document,
+                                                const gchar *element_id);
+void           module_itip_formatter_dom_utils_enable_select
+                                               (WebKitDOMDocument *document,
+                                                const gchar *select_id,
+                                                gboolean enabled);
+gboolean       module_itip_formatter_dom_utils_select_is_enabled
+                                               (WebKitDOMDocument *document,
+                                                const gchar *select_id);
+gchar *                module_itip_formatter_dom_utils_select_get_value
+                                               (WebKitDOMDocument *document,
+                                                const gchar *select_id);
+void           module_itip_formatter_dom_utils_select_set_selected
+                                               (WebKitDOMDocument *document,
+                                                const gchar *select_id,
+                                                const gchar *option);
+void           module_itip_formatter_dom_utils_update_times
+                                               (WebKitDOMDocument *document,
+                                                const gchar *element_id,
+                                                const gchar *header,
+                                                const gchar *label);
+void           module_itip_formatter_dom_utils_append_info_item_row
+                                               (WebKitDOMDocument *document,
+                                                const gchar *table_id,
+                                                const gchar *row_id,
+                                                const gchar *icon_name,
+                                                const gchar *message);
+void           module_itip_formatter_dom_utils_enable_text_area
+                                               (WebKitDOMDocument *document,
+                                                const gchar *area_id,
+                                                gboolean enable);
+void           module_itip_formatter_dom_utils_text_area_set_value
+                                               (WebKitDOMDocument *document,
+                                                const gchar *area_id,
+                                                const gchar *value);
+gchar *                module_itip_formatter_dom_utils_text_area_get_value
+                                               (WebKitDOMDocument *document,
+                                                const gchar *area_id);
+void           module_itip_formatter_dom_utils_rebuild_source_list
+                                               (WebKitDOMDocument *document,
+                                                const gchar *optgroup_id,
+                                                const gchar *optgroup_label,
+                                                const gchar *option_id,
+                                                const gchar *option_label,
+                                                gboolean writable);
+G_END_DECLS
+
+#endif /* MODULE_ITIP_FORMATTER_DOM_UTILS_H */
diff --git a/modules/itip-formatter/web-extension/Makefile.am 
b/modules/itip-formatter/web-extension/Makefile.am
new file mode 100644
index 0000000..b41ffaa
--- /dev/null
+++ b/modules/itip-formatter/web-extension/Makefile.am
@@ -0,0 +1,23 @@
+webextensions_LTLIBRARIES = libmoduleitipformatterwebextension.la
+
+libmoduleitipformatterwebextension_la_SOURCES =                \
+       module-itip-formatter-web-extension.c           \
+       module-itip-formatter-web-extension.h           \
+       ../module-itip-formatter-dom-utils.c            \
+       ../module-itip-formatter-dom-utils.h            \
+       $(top_srcdir)/e-util/e-dom-utils.c              \
+       $(top_srcdir)/e-util/e-dom-utils.h
+
+libmoduleitipformatterwebextension_la_CPPFLAGS =       \
+       -DWEBEXTENSIONS_COMPILATION                     \
+       -DEVOLUTION_IMAGESDIR=\"${imagesdir}\"          \
+       $(GNOME_PLATFORM_CFLAGS)                        \
+       $(AM_CPPFLAGS)                                  \
+       $(WEB_EXTENSIONS_CFLAGS)
+
+libmoduleitipformatterwebextension_la_LIBADD =         \
+       $(GNOME_PLATFORM_LIBS)                          \
+       $(WEB_EXTENSIONS_LIBS)
+
+libmoduleitipformatterwebextension_la_LDFLAGS =                \
+       -module -avoid-version -no-undefined
diff --git a/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c 
b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
new file mode 100644
index 0000000..6bd2b3b
--- /dev/null
+++ b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
@@ -0,0 +1,628 @@
+/*
+ * module-itip-formatter-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 "module-itip-formatter-web-extension.h"
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <webkit2/webkit-web-extension.h>
+
+#include "../module-itip-formatter-dom-utils.h"
+#include "../../../e-util/e-dom-utils.h"
+
+/* FIXME Clean it */
+static GDBusConnection *dbus_connection;
+
+static const char introspection_xml[] =
+"<node>"
+"  <interface name='org.gnome.Evolution.Module.ItipFormatter.WebExtension'>"
+"    <signal name='RecurToggled'>"
+"    </signal>"
+"    <signal name='SourceChanged'>"
+"    </signal>"
+"    <signal name='ButtonClicked'>"
+"      <arg type='s' name='button_value' direction='out'/>"
+"    </signal>"
+"    <method name='SaveDocumentFromElement'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"    </method>"
+"    <method name='ShowButton'>"
+"      <arg type='s' name='button_id' direction='in'/>"
+"    </method>"
+"    <method name='CreateDOMBindings'>"
+"    </method>"
+"    <method name='ElementSetInnerHTML'>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"      <arg type='s' name='inner_html' direction='in'/>"
+"    </method>"
+"    <method name='RemoveElement'>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"    </method>"
+"    <method name='ElementRemoveChildNodes'>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"    </method>"
+"    <method name='EnableButton'>"
+"      <arg type='s' name='button_id' direction='in'/>"
+"      <arg type='b' name='enable' direction='in'/>"
+"    </method>"
+"    <method name='ElementIsHidden'>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"      <arg type='b' name='is_hidden' direction='out'/>"
+"    </method>"
+"    <method name='HideElement'>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"      <arg type='b' name='hide' direction='in'/>"
+"    </method>"
+"    <method name='BindSaveButton'>"
+"    </method>"
+"    <method name='InputSetChecked'>"
+"      <arg type='s' name='input_id' direction='in'/>"
+"      <arg type='b' name='checked' direction='in'/>"
+"    </method>"
+"    <method name='InputIsChecked'>"
+"      <arg type='s' name='input_id' direction='in'/>"
+"      <arg type='b' name='checked' direction='out'/>"
+"    </method>"
+"    <method name='ShowCheckbox'>"
+"      <arg type='s' name='id' direction='in'/>"
+"      <arg type='b' name='show' direction='in'/>"
+"      <arg type='b' name='update_second' direction='in'/>"
+"    </method>"
+"    <method name='SetButtonsSensitive'>"
+"      <arg type='b' name='sensitive' direction='in'/>"
+"    </method>"
+"    <method name='SetAreaText'>"
+"      <arg type='s' name='id' direction='in'/>"
+"      <arg type='s' name='text' direction='in'/>"
+"    </method>"
+"    <method name='ElementSetAccessKey'>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"      <arg type='s' name='access_key' direction='in'/>"
+"    </method>"
+"    <method name='ElementHideChildNodes'>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"    </method>"
+"    <method name='EnableSelect'>"
+"      <arg type='s' name='select_id' direction='in'/>"
+"      <arg type='b' name='enable' direction='in'/>"
+"    </method>"
+"    <method name='SelectIsEnabled'>"
+"      <arg type='s' name='select_id' direction='in'/>"
+"      <arg type='b' name='enable' direction='out'/>"
+"    </method>"
+"    <method name='SelectGetValue'>"
+"      <arg type='s' name='select_id' direction='in'/>"
+"      <arg type='s' name='value' direction='out'/>"
+"    </method>"
+"    <method name='SelectSetSelected'>"
+"      <arg type='s' name='select_id' direction='in'/>"
+"      <arg type='s' name='option' direction='in'/>"
+"    </method>"
+"    <method name='UpdateTimes'>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"      <arg type='s' name='header' direction='in'/>"
+"      <arg type='s' name='label' direction='in'/>"
+"    </method>"
+"    <method name='AppendInfoItemRow'>"
+"      <arg type='s' name='table_id' direction='in'/>"
+"      <arg type='s' name='row_id' direction='in'/>"
+"      <arg type='s' name='icon_name' direction='in'/>"
+"      <arg type='s' name='message' direction='in'/>"
+"    </method>"
+"    <method name='EnableTextArea'>"
+"      <arg type='s' name='area_id' direction='in'/>"
+"      <arg type='b' name='enable' direction='in'/>"
+"    </method>"
+"    <method name='TextAreaSetValue'>"
+"      <arg type='s' name='area_id' direction='in'/>"
+"      <arg type='s' name='value' direction='in'/>"
+"    </method>"
+"    <method name='TextAreaGetValue'>"
+"      <arg type='s' name='area_id' direction='in'/>"
+"      <arg type='s' name='value' direction='out'/>"
+"    </method>"
+"    <method name='RebuildSourceList'>"
+"      <arg type='s' name='optgroup_id' direction='in'/>"
+"      <arg type='s' name='optgroup_label' direction='in'/>"
+"      <arg type='s' name='option_id' direction='in'/>"
+"      <arg type='s' name='option_label' direction='in'/>"
+"      <arg type='b' name='writable' direction='in'/>"
+"    </method>"
+"  </interface>"
+"</node>";
+
+static WebKitDOMDocument *document_saved = NULL;
+
+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, MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE) != 0)
+               return;
+
+       if (g_strcmp0 (method_name, "SaveDocumentFromElement") == 0) {
+               WebKitDOMElement *element;
+               const gchar *element_id;
+
+               g_variant_get (parameters, "(t&s)", &page_id, &element_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);
+               document_saved = document;
+
+               element = e_dom_utils_find_element_by_id (document, element_id);
+
+               if (!WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element))
+                       element = webkit_dom_element_query_selector (
+                               element, "iframe", NULL);
+
+               if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element))
+                       document_saved =
+                               webkit_dom_html_iframe_element_get_content_document (
+                                       WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
+               else
+                       document_saved = document;
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "ShowButton") == 0) {
+               const gchar *button_id;
+
+               button_id = g_variant_get_string (parameters, NULL);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_show_button (document_saved, button_id);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "EnableButton") == 0) {
+               const gchar *button_id;
+               gboolean enable;
+
+               g_variant_get (parameters, "(&sb)", &button_id, &enable);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_enable_button (
+                       document_saved, button_id, enable);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "CreateDOMBindings") == 0) {
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_create_dom_bindings (
+                       document_saved, connection);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "ElementSetInnerHTML") == 0) {
+               const gchar *element_id, *inner_html;
+
+               g_variant_get (parameters, "(&s&s)", &element_id, &inner_html);
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               e_dom_utils_element_set_inner_html (
+                       document_saved, element_id, inner_html);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "RemoveElement") == 0) {
+               const gchar *element_id;
+
+               element_id = g_variant_get_string (parameters, NULL);
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               e_dom_utils_remove_element (document_saved, element_id);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "ElementRemoveChildNodes") == 0) {
+               const gchar *element_id;
+
+               element_id = g_variant_get_string (parameters, NULL);
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               e_dom_utils_element_remove_child_nodes (document_saved, element_id);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "HideElement") == 0) {
+               const gchar *element_id;
+               gboolean hide;
+
+               g_variant_get (parameters, "(&sb)", &element_id, &hide);
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               e_dom_utils_hide_element (document_saved, element_id, hide);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "ElementIsHidden") == 0) {
+               const gchar *element_id;
+               gboolean hidden;
+
+               element_id = g_variant_get_string (parameters, NULL);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               hidden = e_dom_utils_element_is_hidden (document_saved, element_id);
+
+               g_dbus_method_invocation_return_value (
+                       invocation, g_variant_new ("(b)", hidden));
+       } else if (g_strcmp0 (method_name, "BindSaveButton") == 0) {
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_bind_save_button (
+                       document_saved, connection);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "InputSetChecked") == 0) {
+               const gchar *input_id;
+               gboolean checked;
+
+               g_variant_get (parameters, "(&sb)", &input_id, &checked);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_input_set_checked (
+                       document_saved, input_id, checked);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "InputIsChecked") == 0) {
+               const gchar *input_id;
+               gboolean checked;
+
+               input_id = g_variant_get_string (parameters, NULL);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               checked = module_itip_formatter_dom_utils_input_is_checked (
+                       document_saved, input_id);
+
+               g_dbus_method_invocation_return_value (
+                       invocation, g_variant_new ("(b)", checked));
+       } else if (g_strcmp0 (method_name, "ShowCheckbox") == 0) {
+               const gchar *id;
+               gboolean show, update_second;
+
+               g_variant_get (parameters, "(&sbb)", &id, &show, &update_second);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_show_checkbox (
+                       document_saved, id, show, update_second);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "SetButtonsSensitive") == 0) {
+               gboolean sensitive;
+
+               g_variant_get (parameters, "(b)", &sensitive);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_set_buttons_sensitive (
+                       document_saved, sensitive);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "SetAreaText") == 0) {
+               const gchar *id, *text;
+
+               g_variant_get (parameters, "(&s&s)", &id, &text);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_set_area_text (
+                       document_saved, id, text);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "ElementSetAccessKey") == 0) {
+               const gchar *element_id, *access_key;
+
+               g_variant_get (parameters, "(&s&s)", &element_id, &access_key);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_element_set_access_key (
+                       document_saved, element_id, access_key);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "ElementHideChildNodes") == 0) {
+               const gchar *element_id;
+
+               element_id = g_variant_get_string (parameters, NULL);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_element_hide_child_nodes (
+                       document_saved, element_id);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "EnableSelect") == 0) {
+               const gchar *select_id;
+               gboolean enable;
+
+               g_variant_get (parameters, "(&sb)", &select_id, &enable);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_enable_select (
+                       document_saved, select_id, enable);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "SelectIsEnabled") == 0) {
+               const gchar *select_id;
+               gboolean enabled;
+
+               select_id = g_variant_get_string (parameters, NULL);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               enabled = module_itip_formatter_dom_utils_select_is_enabled (
+                       document_saved, select_id);
+
+               g_dbus_method_invocation_return_value (
+                       invocation, g_variant_new ("(b)", enabled));
+       } else if (g_strcmp0 (method_name, "SelectGetValue") == 0) {
+               const gchar *select_id;
+               gchar *value;
+
+               select_id = g_variant_get_string (parameters, NULL);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               value = module_itip_formatter_dom_utils_select_get_value (
+                       document_saved, select_id);
+
+               g_dbus_method_invocation_return_value (
+                       invocation, g_variant_new ("(s)", value));
+
+               g_free (value);
+       } else if (g_strcmp0 (method_name, "SelectSetSelected") == 0) {
+               const gchar *select_id, *option;
+
+               g_variant_get (parameters, "(&s&s)", &select_id, &option);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_select_set_selected (
+                       document_saved, select_id, option);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "UpdateTimes") == 0) {
+               const gchar *element_id, *header, *label;
+
+               g_variant_get (parameters, "(&s&s&s)", &element_id, &header, &label);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_update_times (
+                       document_saved, element_id, header, label);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "AppendInfoItemRow") == 0) {
+               const gchar *table_id, *row_id, *icon_name, *message;
+
+               g_variant_get (
+                       parameters,
+                       "(&s&s&s&s)",
+                       &table_id, &row_id, &icon_name, &message);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_append_info_item_row (
+                       document_saved, table_id, row_id, icon_name, message);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "EnableTextArea") == 0) {
+               const gchar *area_id;
+               gboolean enable;
+
+               g_variant_get (parameters, "(&sb)", &area_id, &enable);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_enable_text_area (
+                       document_saved, area_id, enable);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "TextAreaSetValue") == 0) {
+               const gchar *area_id, *value;
+
+               g_variant_get (parameters, "(&s&s)", &area_id, &value);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_text_area_set_value (
+                       document_saved, area_id, value);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "TextAreaGetValue") == 0) {
+               const gchar *area_id;
+               gchar *value;
+
+               area_id = g_variant_get_string (parameters, NULL);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               value = module_itip_formatter_dom_utils_text_area_get_value (
+                               document_saved, area_id);
+
+               g_dbus_method_invocation_return_value (
+                       invocation, g_variant_new ("(s)", value));
+
+               g_free (value);
+       } else if (g_strcmp0 (method_name, "RebuildSourceList") == 0) {
+               const gchar *optgroup_id, *optgroup_label, *option_id, *option_label;
+               gboolean writable;
+
+               g_variant_get (
+                       parameters,
+                       "(&s&s&s&sb)",
+                       &optgroup_id, &optgroup_label, &option_id, &option_label, &writable);
+
+               /* FIXME return error */
+               if (!document_saved)
+                       g_dbus_method_invocation_return_value (invocation, NULL);
+
+               module_itip_formatter_dom_utils_rebuild_source_list (
+                       document_saved,
+                       optgroup_id,
+                       optgroup_label,
+                       option_id,
+                       option_label,
+                       writable);
+
+               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,
+                       MODULE_ITIP_FORMATTER_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);
+       }
+}
+
+/* Forward declaration */
+G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *extension);
+
+G_MODULE_EXPORT void
+webkit_web_extension_initialize (WebKitWebExtension *extension)
+{
+       char *service_name;
+
+       service_name =
+               g_strdup_printf (
+                       "%s-%s",
+                       MODULE_ITIP_FORMATTER_WEB_EXTENSION_SERVICE_NAME,
+                       g_getenv ("MODULE_ITIP_FORMATTER_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/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.h 
b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.h
new file mode 100644
index 0000000..b9ffae0
--- /dev/null
+++ b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.h
@@ -0,0 +1,26 @@
+/*
+ * module-itip-formatter-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 MODULE_ITIP_FORMATTER_WEB_EXTENSION_H
+#define MODULE_ITIP_FORMATTER_WEB_EXTENSION_H
+
+#define MODULE_ITIP_FORMATTER_WEB_EXTENSION_SERVICE_NAME 
"org.gnome.Evolution.Module.ItipFormatter.WebExtension"
+#define MODULE_ITIP_FORMATTER_WEB_EXTENSION_OBJECT_PATH  
"/org/gnome/Evolution/Module/ItipFormatter/WebExtension"
+#define MODULE_ITIP_FORMATTER_WEB_EXTENSION_INTERFACE    
"org.gnome.Evolution.Module.ItipFormatter.WebExtension"
+
+#endif /* MODULE_ITIP_FORMATTER_WEB_EXTENSION_H */


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