[evolution/wip-webkit2] Port VCard-Inline module to WK2



commit 80c5160f6806d6477ff214b61b084d69194c888d
Author: Tomas Popela <tpopela redhat com>
Date:   Wed Oct 30 14:00:38 2013 +0100

    Port VCard-Inline module to WK2

 e-util/e-dom-utils.c                     |  163 +++++++++++++++++++++++-
 e-util/e-dom-utils.h                     |   18 +++
 modules/vcard-inline/e-mail-part-vcard.c |  208 ++++++++++++++++++------------
 modules/vcard-inline/e-mail-part-vcard.h |    3 -
 web-extensions/evolution-web-extension.c |   61 +++++++++
 5 files changed, 369 insertions(+), 84 deletions(-)
---
diff --git a/e-util/e-dom-utils.c b/e-util/e-dom-utils.c
index 954fd4e..ebe3660 100644
--- a/e-util/e-dom-utils.c
+++ b/e-util/e-dom-utils.c
@@ -621,6 +621,43 @@ e_dom_utils_eab_contact_formatter_bind_dom (WebKitDOMDocument *document)
 
 /* ! This function can be called only from WK2 web-extension ! */
 WebKitDOMElement *
+e_dom_utils_find_element_by_selector (WebKitDOMDocument *document,
+                                      const gchar *selector)
+{
+       WebKitDOMNodeList *frames;
+       WebKitDOMElement *element;
+       gulong ii, length;
+
+       /* Try to look up the element in this DOM document */
+       element = webkit_dom_document_query_selector (document, selector, NULL);
+       if (element != NULL)
+               return element;
+
+       /* If the element is not here then recursively scan all frames */
+       frames = webkit_dom_document_get_elements_by_tag_name (
+               document, "iframe");
+       length = webkit_dom_node_list_get_length (frames);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMHTMLIFrameElement *iframe;
+               WebKitDOMDocument *frame_doc;
+               WebKitDOMElement *element;
+
+               iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT (
+                       webkit_dom_node_list_item (frames, ii));
+
+               frame_doc = webkit_dom_html_iframe_element_get_content_document (iframe);
+
+               element = e_dom_utils_find_element_by_id (frame_doc, selector);
+
+               if (element != NULL)
+                       return element;
+       }
+
+       return NULL;
+}
+
+/* ! This function can be called only from WK2 web-extension ! */
+WebKitDOMElement *
 e_dom_utils_find_element_by_id (WebKitDOMDocument *document,
                                 const gchar *id)
 {
@@ -655,7 +692,6 @@ e_dom_utils_find_element_by_id (WebKitDOMDocument *document,
 
        return NULL;
 }
-
 gboolean
 e_dom_utils_element_exists (WebKitDOMDocument *document,
                             const gchar *element_id)
@@ -818,3 +854,128 @@ e_dom_utils_element_is_hidden (WebKitDOMDocument *document,
        return webkit_dom_html_element_get_hidden (
                WEBKIT_DOM_HTML_ELEMENT (element));
 }
+
+/* VCard Inline Module DOM functions */
+
+static void
+display_mode_toggle_button_cb (WebKitDOMElement *button,
+                               WebKitDOMEvent *event,
+                               GDBusConnection *connection)
+{
+       GError *error;
+
+       g_dbus_connection_emit_signal (
+               connection,
+               NULL,
+               EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+               EVOLUTION_WEB_EXTENSION_INTERFACE,
+               "VCardInlineDisplayModeToggled",
+               g_variant_new (
+                       "(s)",
+                       webkit_dom_html_button_element_get_value (
+                               WEBKIT_DOM_HTML_BUTTON_ELEMENT (button))),
+               &error);
+
+       if (error) {
+               g_warning ("Error emitting signal DisplayModeToggled: %s\n", error->message);
+               g_error_free (error);
+       }
+}
+
+static void
+save_vcard_button_cb (WebKitDOMElement *button,
+                      WebKitDOMEvent *event,
+                      GDBusConnection *connection)
+{
+       GError *error;
+
+       g_dbus_connection_emit_signal (
+               connection,
+               NULL,
+               EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+               EVOLUTION_WEB_EXTENSION_INTERFACE,
+               "VCardInlineSaveButtonPressed",
+               g_variant_new (
+                       "(s)",
+                       webkit_dom_html_button_element_get_value (
+                               WEBKIT_DOM_HTML_BUTTON_ELEMENT (button))),
+               &error);
+
+       if (error) {
+               g_warning ("Error emitting signal SaveVCardButtonPressed: %s\n", error->message);
+               g_error_free (error);
+       }
+}
+
+void
+e_dom_utils_module_vcard_inline_bind_dom (WebKitDOMDocument *document,
+                                          const gchar *element_id,
+                                          GDBusConnection *connection)
+{
+       WebKitDOMElement *element;
+       WebKitDOMDocument *element_document;
+
+       element = e_dom_utils_find_element_by_id (document, element_id);
+       if (!element)
+               return;
+
+       element_document = webkit_dom_node_get_owner_document (
+               WEBKIT_DOM_NODE (element));
+
+       e_dom_utils_bind_dom (
+               element_document,
+               ".org-gnome-vcard-display-mode-button",
+               "click",
+               display_mode_toggle_button_cb,
+               connection);
+
+       e_dom_utils_bind_dom (
+               element_document,
+               ".org-gnome-vcard-save-button",
+               "click",
+               save_vcard_button_cb,
+               connection);
+
+       e_dom_utils_eab_contact_formatter_bind_dom (element_document);
+}
+
+void
+e_dom_utils_module_vcard_inline_update_button (WebKitDOMDocument *document,
+                                               const gchar *button_value,
+                                               const gchar *html_label,
+                                               const gchar *access_key)
+{
+       WebKitDOMElement *element;
+       gchar *selector;
+
+       selector = g_strconcat ("button[value=", button_value, "]", NULL);
+       element = e_dom_utils_find_element_by_selector (document, selector);
+       g_free (selector);
+
+       if (!element)
+               return;
+
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (element), html_label, NULL);
+
+       if (access_key) {
+               webkit_dom_html_element_set_access_key (
+                       WEBKIT_DOM_HTML_ELEMENT (element), access_key);
+       }
+}
+
+void
+e_dom_utils_module_vcard_inline_set_iframe_src (WebKitDOMDocument *document,
+                                                const gchar *src)
+{
+       WebKitDOMElement *element;
+
+       element = e_dom_utils_find_element_by_selector (
+               document, "iframe[name$=org-gnome-vcard-display]");
+
+       if (!element)
+               return;
+
+       webkit_dom_html_iframe_element_set_src (
+               WEBKIT_DOM_HTML_IFRAME_ELEMENT (element), src);
+}
diff --git a/e-util/e-dom-utils.h b/e-util/e-dom-utils.h
index 478740e..dac466a 100644
--- a/e-util/e-dom-utils.h
+++ b/e-util/e-dom-utils.h
@@ -52,6 +52,10 @@ void         e_dom_utils_e_mail_display_bind_dom
                                                (WebKitDOMDocument *document,
                                                 GDBusConnection *connection);
 WebKitDOMElement *
+               e_dom_utils_find_element_by_selector
+                                               (WebKitDOMDocument *document,
+                                                const gchar *selector);
+WebKitDOMElement *
                e_dom_utils_find_element_by_id  (WebKitDOMDocument *document,
                                                 const gchar *element_id);
 gboolean       e_dom_utils_element_exists
@@ -76,6 +80,20 @@ void         e_dom_utils_hide_element        (WebKitDOMDocument *document,
                                                  gboolean hide);
 gboolean       e_dom_utils_element_is_hidden   (WebKitDOMDocument *document,
                                                 const gchar *element_id);
+
+/* VCard Inline Module DOM functions */
+void           e_dom_utils_module_vcard_inline_bind_dom
+                                               (WebKitDOMDocument *document,
+                                                const gchar *element_id,
+                                                GDBusConnection *connection);
+void           e_dom_utils_module_vcard_inline_update_button
+                                               (WebKitDOMDocument *document,
+                                                const gchar *button_value,
+                                                const gchar *html_label,
+                                                const gchar *access_key);
+void           e_dom_utils_module_vcard_inline_set_iframe_src
+                                               (WebKitDOMDocument *document,
+                                                const gchar *src);
 G_END_DECLS
 
 #endif /* E_DOM_UTILS_H */
diff --git a/modules/vcard-inline/e-mail-part-vcard.c b/modules/vcard-inline/e-mail-part-vcard.c
index 3f52ec6..16928c6 100644
--- a/modules/vcard-inline/e-mail-part-vcard.c
+++ b/modules/vcard-inline/e-mail-part-vcard.c
@@ -33,6 +33,12 @@
 
 struct _EMailPartVCardPrivate {
        gint placeholder;
+
+       guint display_mode_toggled_signal_id;
+       guint save_vcard_button_pressed_signal_id;
+
+       GDBusProxy *web_extension;
+       guint64 page_id;
 };
 
 G_DEFINE_DYNAMIC_TYPE (
@@ -86,8 +92,12 @@ client_connect_cb (GObject *source_object,
 }
 
 static void
-save_vcard_cb (WebKitDOMEventTarget *button,
-               WebKitDOMEvent *event,
+save_vcard_cb (GDBusConnection *connection,
+               const gchar *sender_name,
+               const gchar *object_path,
+               const gchar *interface_name,
+               const gchar *signal_name,
+               GVariant *parameters,
                EMailPartVCard *vcard_part)
 {
        EShell *shell;
@@ -98,6 +108,9 @@ save_vcard_cb (WebKitDOMEventTarget *button,
        const gchar *extension_name;
        GtkWidget *dialog;
 
+       if (g_strcmp0 (signal_name, "VCardInlineSaveButtonPressed") != 0)
+               return;
+
        shell = e_shell_get_default ();
        registry = e_shell_get_registry (shell);
        extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
@@ -132,8 +145,12 @@ save_vcard_cb (WebKitDOMEventTarget *button,
 }
 
 static void
-display_mode_toggle_cb (WebKitDOMEventTarget *button,
-                        WebKitDOMEvent *event,
+display_mode_toggle_cb (GDBusConnection *connection,
+                        const gchar *sender_name,
+                        const gchar *object_path,
+                        const gchar *interface_name,
+                        const gchar *signal_name,
+                        GVariant *parameters,
                         EMailPartVCard *vcard_part)
 {
        EABContactDisplayMode mode;
@@ -141,6 +158,16 @@ display_mode_toggle_cb (WebKitDOMEventTarget *button,
        gchar *html_label;
        gchar *access_key;
        const gchar *part_id;
+       const gchar *button_value;
+       GVariant *result;
+
+       if (g_strcmp0 (signal_name, "VCardInlineDisplayModeToggled") != 0)
+               return;
+
+       if (!vcard_part->priv->web_extension)
+               return;
+
+       button_value = g_variant_get_string (parameters, NULL);
 
        part_id = e_mail_part_get_id (E_MAIL_PART (vcard_part));
 
@@ -150,38 +177,35 @@ display_mode_toggle_cb (WebKitDOMEventTarget *button,
 
                html_label = e_mail_formatter_parse_html_mnemonics (
                                _("Show F_ull vCard"), &access_key);
-
-               webkit_dom_html_element_set_inner_html (
-                       WEBKIT_DOM_HTML_ELEMENT (button),
-                       html_label, NULL);
-               if (access_key) {
-                       webkit_dom_html_element_set_access_key (
-                               WEBKIT_DOM_HTML_ELEMENT (button),
-                               access_key);
-                       g_free (access_key);
-               }
-
-               g_free (html_label);
-
        } else {
                mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
 
                html_label = e_mail_formatter_parse_html_mnemonics (
                                _("Show Com_pact vCard"), &access_key);
-
-               webkit_dom_html_element_set_inner_html (
-                       WEBKIT_DOM_HTML_ELEMENT (button),
-                       html_label, NULL);
-               if (access_key) {
-                       webkit_dom_html_element_set_access_key (
-                               WEBKIT_DOM_HTML_ELEMENT (button),
-                               access_key);
-                       g_free (access_key);
-               }
-
-               g_free (html_label);
        }
 
+       result = g_dbus_proxy_call_sync (
+                       vcard_part->priv->web_extension,
+                       "VCardInlineUpdateButton",
+                       g_variant_new (
+                               "(tsss)",
+                               vcard_part->priv->page_id,
+                               button_value,
+                               html_label,
+                               access_key),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
+
+       if (access_key)
+               g_free (access_key);
+
+       g_free (html_label);
+
        eab_contact_formatter_set_display_mode (vcard_part->formatter, mode);
 
        uri = e_mail_part_build_uri (
@@ -189,8 +213,20 @@ display_mode_toggle_cb (WebKitDOMEventTarget *button,
                "part_id", G_TYPE_STRING, part_id,
                "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW, NULL);
 
-       webkit_dom_html_iframe_element_set_src (
-               WEBKIT_DOM_HTML_IFRAME_ELEMENT (vcard_part->iframe), uri);
+       result = g_dbus_proxy_call_sync (
+                       vcard_part->priv->web_extension,
+                       "VCardInlineSetIFrameSrc",
+                       g_variant_new (
+                               "(ts)",
+                               vcard_part->priv->page_id,
+                               uri),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
 
        g_free (uri);
 }
@@ -203,11 +239,22 @@ mail_part_vcard_dispose (GObject *object)
        g_clear_object (&part->contact_display);
        g_clear_object (&part->message_label);
        g_clear_object (&part->formatter);
-       g_clear_object (&part->iframe);
-       g_clear_object (&part->save_button);
-       g_clear_object (&part->toggle_button);
        g_clear_object (&part->folder);
 
+       if (part->priv->display_mode_toggled_signal_id > 0) {
+               g_dbus_connection_signal_unsubscribe (
+                       g_dbus_proxy_get_connection (part->priv->web_extension),
+                       part->priv->display_mode_toggled_signal_id);
+               part->priv->display_mode_toggled_signal_id = 0;
+       }
+
+       if (part->priv->save_vcard_button_pressed_signal_id > 0) {
+               g_dbus_connection_signal_unsubscribe (
+                       g_dbus_proxy_get_connection (part->priv->web_extension),
+                       part->priv->save_vcard_button_pressed_signal_id);
+               part->priv->save_vcard_button_pressed_signal_id = 0;
+       }
+
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_mail_part_vcard_parent_class)->dispose (object);
 }
@@ -250,57 +297,58 @@ mail_part_vcard_constructed (GObject *object)
 
 static void
 mail_part_vcard_bind_dom_element (EMailPart *part,
-                                  WebKitDOMElement *element)
+                                  GDBusProxy *evolution_web_extension,
+                                 guint64 page_id,
+                                  const gchar *element_id)
 {
        EMailPartVCard *vcard_part;
-       WebKitDOMNodeList *list;
-       WebKitDOMElement *iframe;
-       WebKitDOMElement *toggle_button;
-       WebKitDOMElement *save_button;
+       GVariant *result;
 
        vcard_part = E_MAIL_PART_VCARD (part);
 
-       /* IFRAME */
-       list = webkit_dom_element_get_elements_by_tag_name (
-               element, "iframe");
-       if (webkit_dom_node_list_get_length (list) != 1)
-               return;
-       iframe = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0));
-       g_clear_object (&vcard_part->iframe);
-       vcard_part->iframe = g_object_ref (iframe);
-
-       /* TOGGLE DISPLAY MODE BUTTON */
-       list = webkit_dom_element_get_elements_by_class_name (
-               element, "org-gnome-vcard-display-mode-button");
-       if (webkit_dom_node_list_get_length (list) != 1)
-               return;
-       toggle_button = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0));
-       g_clear_object (&vcard_part->toggle_button);
-       vcard_part->toggle_button = g_object_ref (toggle_button);
-
-       /* SAVE TO ADDRESSBOOK BUTTON */
-       list = webkit_dom_element_get_elements_by_class_name (
-               element, "org-gnome-vcard-save-button");
-       if (webkit_dom_node_list_get_length (list) != 1)
-               return;
-       save_button = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0));
-       g_clear_object (&vcard_part->save_button);
-       vcard_part->save_button = g_object_ref (save_button);
-
-       webkit_dom_event_target_add_event_listener (
-               WEBKIT_DOM_EVENT_TARGET (toggle_button),
-               "click", G_CALLBACK (display_mode_toggle_cb),
-               FALSE, vcard_part);
-
-       webkit_dom_event_target_add_event_listener (
-               WEBKIT_DOM_EVENT_TARGET (save_button),
-               "click", G_CALLBACK (save_vcard_cb),
-               FALSE, vcard_part);
-
-       /* Bind collapse buttons for contact lists. */
-       eab_contact_formatter_bind_dom (
-               webkit_dom_html_iframe_element_get_content_document (
-                       WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe)));
+       vcard_part->priv->web_extension = evolution_web_extension;
+       vcard_part->priv->page_id = page_id;
+
+       vcard_part->priv->display_mode_toggled_signal_id =
+               g_dbus_connection_signal_subscribe (
+                       g_dbus_proxy_get_connection (evolution_web_extension),
+                       g_dbus_proxy_get_name (evolution_web_extension),
+                       g_dbus_proxy_get_interface_name (evolution_web_extension),
+                       "VCardInlineDisplayModeToggled",
+                       g_dbus_proxy_get_object_path (evolution_web_extension),
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       (GDBusSignalCallback) display_mode_toggle_cb,
+                       vcard_part,
+                       NULL);
+
+       vcard_part->priv->save_vcard_button_pressed_signal_id =
+               g_dbus_connection_signal_subscribe (
+                       g_dbus_proxy_get_connection (evolution_web_extension),
+                       g_dbus_proxy_get_name (evolution_web_extension),
+                       g_dbus_proxy_get_interface_name (evolution_web_extension),
+                       "VCardInlineSaveButtonPressed",
+                       g_dbus_proxy_get_object_path (evolution_web_extension),
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       (GDBusSignalCallback) save_vcard_cb,
+                       vcard_part,
+                       NULL);
+
+       result = g_dbus_proxy_call_sync (
+                       vcard_part->priv->web_extension,
+                       "VCardInlineBindDOM",
+                       g_variant_new (
+                               "(ts)",
+                               vcard_part->priv->page_id,
+                               element_id),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (result)
+               g_variant_unref (result);
 }
 
 static void
diff --git a/modules/vcard-inline/e-mail-part-vcard.h b/modules/vcard-inline/e-mail-part-vcard.h
index a6d7267..9aadfa8 100644
--- a/modules/vcard-inline/e-mail-part-vcard.h
+++ b/modules/vcard-inline/e-mail-part-vcard.h
@@ -58,9 +58,6 @@ struct _EMailPartVCard {
        GtkWidget *message_label;
 
        EABContactFormatter *formatter;
-       WebKitDOMElement *iframe;
-       WebKitDOMElement *toggle_button;
-       WebKitDOMElement *save_button;
 
        CamelFolder *folder;
        gchar *message_uid;
diff --git a/web-extensions/evolution-web-extension.c b/web-extensions/evolution-web-extension.c
index 481c3ba..8bb3fcd 100644
--- a/web-extensions/evolution-web-extension.c
+++ b/web-extensions/evolution-web-extension.c
@@ -77,6 +77,26 @@ static const char introspection_xml[] =
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='element_id' direction='in'/>"
 "    </method>"
+"    <signal name='VCardInlineDisplayModeToggled'>"
+"      <arg type='s' name='button_class' direction='out'/>"
+"    </signal>"
+"    <signal name='VCardInlineSaveButtonPressed'>"
+"      <arg type='s' name='button_class' direction='out'/>"
+"    </signal>"
+"    <method name='VCardInlineBindDOM'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='element_id' direction='in'/>"
+"    </method>"
+"    <method name='VCardInlineUpdateButton'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='button_value' direction='in'/>"
+"      <arg type='s' name='html_label' direction='in'/>"
+"      <arg type='s' name='access_key' direction='in'/>"
+"    </method>"
+"    <method name='VCardInlineSetIFrameSrc'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='src' direction='in'/>"
+"    </method>"
 "  </interface>"
 "</node>";
 
@@ -318,6 +338,47 @@ handle_method_call (GDBusConnection *connection,
                e_dom_utils_e_mail_part_headers_bind_dom_element (document, element_id);
 
                g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "VCardInlineBindDOM") == 0) {
+               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);
+               e_dom_utils_vcard_inline_bind_dom (document, element_id);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "VCardInlineUpdateButton") == 0) {
+               const gchar *button_value, *html_label, *access_key;
+
+               g_variant_get (
+                       parameters,
+                       "(t&s&s&s)",
+                       &page_id, &button_value, &html_label, &access_key);
+
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               e_dom_utils_vcard_inline_update_button (
+                       document, button_value, html_label, access_key);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "VCardInlineSetIFrameSrc") == 0) {
+               const gchar *src
+
+               g_variant_get (parameters, "(t&s)", &page_id, &src);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       return;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               e_dom_utils_vcard_inline_set_iframe_src (document, src);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
        }
 }
 


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