[evolution/wip/webkit2: 117/128] Apply patches from wip-webkit2 on top of the master
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit2: 117/128] Apply patches from wip-webkit2 on top of the master
- Date: Tue, 18 Nov 2014 12:07:49 +0000 (UTC)
commit 978883feb7a2329830b27d76462fb0866933e5bc
Author: Tomas Popela <tpopela redhat com>
Date: Mon Sep 8 11:12:18 2014 +0200
Apply patches from wip-webkit2 on top of the master
The main development will be done in this branch wip/webkit2 (based on 3.13.x) the
wip-webkit2 branch will be left on 3.11.x as playground for various
things as it doesn't have to WebKit based composer.
Makefile.am | 1 +
addressbook/gui/widgets/eab-contact-display.c | 45 +-
addressbook/gui/widgets/eab-contact-formatter.c | 62 -
addressbook/gui/widgets/eab-contact-formatter.h | 1 -
configure.ac | 19 +-
e-util/Makefile.am | 3 +
e-util/e-dom-utils.c | 1280 ++++++++++++++++
e-util/e-dom-utils.h | 107 ++
e-util/e-mail-signature-preview.c | 69 +-
e-util/e-search-bar.c | 180 ++-
e-util/e-util.h | 1 +
e-util/e-web-view-preview.c | 12 +-
e-util/e-web-view.c | 1480 ++++++++++++++-----
e-util/e-web-view.h | 53 +-
em-format/Makefile.am | 2 +
em-format/e-mail-formatter-headers.c | 4 +-
em-format/e-mail-formatter.c | 3 +
em-format/e-mail-meta-remove-filter.c | 267 ++++
em-format/e-mail-meta-remove-filter.h | 66 +
em-format/e-mail-part-headers.c | 36 +-
em-format/e-mail-part.c | 10 +-
em-format/e-mail-part.h | 9 +-
mail/e-http-request.c | 2 +-
mail/e-mail-display-popup-extension.c | 5 +-
mail/e-mail-display-popup-extension.h | 7 +-
mail/e-mail-display.c | 1450 +++++++++++++-----
mail/e-mail-display.h | 6 +-
mail/e-mail-printer.c | 24 +-
mail/e-mail-reader-utils.c | 6 +-
mail/e-mail-reader.c | 38 +-
mail/e-mail-request.c | 2 +-
modules/itip-formatter/Makefile.am | 5 +-
modules/itip-formatter/e-mail-formatter-itip.c | 2 +-
modules/itip-formatter/e-mail-part-itip.c | 39 +-
.../itip-formatter/itip-view-elements-defines.h | 65 +
modules/itip-formatter/itip-view.c | 1578 +++++++++-----------
modules/itip-formatter/itip-view.h | 11 +-
.../module-itip-formatter-dom-utils.c | 723 +++++++++
.../module-itip-formatter-dom-utils.h | 112 ++
modules/itip-formatter/web-extension/Makefile.am | 25 +
.../module-itip-formatter-web-extension.c | 619 ++++++++
.../module-itip-formatter-web-extension.h | 26 +
modules/mail/Makefile.am | 2 +
modules/mail/e-mail-shell-backend.c | 3 +-
modules/mail/e-mail-shell-view-private.c | 143 ++-
modules/mail/e-mail-shell-view-private.h | 5 +
modules/mail/web-extension/Makefile.am | 23 +
.../mail/web-extension/module-mail-web-extension.c | 141 ++
.../mail/web-extension/module-mail-web-extension.h | 26 +
modules/prefer-plain/Makefile.am | 2 +-
.../e-mail-display-popup-prefer-plain.c | 230 +++-
modules/prefer-plain/web-extension/Makefile.am | 23 +
.../module-prefer-plain-web-extension.c | 176 +++
.../module-prefer-plain-web-extension.h | 26 +
modules/text-highlight/Makefile.am | 2 +
.../e-mail-display-popup-text-highlight.c | 209 ++-
modules/text-highlight/web-extension/Makefile.am | 23 +
.../module-text-highlight-web-extension.c | 176 +++
.../module-text-highlight-web-extension.h | 26 +
modules/vcard-inline/e-mail-formatter-vcard.c | 9 +-
modules/vcard-inline/e-mail-part-vcard.c | 216 ++--
modules/vcard-inline/e-mail-part-vcard.h | 4 -
modules/web-inspector/evolution-web-inspector.c | 33 +-
plugins/mail-to-task/mail-to-task.c | 15 +-
shell/main.c | 3 +-
web-extensions/Makefile.am | 23 +
web-extensions/evolution-web-extension.c | 636 ++++++++
web-extensions/evolution-web-extension.h | 26 +
68 files changed, 8420 insertions(+), 2236 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index cd8e3e9..82c2ae8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -71,6 +71,7 @@ SUBDIRS = \
art \
plugins \
modules \
+ web-extensions \
$(MAINT_SUBDIR) \
doc \
ui \
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
index cd7fafd..f2111be 100644
--- a/addressbook/gui/widgets/eab-contact-display.c
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -28,7 +28,7 @@
#include <string.h>
#include <glib/gi18n.h>
-#include <webkit/webkit.h>
+#include <webkit2/webkit2.h>
#include "e-contact-map.h"
#include "eab-contact-formatter.h"
@@ -386,19 +386,31 @@ contact_display_object_requested (WebKitWebView *web_view,
#endif
static void
-contact_display_load_status_changed (WebKitWebView *web_view,
- GParamSpec *pspec,
- gpointer user_data)
+contact_display_load_changed (WebKitWebView *web_view,
+ WebKitLoadEvent load_event,
+ gpointer user_data)
{
- WebKitLoadStatus load_status;
- WebKitDOMDocument *document;
-
- load_status = webkit_web_view_get_load_status (web_view);
- if (load_status != WEBKIT_LOAD_FINISHED)
- return;
-
- document = webkit_web_view_get_dom_document (web_view);
- eab_contact_formatter_bind_dom (document);
+ GDBusProxy *web_extension;
+ GVariant* result;
+
+ if (load_event != WEBKIT_LOAD_FINISHED)
+ return;
+
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (web_view));
+ if (web_extension) {
+ result = g_dbus_proxy_call_sync (
+ web_extension,
+ "EABContactFormatterBindDOM",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (web_view)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, //cancellable
+ NULL);
+ if (result)
+ g_variant_unref (result);
+ }
}
static void
@@ -514,15 +526,12 @@ eab_contact_display_init (EABContactDisplay *display)
G_CALLBACK (contact_display_object_requested), display);
#endif
e_signal_connect_notify (
- web_view, "notify::load-status",
- G_CALLBACK (contact_display_load_status_changed), NULL);
+ web_view, "notify::load-changed",
+ G_CALLBACK (contact_display_load_changed), NULL);
g_signal_connect (
web_view, "style-updated",
G_CALLBACK (load_contact), NULL);
- e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_FILE_REQUEST);
- e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_STOCK_REQUEST);
-
action_group = gtk_action_group_new ("internal-mailto");
gtk_action_group_set_translation_domain (action_group, domain);
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
diff --git a/addressbook/gui/widgets/eab-contact-formatter.c b/addressbook/gui/widgets/eab-contact-formatter.c
index 14e0d0b..983ae66 100644
--- a/addressbook/gui/widgets/eab-contact-formatter.c
+++ b/addressbook/gui/widgets/eab-contact-formatter.c
@@ -1383,65 +1383,3 @@ eab_contact_formatter_format_contact (EABContactFormatter *formatter,
else
render_compact (formatter, contact, output_buffer);
}
-
-static void
-collapse_contacts_list (WebKitDOMEventTarget *event_target,
- WebKitDOMEvent *event,
- gpointer user_data)
-{
- WebKitDOMDocument *document;
- WebKitDOMElement *list;
- gchar *id, *list_id;
- gchar *imagesdir, *src;
- gboolean hidden;
-
- document = user_data;
- id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (event_target));
-
- list_id = g_strconcat ("list-", id, NULL);
- list = webkit_dom_document_get_element_by_id (document, list_id);
- g_free (id);
- g_free (list_id);
-
- if (list == NULL)
- return;
-
- imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
- hidden = webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (list));
-
- if (hidden)
- src = g_strdup_printf ("evo-file://%s/minus.png", imagesdir);
- else
- src = g_strdup_printf ("evo-file://%s/plus.png", imagesdir);
-
- webkit_dom_html_element_set_hidden (
- WEBKIT_DOM_HTML_ELEMENT (list), !hidden);
- webkit_dom_html_image_element_set_src (
- WEBKIT_DOM_HTML_IMAGE_ELEMENT (event_target), src);
-
- g_free (src);
- g_free (imagesdir);
-}
-
-void
-eab_contact_formatter_bind_dom (WebKitDOMDocument *document)
-{
- WebKitDOMNodeList *nodes;
- gulong ii, length;
-
- nodes = webkit_dom_document_get_elements_by_class_name (
- document, "_evo_collapse_button");
-
- length = webkit_dom_node_list_get_length (nodes);
- for (ii = 0; ii < length; ii++) {
-
- WebKitDOMNode *node;
-
- node = webkit_dom_node_list_item (nodes, ii);
- webkit_dom_event_target_add_event_listener (
- WEBKIT_DOM_EVENT_TARGET (node), "click",
- G_CALLBACK (collapse_contacts_list), FALSE, document);
- }
-
- g_object_unref (nodes);
-}
diff --git a/addressbook/gui/widgets/eab-contact-formatter.h b/addressbook/gui/widgets/eab-contact-formatter.h
index b4acc62..b691f31 100644
--- a/addressbook/gui/widgets/eab-contact-formatter.h
+++ b/addressbook/gui/widgets/eab-contact-formatter.h
@@ -75,7 +75,6 @@ void eab_contact_formatter_format_contact
(EABContactFormatter *formatter,
EContact *contact,
GString *output_buffer);
-void eab_contact_formatter_bind_dom (WebKitDOMDocument *document);
G_END_DECLS
diff --git a/configure.ac b/configure.ac
index 2babc56..eecaa11 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,7 +50,7 @@ m4_define([gcr_minimum_version], [3.4])
m4_define([enchant_minimum_version], [1.1.7])
m4_define([gnome_desktop_minimum_version], [2.91.3])
m4_define([gsettings_desktop_schemas_minimum_version], [2.91.92])
-m4_define([webkitgtk_minimum_version], [2.2.0])
+m4_define([webkit2gtk_minimum_version], [2.5.3])
m4_define([libgdata_minimum_version], [0.10])
m4_define([libxml_minimum_version], [2.7.3])
m4_define([shared_mime_info_minimum_version], [0.22])
@@ -279,7 +279,7 @@ PKG_CHECK_MODULES([GNOME_PLATFORM],
libxml-2.0 >= libxml_minimum_version
shared-mime-info >= shared_mime_info_minimum_version
gsettings-desktop-schemas >= gsettings_desktop_schemas_minimum_version
- webkitgtk-3.0 >= webkitgtk_minimum_version])
+ webkit2gtk-4.0 >= webkitgtk_minimum_version])
GNOME_DESKTOP_DEPENDENCY=""
AC_ARG_ENABLE([gnome-desktop],
@@ -1266,6 +1266,16 @@ AC_SUBST(viewsdir)
dnl For evolution-alarm-notify.desktop
AS_AC_EXPAND(PRIVLIBEXECDIR, "$privlibexecdir")
+dnl **********************************
+dnl WebKit2 Web Extensions
+dnl **********************************
+webextensionsdir="$privlibdir/web-extensions"
+AC_SUBST(webextensionsdir)
+
+PKG_CHECK_MODULES(WEB_EXTENSION, [webkit2gtk-4.0 >= webkit2gtk_minimum_version])
+AC_SUBST(WEB_EXTENSIONS_CFLAGS)
+AC_SUBST(WEB_EXTENSIONS_LIBS)
+
dnl ************************
dnl Plugins
dnl ************************
@@ -1593,8 +1603,10 @@ 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/mail/web-extension/Makefile
modules/mailto-handler/Makefile
modules/mdn/Makefile
modules/offline-alert/Makefile
@@ -1602,10 +1614,12 @@ modules/plugin-lib/Makefile
modules/plugin-manager/Makefile
modules/prefer-plain/Makefile
modules/prefer-plain/plugin/Makefile
+modules/prefer-plain/web-extension/Makefile
modules/settings/Makefile
modules/spamassassin/Makefile
modules/startup-wizard/Makefile
modules/text-highlight/Makefile
+modules/text-highlight/web-extension/Makefile
modules/tnef-attachment/Makefile
modules/vcard-inline/Makefile
modules/web-inspector/Makefile
@@ -1623,6 +1637,7 @@ plugins/pst-import/Makefile
plugins/publish-calendar/Makefile
plugins/save-calendar/Makefile
plugins/templates/Makefile
+web-extensions/Makefile
smime/Makefile
smime/lib/Makefile
smime/gui/Makefile
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index 61ee3f8..030efe6 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -97,6 +97,7 @@ libevolution_util_la_CPPFLAGS = \
-DEVOLUTION_TOOLSDIR=\""$(privlibexecdir)"\" \
-DEVOLUTION_UIDIR=\""$(uidir)"\" \
-DEVOLUTION_RULEDIR=\"$(ruledir)\" \
+ -DEVOLUTION_WEB_EXTENSIONS_DIR=\""$(webextensionsdir)"\" \
-DG_LOG_DOMAIN=\"evolution-util\" \
$(EVOLUTION_DATA_SERVER_CFLAGS) \
$(GNOME_PLATFORM_CFLAGS) \
@@ -178,6 +179,7 @@ evolution_util_include_HEADERS = \
e-destination-store.h \
e-dialog-utils.h \
e-dialog-widgets.h \
+ e-dom-utils.h \
e-emoticon-action.h \
e-emoticon-chooser-menu.h \
e-emoticon-chooser.h \
@@ -450,6 +452,7 @@ libevolution_util_la_SOURCES = \
e-destination-store.c \
e-dialog-utils.c \
e-dialog-widgets.c \
+ e-dom-utils.c \
e-emoticon-action.c \
e-emoticon-chooser-menu.c \
e-emoticon-chooser.c \
diff --git a/e-util/e-dom-utils.c b/e-util/e-dom-utils.c
new file mode 100644
index 0000000..377d174
--- /dev/null
+++ b/e-util/e-dom-utils.c
@@ -0,0 +1,1280 @@
+/*
+ * e-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 "e-dom-utils.h"
+
+#define WEBKIT_DOM_USE_UNSTABLE_API
+#include <webkitdom/WebKitDOMDOMSelection.h>
+#include <webkitdom/WebKitDOMDOMWindowUnstable.h>
+#include <webkitdom/WebKitDOMHTMLElementUnstable.h>
+
+#include "../web-extensions/evolution-web-extension.h"
+
+#include <config.h>
+
+static void
+replace_local_image_links (WebKitDOMElement *element)
+{
+ WebKitDOMElement *child;
+
+ if (element == NULL)
+ return;
+
+ if (WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (element)) {
+ WebKitDOMHTMLImageElement *img;
+ gchar *src;
+
+ img = WEBKIT_DOM_HTML_IMAGE_ELEMENT (element);
+ src = webkit_dom_html_image_element_get_src (img);
+ if (src && g_ascii_strncasecmp (src, "file://", 7) == 0) {
+ gchar *new_src;
+
+ /* this forms "evo-file://", which can be loaded,
+ * while "file://" cannot be, due to webkit policy */
+ new_src = g_strconcat ("evo-", src, NULL);
+ webkit_dom_html_image_element_set_src (img, new_src);
+ g_free (new_src);
+ }
+
+ g_free (src);
+ }
+
+ if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) {
+ WebKitDOMDocument *content_document;
+
+ content_document =
+ webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
+
+ if (!content_document)
+ return;
+
+ replace_local_image_links (WEBKIT_DOM_ELEMENT (content_document));
+ }
+
+ child = webkit_dom_element_get_first_element_child (element);
+ replace_local_image_links (child);
+
+ do {
+ element = webkit_dom_element_get_next_element_sibling (element);
+ replace_local_image_links (element);
+ } while (element != NULL);
+}
+
+void
+e_dom_utils_replace_local_image_links (WebKitDOMDocument *document)
+{
+ WebKitDOMNode *node;
+
+ for (node = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (document));
+ node;
+ node = webkit_dom_node_get_next_sibling (node)) {
+ if (WEBKIT_DOM_IS_ELEMENT (node))
+ replace_local_image_links (WEBKIT_DOM_ELEMENT (node));
+ }
+}
+
+static gboolean
+document_has_selection (WebKitDOMDocument *document)
+{
+ WebKitDOMDOMWindow *dom_window;
+ WebKitDOMDOMSelection *dom_selection;
+
+ dom_window = webkit_dom_document_get_default_view (document);
+ if (!dom_window)
+ return FALSE;
+
+ dom_selection = webkit_dom_dom_window_get_selection (dom_window);
+ if (!WEBKIT_DOM_IS_DOM_SELECTION (dom_selection))
+ return FALSE;
+
+ if (webkit_dom_dom_selection_get_range_count (dom_selection) == 0)
+ return FALSE;
+
+ if (webkit_dom_dom_selection_get_is_collapsed (dom_selection))
+ return FALSE;
+
+ return TRUE;
+}
+
+gchar *
+e_dom_utils_get_document_content_html (WebKitDOMDocument *document)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_get_document_element (document);
+
+ return webkit_dom_html_element_get_outer_html (WEBKIT_DOM_HTML_ELEMENT (element));
+}
+
+static gchar *
+get_frame_selection_html (WebKitDOMElement *iframe)
+{
+ WebKitDOMDocument *content_document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMNodeList *frames;
+ gulong ii, length;
+
+ content_document = webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe));
+
+ if (!content_document)
+ return NULL;
+
+ window = webkit_dom_document_get_default_view (content_document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (selection && (webkit_dom_dom_selection_get_range_count (selection) > 0)) {
+ WebKitDOMRange *range;
+ WebKitDOMElement *element;
+ WebKitDOMDocumentFragment *fragment;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+ if (range != NULL) {
+ fragment = webkit_dom_range_clone_contents (
+ range, NULL);
+
+ element = webkit_dom_document_create_element (
+ content_document, "DIV", NULL);
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (element),
+ WEBKIT_DOM_NODE (fragment), NULL);
+
+ return webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+ }
+ }
+
+ frames = webkit_dom_document_get_elements_by_tag_name (
+ content_document, "IFRAME");
+ length = webkit_dom_node_list_get_length (frames);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node;
+ gchar *text;
+
+ node = webkit_dom_node_list_item (frames, ii);
+
+ text = get_frame_selection_html (
+ WEBKIT_DOM_ELEMENT (node));
+
+ if (text != NULL) {
+ g_object_unref (frames);
+ return text;
+ }
+ }
+
+ g_object_unref (frames);
+ return NULL;
+}
+
+gchar *
+e_dom_utils_get_selection_content_html (WebKitDOMDocument *document)
+{
+ WebKitDOMNodeList *frames;
+ gulong ii, length;
+
+ if (!document_has_selection (document))
+ return NULL;
+
+ 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++) {
+ gchar *text;
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (frames, ii);
+
+ text = get_frame_selection_html (
+ WEBKIT_DOM_ELEMENT (node));
+
+ if (text != NULL)
+ return text;
+ }
+
+ return NULL;
+}
+
+static gchar *
+get_frame_selection_content_text (WebKitDOMElement *iframe)
+{
+ WebKitDOMDocument *content_document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMNodeList *frames;
+ gulong ii, length;
+
+ content_document = webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe));
+
+ if (!content_document)
+ return NULL;
+
+ window = webkit_dom_document_get_default_view (content_document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (selection && (webkit_dom_dom_selection_get_range_count (selection) > 0)) {
+ WebKitDOMRange *range;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+ if (range != NULL)
+ return webkit_dom_range_to_string (range, NULL);
+ }
+
+ frames = webkit_dom_document_get_elements_by_tag_name (
+ content_document, "IFRAME");
+ length = webkit_dom_node_list_get_length (frames);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node;
+ gchar *text;
+
+ node = webkit_dom_node_list_item (frames, ii);
+
+ text = get_frame_selection_content_text (
+ WEBKIT_DOM_ELEMENT (node));
+
+ if (text != NULL) {
+ g_object_unref (frames);
+ return text;
+ }
+ }
+
+ g_object_unref (frames);
+ return NULL;
+}
+
+gchar *
+e_dom_utils_get_selection_content_text (WebKitDOMDocument *document)
+{
+ WebKitDOMNodeList *frames;
+ gulong ii, length;
+
+ 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++) {
+ gchar *text;
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (frames, ii);
+
+ text = get_frame_selection_content_text (
+ WEBKIT_DOM_ELEMENT (node));
+
+ if (text != NULL) {
+ g_object_unref (frames);
+ return text;
+ }
+ }
+
+ g_object_unref (frames);
+ return NULL;
+}
+
+void
+e_dom_utils_create_and_add_css_style_sheet (WebKitDOMDocument *document,
+ const gchar *style_sheet_id)
+{
+ WebKitDOMElement *style_element;
+
+ style_element = webkit_dom_document_get_element_by_id (document, style_sheet_id);
+
+ if (!style_element) {
+ /* Create new <style> element */
+ style_element = webkit_dom_document_create_element (document, "style", NULL);
+ webkit_dom_element_set_id (
+ style_element,
+ style_sheet_id);
+ webkit_dom_html_style_element_set_media (
+ WEBKIT_DOM_HTML_STYLE_ELEMENT (style_element),
+ "screen");
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (style_element),
+ /* WebKit hack - we have to insert empty TextNode into style element */
+ WEBKIT_DOM_NODE (webkit_dom_document_create_text_node (document, "")),
+ NULL);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (webkit_dom_document_get_head (document)),
+ WEBKIT_DOM_NODE (style_element),
+ NULL);
+ }
+}
+
+static void
+add_css_rule_into_style_sheet (WebKitDOMDocument *document,
+ const gchar *style_sheet_id,
+ const gchar *selector,
+ const gchar *style)
+{
+ WebKitDOMElement *style_element;
+ WebKitDOMStyleSheet *sheet;
+ WebKitDOMCSSRuleList *rules_list;
+ gint length, ii;
+
+ style_element = webkit_dom_document_get_element_by_id (document, style_sheet_id);
+
+ if (!style_element) {
+ e_dom_utils_create_and_add_css_style_sheet (document, style_sheet_id);
+ style_element = webkit_dom_document_get_element_by_id (document, style_sheet_id);
+ }
+
+ /* Get sheet that is associated with style element */
+ sheet = webkit_dom_html_style_element_get_sheet (WEBKIT_DOM_HTML_STYLE_ELEMENT (style_element));
+
+ rules_list = webkit_dom_css_style_sheet_get_css_rules (WEBKIT_DOM_CSS_STYLE_SHEET (sheet));
+ length = webkit_dom_css_rule_list_get_length (rules_list);
+
+ /* Check if rule exists */
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMCSSRule *rule;
+ gchar *rule_text;
+ gchar *rule_selector, *selector_end;
+
+ rule = webkit_dom_css_rule_list_item (rules_list, ii);
+
+ if (!WEBKIT_DOM_IS_CSS_RULE (rule))
+ continue;
+
+ rule_text = webkit_dom_css_rule_get_css_text (rule);
+
+ /* Find the start of the style => end of the selector */
+ selector_end = g_strstr_len (rule_text, -1, " {");
+ if (!selector_end) {
+ g_free (rule_text);
+ continue;
+ }
+
+ rule_selector =
+ g_utf8_substring (
+ rule_text,
+ 0,
+ g_utf8_pointer_to_offset (rule_text, selector_end));
+
+ if (g_strcmp0 (rule_selector, selector) == 0) {
+ /* If exists remove it */
+ webkit_dom_css_style_sheet_remove_rule (
+ WEBKIT_DOM_CSS_STYLE_SHEET (sheet),
+ ii, NULL);
+ }
+
+ g_free (rule_selector);
+ g_free (rule_text);
+ }
+
+ /* Insert the rule at the end, so it will override previously inserted */
+ webkit_dom_css_style_sheet_add_rule (
+ WEBKIT_DOM_CSS_STYLE_SHEET (sheet),
+ selector,
+ style,
+ webkit_dom_css_rule_list_get_length (
+ webkit_dom_css_style_sheet_get_css_rules (
+ WEBKIT_DOM_CSS_STYLE_SHEET (sheet))), /* Index */
+ NULL);
+}
+
+static void
+add_css_rule_into_style_sheet_recursive (WebKitDOMDocument *document,
+ const gchar *style_sheet_id,
+ const gchar *selector,
+ const gchar *style)
+{
+ WebKitDOMNodeList *frames;
+ gint ii, length;
+
+ /* Add rule to document */
+ add_css_rule_into_style_sheet (
+ document,
+ style_sheet_id,
+ selector,
+ style);
+
+ frames = webkit_dom_document_query_selector_all (document, "iframe", NULL);
+ length = webkit_dom_node_list_get_length (frames);
+
+ /* Add rules to every sub document */
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMDocument *content_document = NULL;
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (frames, ii);
+ content_document =
+ webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (node));
+
+ if (!content_document)
+ continue;
+
+ add_css_rule_into_style_sheet_recursive (
+ content_document,
+ style_sheet_id,
+ selector,
+ style);
+ }
+ g_object_unref (frames);
+}
+
+void
+e_dom_utils_add_css_rule_into_style_sheet (WebKitDOMDocument *document,
+ const gchar *style_sheet_id,
+ const gchar *selector,
+ const gchar *style)
+{
+ g_return_if_fail (style_sheet_id && *style_sheet_id);
+ g_return_if_fail (selector && *selector);
+ g_return_if_fail (style && *style);
+
+ add_css_rule_into_style_sheet_recursive (
+ document,
+ style_sheet_id,
+ selector,
+ style);
+}
+
+static void
+collapse_contacts_list (WebKitDOMEventTarget *event_target,
+ WebKitDOMEvent *event,
+ gpointer user_data)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMElement *list;
+ gchar *id, *list_id;
+ gchar *imagesdir, *src;
+ gboolean hidden;
+
+ document = user_data;
+ id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (event_target));
+
+ list_id = g_strconcat ("list-", id, NULL);
+ list = webkit_dom_document_get_element_by_id (document, list_id);
+ g_free (id);
+ g_free (list_id);
+
+ if (list == NULL)
+ return;
+
+ imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
+ hidden = webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (list));
+
+ if (hidden)
+ src = g_strdup_printf ("evo-file://%s/minus.png", imagesdir);
+ else
+ src = g_strdup_printf ("evo-file://%s/plus.png", imagesdir);
+
+ webkit_dom_html_element_set_hidden (
+ WEBKIT_DOM_HTML_ELEMENT (list), !hidden);
+ webkit_dom_html_image_element_set_src (
+ WEBKIT_DOM_HTML_IMAGE_ELEMENT (event_target), src);
+
+ g_free (src);
+ g_free (imagesdir);
+}
+
+static void
+toggle_headers_visibility (WebKitDOMElement *button,
+ WebKitDOMEvent *event,
+ WebKitDOMDocument *document)
+{
+ WebKitDOMElement *short_headers, *full_headers;
+ WebKitDOMCSSStyleDeclaration *css_short, *css_full;
+ gboolean expanded;
+ const gchar *path;
+ gchar *css_value;
+
+ short_headers = webkit_dom_document_get_element_by_id (
+ document, "__evo-short-headers");
+ if (short_headers == NULL)
+ return;
+
+ css_short = webkit_dom_element_get_style (short_headers);
+
+ full_headers = webkit_dom_document_get_element_by_id (
+ document, "__evo-full-headers");
+ if (full_headers == NULL)
+ return;
+
+ css_full = webkit_dom_element_get_style (full_headers);
+ css_value = webkit_dom_css_style_declaration_get_property_value (
+ css_full, "display");
+ expanded = (g_strcmp0 (css_value, "table") == 0);
+ g_free (css_value);
+
+ webkit_dom_css_style_declaration_set_property (
+ css_full, "display",
+ expanded ? "none" : "table", "", NULL);
+ webkit_dom_css_style_declaration_set_property (
+ css_short, "display",
+ expanded ? "table" : "none", "", NULL);
+
+ if (expanded)
+ path = "evo-file://" EVOLUTION_IMAGESDIR "/plus.png";
+ else
+ path = "evo-file://" EVOLUTION_IMAGESDIR "/minus.png";
+
+ webkit_dom_html_image_element_set_src (
+ WEBKIT_DOM_HTML_IMAGE_ELEMENT (button), path);
+}
+
+static void
+toggle_address_visibility (WebKitDOMElement *button,
+ WebKitDOMEvent *event,
+ GDBusConnection *connection)
+{
+ WebKitDOMElement *full_addr, *ellipsis;
+ WebKitDOMElement *parent;
+ WebKitDOMCSSStyleDeclaration *css_full, *css_ellipsis;
+ const gchar *path;
+ gboolean expanded;
+ GError *error = NULL;
+
+ /* <b> element */
+ parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (button));
+ /* <td> element */
+ parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (parent));
+
+ full_addr = webkit_dom_element_query_selector (parent, "#__evo-moreaddr", NULL);
+
+ if (!full_addr)
+ return;
+
+ css_full = webkit_dom_element_get_style (full_addr);
+
+ ellipsis = webkit_dom_element_query_selector (parent, "#__evo-moreaddr-ellipsis", NULL);
+
+ if (!ellipsis)
+ return;
+
+ css_ellipsis = webkit_dom_element_get_style (ellipsis);
+
+ expanded = (g_strcmp0 (
+ webkit_dom_css_style_declaration_get_property_value (
+ css_full, "display"), "inline") == 0);
+
+ webkit_dom_css_style_declaration_set_property (
+ css_full, "display", (expanded ? "none" : "inline"), "", NULL);
+ webkit_dom_css_style_declaration_set_property (
+ css_ellipsis, "display", (expanded ? "inline" : "none"), "", NULL);
+
+ if (expanded)
+ path = "evo-file://" EVOLUTION_IMAGESDIR "/plus.png";
+ else
+ path = "evo-file://" EVOLUTION_IMAGESDIR "/minus.png";
+
+ if (!WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (button)) {
+ button = webkit_dom_element_query_selector (parent, "#__evo-moreaddr-img", NULL);
+
+ if (!button)
+ return;
+ }
+
+ webkit_dom_html_image_element_set_src (
+ WEBKIT_DOM_HTML_IMAGE_ELEMENT (button), path);
+
+ g_dbus_connection_emit_signal (
+ connection,
+ NULL,
+ EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+ EVOLUTION_WEB_EXTENSION_INTERFACE,
+ "HeadersCollapsed",
+ g_variant_new ("(b)", expanded),
+ &error);
+
+ if (error) {
+ g_warning ("Error emitting signal HeadersCollapsed: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+e_dom_utils_bind_dom (WebKitDOMDocument *document,
+ const gchar *selector,
+ const gchar *event,
+ gpointer callback,
+ gpointer user_data)
+{
+ WebKitDOMNodeList *nodes;
+ gulong ii, length;
+
+ nodes = webkit_dom_document_query_selector_all (
+ document, selector, NULL);
+
+ length = webkit_dom_node_list_get_length (nodes);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (nodes, ii);
+ webkit_dom_event_target_add_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (node), event,
+ G_CALLBACK (callback), FALSE, user_data);
+ }
+ g_object_unref (nodes);
+}
+
+static void
+e_dom_utils_bind_elements_recursively (WebKitDOMDocument *document,
+ const gchar *selector,
+ const gchar *event,
+ gpointer callback,
+ gpointer user_data)
+{
+ WebKitDOMNodeList *nodes;
+ gulong ii, length;
+
+ nodes = webkit_dom_document_query_selector_all (
+ document, selector, NULL);
+
+ length = webkit_dom_node_list_get_length (nodes);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (nodes, ii);
+ webkit_dom_event_target_add_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (node), event,
+ G_CALLBACK (callback), FALSE, user_data);
+ }
+ g_object_unref (nodes);
+
+ nodes = webkit_dom_document_query_selector_all (document, "iframe", NULL);
+ length = webkit_dom_node_list_get_length (nodes);
+
+ /* Add rules to every sub document */
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMDocument *content_document = NULL;
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (nodes, ii);
+ content_document =
+ webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (node));
+
+ if (!content_document)
+ continue;
+
+ e_dom_utils_bind_elements_recursively (
+ content_document,
+ selector,
+ event,
+ callback,
+ user_data);
+ }
+ g_object_unref (nodes);
+}
+
+static void
+element_focus_cb (WebKitDOMElement *element,
+ WebKitDOMEvent *event,
+ GDBusConnection *connection)
+{
+ g_dbus_connection_call (
+ connection,
+ "org.gnome.Evolution.WebExtension",
+ "/org/gnome/Evolution/WebExtension",
+ "org.freedesktop.DBus.Properties",
+ "Set",
+ g_variant_new (
+ "(ssv)",
+ "org.gnome.Evolution.WebExtension",
+ "NeedInput",
+ g_variant_new_boolean (TRUE)),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+
+}
+
+static void
+element_blur_cb (WebKitDOMElement *element,
+ WebKitDOMEvent *event,
+ GDBusConnection *connection)
+{
+ g_dbus_connection_call (
+ connection,
+ "org.gnome.Evolution.WebExtension",
+ "/org/gnome/Evolution/WebExtension",
+ "org.freedesktop.DBus.Properties",
+ "Set",
+ g_variant_new (
+ "(ssv)",
+ "org.gnome.Evolution.WebExtension",
+ "NeedInput",
+ g_variant_new_boolean (FALSE)),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+
+void
+e_dom_utils_bind_focus_on_elements (WebKitDOMDocument *document,
+ GDBusConnection *connection)
+{
+ const gchar *elements = "input, textarea, select, button, label";
+
+ e_dom_utils_bind_elements_recursively (
+ document,
+ elements,
+ "focus",
+ element_focus_cb,
+ connection);
+
+ e_dom_utils_bind_elements_recursively (
+ document,
+ elements,
+ "blur",
+ element_blur_cb,
+ connection);
+}
+
+void
+e_dom_utils_e_mail_display_bind_dom (WebKitDOMDocument *document,
+ GDBusConnection *connection)
+{
+ e_dom_utils_bind_dom (
+ document,
+ "#__evo-collapse-headers-img",
+ "click",
+ toggle_headers_visibility,
+ document);
+
+ e_dom_utils_bind_dom (
+ document,
+ "*[id^=__evo-moreaddr-]",
+ "click",
+ toggle_address_visibility,
+ connection);
+}
+
+void
+e_dom_utils_eab_contact_formatter_bind_dom (WebKitDOMDocument *document)
+{
+ e_dom_utils_bind_dom (
+ document,
+ "._evo_collapse_button",
+ "click",
+ collapse_contacts_list,
+ 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 *content_document;
+ WebKitDOMElement *element;
+
+ iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT (
+ webkit_dom_node_list_item (frames, ii));
+
+ content_document = webkit_dom_html_iframe_element_get_content_document (iframe);
+ if (!content_document)
+ continue;
+
+ element = e_dom_utils_find_element_by_id (content_document, selector);
+
+ if (element != NULL) {
+ g_object_unref (frames);
+ return element;
+ }
+ }
+
+ g_object_unref (frames);
+ 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)
+{
+ WebKitDOMNodeList *frames;
+ WebKitDOMElement *element;
+ gulong ii, length;
+
+ /* Try to look up the element in this DOM document */
+ element = webkit_dom_document_get_element_by_id (document, id);
+ 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 *content_document;
+ WebKitDOMElement *element;
+
+ iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT (
+ webkit_dom_node_list_item (frames, ii));
+
+ content_document = webkit_dom_html_iframe_element_get_content_document (iframe);
+ if (!content_document)
+ continue;
+
+ element = e_dom_utils_find_element_by_id (content_document, id);
+
+ if (element != NULL) {
+ g_object_unref (frames);
+ return element;
+ }
+ }
+
+ g_object_unref (frames);
+ return NULL;
+}
+
+gboolean
+e_dom_utils_element_exists (WebKitDOMDocument *document,
+ const gchar *element_id)
+{
+ WebKitDOMNodeList *frames;
+ gboolean element_exists = FALSE;
+ gulong ii, length;
+
+ /* Try to look up the element in this DOM document */
+ if (webkit_dom_document_get_element_by_id (document, element_id))
+ return TRUE;
+
+ /* 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 *content_document;
+
+ iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT (
+ webkit_dom_node_list_item (frames, ii));
+
+ content_document = webkit_dom_html_iframe_element_get_content_document (iframe);
+ if (!content_document)
+ continue;
+
+ element_exists = e_dom_utils_element_exists (content_document, element_id);
+
+ if (element_exists) {
+ g_object_unref (frames);
+ return TRUE;
+ }
+ }
+
+ g_object_unref (frames);
+ return FALSE;
+}
+
+gchar *
+e_dom_utils_get_active_element_name (WebKitDOMDocument *document)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_get_active_element (document);
+
+ if (!element)
+ return NULL;
+
+ while (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) {
+ WebKitDOMDocument *content_document;
+
+ content_document =
+ webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
+
+ if (!content_document)
+ break;
+
+ element = webkit_dom_document_get_active_element (content_document);
+ }
+
+ return webkit_dom_node_get_local_name (WEBKIT_DOM_NODE (element));
+}
+
+void
+e_dom_utils_e_mail_part_headers_bind_dom_element (WebKitDOMDocument *document,
+ const gchar *element_id)
+{
+ WebKitDOMDocument *element_document;
+ WebKitDOMElement *element;
+ WebKitDOMElement *photo;
+ gchar *addr, *uri;
+
+ 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));
+ photo = webkit_dom_document_get_element_by_id (
+ element_document, "__evo-contact-photo");
+
+ /* Contact photos disabled, the <img> tag is not there. */
+ if (!photo)
+ return;
+
+ addr = webkit_dom_element_get_attribute (photo, "data-mailaddr");
+ uri = g_strdup_printf ("mail://contact-photo?mailaddr=%s", addr);
+
+ webkit_dom_html_image_element_set_src (
+ WEBKIT_DOM_HTML_IMAGE_ELEMENT (photo), uri);
+
+ g_free (addr);
+ g_free (uri);
+}
+
+void
+e_dom_utils_element_set_inner_html (WebKitDOMDocument *document,
+ const gchar *element_id,
+ const gchar *inner_html)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_get_element_by_id (document, element_id);
+
+ if (!element)
+ return;
+
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element), inner_html, NULL);
+}
+
+void
+e_dom_utils_remove_element (WebKitDOMDocument *document,
+ const gchar *element_id)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_get_element_by_id (document, element_id);
+
+ if (!element)
+ return;
+
+ webkit_dom_node_remove_child (
+ webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+ WEBKIT_DOM_NODE (element),
+ NULL);
+}
+
+void
+e_dom_utils_element_remove_child_nodes (WebKitDOMDocument *document,
+ const gchar *element_id)
+{
+ WebKitDOMNode *node;
+
+ node = WEBKIT_DOM_NODE (webkit_dom_document_get_element_by_id (document, element_id));
+
+ if (!node)
+ return;
+
+ while (webkit_dom_node_has_child_nodes (node)) {
+ webkit_dom_node_remove_child (
+ node,
+ webkit_dom_node_get_last_child (node),
+ NULL);
+ }
+}
+
+void
+e_dom_utils_hide_element (WebKitDOMDocument *document,
+ const gchar *element_id,
+ gboolean hide)
+{
+ WebKitDOMElement *element;
+
+ 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), hide);
+}
+
+gboolean
+e_dom_utils_element_is_hidden (WebKitDOMDocument *document,
+ const gchar *element_id)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_get_element_by_id (document, element_id);
+
+ if (!element)
+ return FALSE;
+
+ return webkit_dom_html_element_get_hidden (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+}
+
+static void
+get_total_offsets (WebKitDOMElement *element,
+ glong *left,
+ glong *top)
+{
+ WebKitDOMElement *offset_parent;
+
+ if (left)
+ *left = 0;
+
+ if (top)
+ *top = 0;
+
+ offset_parent = element;
+ do {
+ if (left) {
+ *left += webkit_dom_element_get_offset_left (offset_parent);
+ *left -= webkit_dom_element_get_scroll_left (offset_parent);
+ }
+ if (top) {
+ *top += webkit_dom_element_get_offset_top (offset_parent);
+ *top -= webkit_dom_element_get_scroll_top (offset_parent);
+ }
+ offset_parent = webkit_dom_element_get_offset_parent (offset_parent);
+ } while (offset_parent);
+}
+
+static WebKitDOMElement *
+find_element_from_point (WebKitDOMDocument *document,
+ gint32 x,
+ gint32 y,
+ WebKitDOMElement *element_on_point)
+{
+ WebKitDOMDocument *content_document;
+ WebKitDOMElement *element;
+
+ if (!element_on_point)
+ element = webkit_dom_document_element_from_point (document, x, y);
+ else {
+ glong left, top;
+ get_total_offsets (element_on_point, &left, &top);
+
+ element = webkit_dom_document_element_from_point (
+ document, x - left, y - top);
+ }
+
+ if (!element)
+ return element_on_point;
+
+ if (element_on_point && webkit_dom_node_is_equal_node (
+ WEBKIT_DOM_NODE (element),
+ WEBKIT_DOM_NODE (element_on_point))) {
+ return element_on_point;
+ }
+
+ if (!WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element))
+ return element_on_point;
+
+ content_document =
+ webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
+
+ if (!content_document)
+ return element_on_point;
+
+ return find_element_from_point (content_document, x, y, element);
+}
+
+/* ! This function can be called only from WK2 web-extension ! */
+WebKitDOMElement *
+e_dom_utils_get_element_from_point (WebKitDOMDocument *document,
+ gint32 x,
+ gint32 y)
+{
+ return find_element_from_point (document, x, y, NULL);
+}
+
+/* ! This function can be called only from WK2 web-extension ! */
+WebKitDOMDocument *
+e_dom_utils_get_document_from_point (WebKitDOMDocument *document,
+ gint32 x,
+ gint32 y)
+{
+ WebKitDOMElement *element;
+
+ if (x == 0 && y == 0)
+ element = webkit_dom_document_get_active_element (document);
+ else
+ element = find_element_from_point (document, x, y, NULL);
+
+ if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element))
+ return webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
+ else
+ return webkit_dom_node_get_owner_document (
+ WEBKIT_DOM_NODE (element));
+}
+
+/* VCard Inline Module DOM functions */
+
+static void
+display_mode_toggle_button_cb (WebKitDOMElement *button,
+ WebKitDOMEvent *event,
+ GDBusConnection *connection)
+{
+ GError *error = NULL;
+ gchar *element_id;
+
+ element_id = webkit_dom_element_get_id (button);
+
+ g_dbus_connection_emit_signal (
+ connection,
+ NULL,
+ EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+ EVOLUTION_WEB_EXTENSION_INTERFACE,
+ "VCardInlineDisplayModeToggled",
+ g_variant_new ("(s)", element_id),
+ &error);
+
+ if (error) {
+ g_warning ("Error emitting signal DisplayModeToggled: %s\n", error->message);
+ g_error_free (error);
+ }
+
+ g_free (element_id);
+}
+
+static void
+save_vcard_button_cb (WebKitDOMElement *button,
+ WebKitDOMEvent *event,
+ GDBusConnection *connection)
+{
+ GError *error = NULL;
+ gchar *button_value;
+
+ button_value = webkit_dom_html_button_element_get_value (
+ WEBKIT_DOM_HTML_BUTTON_ELEMENT (button));
+
+ g_dbus_connection_emit_signal (
+ connection,
+ NULL,
+ EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+ EVOLUTION_WEB_EXTENSION_INTERFACE,
+ "VCardInlineSaveButtonPressed",
+ g_variant_new ("(s)", button_value),
+ &error);
+
+ if (error) {
+ g_warning ("Error emitting signal SaveVCardButtonPressed: %s\n", error->message);
+ g_error_free (error);
+ }
+
+ g_free (button_value);
+}
+
+void
+e_dom_utils_module_vcard_inline_bind_dom (WebKitDOMDocument *document,
+ const gchar *element_id,
+ GDBusConnection *connection)
+{
+ WebKitDOMElement *element;
+ WebKitDOMDocument *element_document;
+ gchar *selector;
+
+ 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));
+
+ selector = g_strconcat ("button[id='", element_id, "']", NULL);
+ e_dom_utils_bind_dom (
+ element_document,
+ selector,
+ "click",
+ display_mode_toggle_button_cb,
+ connection);
+ g_free (selector);
+
+ selector = g_strconcat ("button[value='", element_id, "']", NULL);
+ e_dom_utils_bind_dom (
+ element_document,
+ selector,
+ "click",
+ save_vcard_button_cb,
+ connection);
+ g_free (selector);
+
+ e_dom_utils_eab_contact_formatter_bind_dom (element_document);
+}
+
+void
+e_dom_utils_module_vcard_inline_update_button (WebKitDOMDocument *document,
+ const gchar *button_id,
+ const gchar *html_label,
+ const gchar *access_key)
+{
+ WebKitDOMElement *element;
+ gchar *selector;
+
+ selector = g_strconcat ("button[id='", button_id, "']", 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 *button_id,
+ const gchar *src)
+{
+ WebKitDOMElement *element, *parent, *iframe;
+ gchar *selector;
+
+ selector = g_strconcat ("button[id='", button_id, "']", NULL);
+ element = e_dom_utils_find_element_by_selector (document, selector);
+ g_free (selector);
+
+ parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (element));
+ if (!parent)
+ return;
+
+ iframe = webkit_dom_element_query_selector (parent, "iframe", NULL);
+ if (!iframe)
+ return;
+
+ webkit_dom_html_iframe_element_set_src (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe), src);
+}
diff --git a/e-util/e-dom-utils.h b/e-util/e-dom-utils.h
new file mode 100644
index 0000000..2da7d94
--- /dev/null
+++ b/e-util/e-dom-utils.h
@@ -0,0 +1,107 @@
+/*
+ * e-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 E_DOM_UTILS_H
+#define E_DOM_UTILS_H
+
+#include <webkitdom/webkitdom.h>
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void e_dom_utils_replace_local_image_links
+ (WebKitDOMDocument *document);
+gchar * e_dom_utils_get_document_content_html
+ (WebKitDOMDocument *document);
+gchar * e_dom_utils_get_selection_content_html
+ (WebKitDOMDocument *document);
+gchar * e_dom_utils_get_selection_content_text
+ (WebKitDOMDocument *document);
+void e_dom_utils_create_and_add_css_style_sheet
+ (WebKitDOMDocument *document,
+ const gchar *style_sheet_id);
+void e_dom_utils_add_css_rule_into_style_sheet
+ (WebKitDOMDocument *document,
+ const gchar *style_sheet_id,
+ const gchar *selector,
+ const gchar *style);
+void e_dom_utils_eab_contact_formatter_bind_dom
+ (WebKitDOMDocument *document);
+void e_dom_utils_bind_focus_on_elements
+ (WebKitDOMDocument *document,
+ GDBusConnection *connection);
+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
+ (WebKitDOMDocument *document,
+ const gchar *element_id);
+gchar * e_dom_utils_get_active_element_name
+ (WebKitDOMDocument *document);
+void e_dom_utils_e_mail_part_headers_bind_dom_element
+ (WebKitDOMDocument *document,
+ const gchar *element_id);
+void e_dom_utils_element_set_inner_html
+ (WebKitDOMDocument *document,
+ const gchar *element_id,
+ const gchar *inner_html);
+void e_dom_utils_remove_element (WebKitDOMDocument *document,
+ const gchar *element_id);
+void e_dom_utils_element_remove_child_nodes
+ (WebKitDOMDocument *document,
+ const gchar *element_id);
+void e_dom_utils_hide_element (WebKitDOMDocument *document,
+ const gchar *element_id,
+ gboolean hide);
+gboolean e_dom_utils_element_is_hidden (WebKitDOMDocument *document,
+ const gchar *element_id);
+WebKitDOMElement *
+ e_dom_utils_get_element_from_point
+ (WebKitDOMDocument *document,
+ gint32 x,
+ gint32 y);
+WebKitDOMDocument *
+ e_dom_utils_get_document_from_point
+ (WebKitDOMDocument *document,
+ gint32 x,
+ gint32 y);
+/* 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_id,
+ const gchar *html_label,
+ const gchar *access_key);
+void e_dom_utils_module_vcard_inline_set_iframe_src
+ (WebKitDOMDocument *document,
+ const gchar *button_id,
+ const gchar *src);
+G_END_DECLS
+
+#endif /* E_DOM_UTILS_H */
diff --git a/e-util/e-mail-signature-preview.c b/e-util/e-mail-signature-preview.c
index f125c8b..9312ff7 100644
--- a/e-util/e-mail-signature-preview.c
+++ b/e-util/e-mail-signature-preview.c
@@ -56,56 +56,31 @@ G_DEFINE_TYPE (
E_TYPE_WEB_VIEW)
static void
-replace_local_image_links (WebKitDOMDocument *document)
-{
- gint ii, length;
- WebKitDOMNodeList *list;
-
- list = webkit_dom_document_query_selector_all (
- document, "img[src^=\"file://\"]", NULL);
- length = webkit_dom_node_list_get_length (list);
-
- for (ii = 0; ii < length; ii++) {
- gchar *src, *new_src;
- WebKitDOMHTMLImageElement *img;
-
- img = WEBKIT_DOM_HTML_IMAGE_ELEMENT (
- webkit_dom_node_list_item (list, ii));
- src = webkit_dom_html_image_element_get_src (img);
-
- /* this forms "evo-file://", which can be loaded,
- * while "file://" cannot be, due to WebKit policy */
- new_src = g_strconcat ("evo-", src, NULL);
- webkit_dom_html_image_element_set_src (img, new_src);
- g_free (new_src);
- g_free (src);
- }
- g_object_unref (list);
-
- list = webkit_dom_document_get_elements_by_tag_name ( document, "iframe");
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMDocument *content_document;
- WebKitDOMHTMLIFrameElement *iframe;
-
- iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT (
- webkit_dom_node_list_item (list, ii));
-
- content_document =
- webkit_dom_html_iframe_element_get_content_document (iframe);
-
- if (content_document && WEBKIT_DOM_IS_DOCUMENT (content_document))
- replace_local_image_links (content_document);
- }
- g_object_unref (list);
-}
-
-static void
signature_preview_document_loaded_cb (WebKitWebView *web_view,
WebKitWebFrame *web_frame,
gpointer user_data)
{
- replace_local_image_links (webkit_web_view_get_dom_document (web_view));
+ GDBusProxy *web_extension;
+ GVariant* result;
+
+ if (load_event != WEBKIT_LOAD_FINISHED)
+ return;
+
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (web_view));
+ if (web_extension) {
+ result = g_dbus_proxy_call_sync (
+ web_extension,
+ "ReplaceLocalImageLinks",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (web_view)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, //cancellable
+ NULL);
+ if (result)
+ g_variant_unref (result);
+ }
}
static void
@@ -361,7 +336,7 @@ e_mail_signature_preview_init (EMailSignaturePreview *preview)
preview->priv = E_MAIL_SIGNATURE_PREVIEW_GET_PRIVATE (preview);
g_signal_connect (
- preview, "document-load-finished",
+ preview, "load-changed",
G_CALLBACK (signature_preview_document_loaded_cb), NULL);
}
diff --git a/e-util/e-search-bar.c b/e-util/e-search-bar.c
index d3ade35..3410509 100644
--- a/e-util/e-search-bar.c
+++ b/e-util/e-search-bar.c
@@ -44,9 +44,11 @@ struct _ESearchBarPrivate {
GtkWidget *prev_button;
GtkWidget *next_button;
+ WebKitFindController *find_controller;
+
gchar *active_search;
- guint rerun_search : 1;
+ gboolean search_forward;
};
enum {
@@ -77,7 +79,6 @@ search_bar_update_matches (ESearchBar *search_bar,
GtkWidget *matches_label;
gchar *text;
- search_bar->priv->rerun_search = FALSE;
matches_label = search_bar->priv->matches_label;
text = g_strdup_printf (_("Matches: %u"), matches);
@@ -86,14 +87,88 @@ search_bar_update_matches (ESearchBar *search_bar,
g_free (text);
}
+ static void
+webkit_find_controller_found_text_cb (WebKitFindController *find_controller,
+ guint match_count,
+ ESearchBar *search_bar)
+{
+ GtkWidget *widget;
+ WebKitFindOptions options;
+ gboolean wrapped = FALSE;
+
+ search_bar_update_matches (search_bar, match_count);
+
+ g_free (search_bar->priv->active_search);
+ search_bar->priv->active_search =
+ g_strdup (webkit_find_controller_get_search_text (find_controller));
+
+ gtk_widget_set_sensitive (search_bar->priv->next_button, TRUE);
+ gtk_widget_set_sensitive (search_bar->priv->prev_button, TRUE);
+
+ g_object_notify (G_OBJECT (search_bar), "active-search");
+
+ options = webkit_find_controller_get_options (find_controller);
+
+ if (options & WEBKIT_FIND_OPTIONS_WRAP_AROUND)
+ wrapped = TRUE;
+
+ /* Update wrapped label visibility. */
+ widget = search_bar->priv->wrapped_next_box;
+
+ if (wrapped && search_bar->priv->search_forward)
+ gtk_widget_show (widget);
+ else
+ gtk_widget_hide (widget);
+
+ widget = search_bar->priv->wrapped_prev_box;
+
+ if (wrapped && !search_bar->priv->search_forward)
+ gtk_widget_show (widget);
+ else
+ gtk_widget_hide (widget);
+}
+
static void
-search_bar_update_highlights (ESearchBar *search_bar)
+webkit_find_controller_failed_to_found_text_cb (WebKitFindController *find_controller,
+ ESearchBar *search_bar)
{
- EWebView *web_view;
+ WebKitFindOptions options;
+ GtkWidget *widget;
+
+ options = webkit_find_controller_get_options (find_controller);
+
+ /* If we didn't find anything, try from the beggining with WRAP_AROUND option */
+ if (!(options & WEBKIT_FIND_OPTIONS_WRAP_AROUND)) {
+ webkit_find_controller_search (
+ find_controller,
+ webkit_find_controller_get_search_text (find_controller),
+ options | WEBKIT_FIND_OPTIONS_WRAP_AROUND,
+ G_MAXUINT);
+ }
+
+ search_bar_update_matches (search_bar, 0);
+
+ g_free (search_bar->priv->active_search);
+ search_bar->priv->active_search =
+ g_strdup (webkit_find_controller_get_search_text (find_controller));
+
+ gtk_widget_set_sensitive (search_bar->priv->next_button, FALSE);
+ gtk_widget_set_sensitive (search_bar->priv->prev_button, FALSE);
+
+ g_object_notify (G_OBJECT (search_bar), "active-search");
+
+ /* Update wrapped label visibility. */
+ widget = search_bar->priv->wrapped_next_box;
+ gtk_widget_hide (widget);
- web_view = e_search_bar_get_web_view (search_bar);
+ widget = search_bar->priv->wrapped_prev_box;
+ gtk_widget_hide (widget);
+}
- webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+static void
+search_bar_update_highlights (ESearchBar *search_bar)
+{
+ webkit_find_controller_search_finish (search_bar->priv->find_controller);
e_search_bar_changed (search_bar);
}
@@ -102,15 +177,13 @@ static void
search_bar_find (ESearchBar *search_bar,
gboolean search_forward)
{
- EWebView *web_view;
- GtkWidget *widget;
+ WebKitFindController *find_controller;
gboolean case_sensitive;
- gboolean wrapped = FALSE;
- gboolean success;
gchar *text;
- guint matches;
- web_view = e_search_bar_get_web_view (search_bar);
+ find_controller = search_bar->priv->find_controller;
+ search_bar->priv->search_forward = search_forward;
+
case_sensitive = e_search_bar_get_case_sensitive (search_bar);
text = e_search_bar_get_text (search_bar);
@@ -120,46 +193,14 @@ search_bar_find (ESearchBar *search_bar,
return;
}
- webkit_web_view_unmark_text_matches (
- WEBKIT_WEB_VIEW (web_view));
- matches = webkit_web_view_mark_text_matches (
- WEBKIT_WEB_VIEW (web_view),
- text, case_sensitive, 0);
- webkit_web_view_set_highlight_text_matches (
- WEBKIT_WEB_VIEW (web_view), TRUE);
- search_bar_update_matches (search_bar, matches);
-
- success = webkit_web_view_search_text (
- WEBKIT_WEB_VIEW (web_view),
- text, case_sensitive, search_forward, FALSE);
-
- if (!success)
- wrapped = webkit_web_view_search_text (
- WEBKIT_WEB_VIEW (web_view),
- text, case_sensitive, search_forward, TRUE);
-
- g_free (search_bar->priv->active_search);
- search_bar->priv->active_search = text;
-
- gtk_widget_set_sensitive (search_bar->priv->next_button, matches != 0);
- gtk_widget_set_sensitive (search_bar->priv->prev_button, matches != 0);
-
- g_object_notify (G_OBJECT (search_bar), "active-search");
-
- /* Update wrapped label visibility. */
- widget = search_bar->priv->wrapped_next_box;
+ webkit_find_controller_search_finish (find_controller);
+ webkit_find_controller_search (
+ find_controller,
+ text,
+ case_sensitive ? WEBKIT_FIND_OPTIONS_NONE : WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE,
+ G_MAXUINT);
- if (wrapped && search_forward)
- gtk_widget_show (widget);
- else
- gtk_widget_hide (widget);
-
- widget = search_bar->priv->wrapped_prev_box;
-
- if (wrapped && !search_forward)
- gtk_widget_show (widget);
- else
- gtk_widget_hide (widget);
+ g_free (text);
}
static void
@@ -202,15 +243,14 @@ search_bar_toggled_cb (ESearchBar *search_bar)
}
static void
-web_view_load_status_changed_cb (WebKitWebView *webkit_web_view,
- GParamSpec *pspec,
- gpointer user_data)
+web_view_load_changed_cb (WebKitWebView *webkit_web_view,
+ WebKitLoadEvent load_event,
+ gpointer user_data)
{
- WebKitLoadStatus status;
ESearchBar *search_bar;
status = webkit_web_view_get_load_status (webkit_web_view);
- if (status != WEBKIT_LOAD_FINISHED)
+ if (load_event != WEBKIT_LOAD_FINISHED)
return;
if (!user_data)
@@ -231,14 +271,29 @@ static void
search_bar_set_web_view (ESearchBar *search_bar,
EWebView *web_view)
{
+ WebKitFindController *find_controller;
+
g_return_if_fail (E_IS_WEB_VIEW (web_view));
g_return_if_fail (search_bar->priv->web_view == NULL);
search_bar->priv->web_view = g_object_ref (web_view);
+ find_controller =
+ webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (web_view));
+
+ search_bar->priv->find_controller = find_controller;
+
e_signal_connect_notify (
- web_view, "notify::load-status",
- G_CALLBACK (web_view_load_status_changed_cb), search_bar);
+ web_view, "notify::changed",
+ G_CALLBACK (web_view_load_changed_cb), search_bar);
+
+ g_signal_connect (
+ find_controller, "found-text",
+ G_CALLBACK (webkit_find_controller_found_text_cb), search_bar);
+
+ g_signal_connect (
+ find_controller, "failed-to-find-text",
+ G_CALLBACK (webkit_find_controller_failed_to_found_text_cb), search_bar);
}
static void
@@ -390,7 +445,6 @@ static void
search_bar_show (GtkWidget *widget)
{
ESearchBar *search_bar;
- EWebView *web_view;
search_bar = E_SEARCH_BAR (widget);
@@ -399,8 +453,7 @@ search_bar_show (GtkWidget *widget)
gtk_widget_grab_focus (search_bar->priv->entry);
- web_view = e_search_bar_get_web_view (search_bar);
- webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+ webkit_find_controller_search_finish (search_bar->priv->find_controller);
search_bar_find (search_bar, TRUE);
}
@@ -439,8 +492,6 @@ search_bar_key_press_event (GtkWidget *widget,
static void
search_bar_clear (ESearchBar *search_bar)
{
- WebKitWebView *web_view;
-
g_free (search_bar->priv->active_search);
search_bar->priv->active_search = NULL;
@@ -452,9 +503,6 @@ search_bar_clear (ESearchBar *search_bar)
search_bar_update_highlights (search_bar);
- web_view = WEBKIT_WEB_VIEW (search_bar->priv->web_view);
- webkit_web_view_unmark_text_matches (web_view);
-
g_object_notify (G_OBJECT (search_bar), "active-search");
}
diff --git a/e-util/e-util.h b/e-util/e-util.h
index e2481eb..e03f6b6 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -91,6 +91,7 @@
#include <e-util/e-destination-store.h>
#include <e-util/e-dialog-utils.h>
#include <e-util/e-dialog-widgets.h>
+#include <e-util/e-dom-utils.h>
#include <e-util/e-emoticon-action.h>
#include <e-util/e-emoticon-chooser-menu.h>
#include <e-util/e-emoticon-chooser.h>
diff --git a/e-util/e-web-view-preview.c b/e-util/e-web-view-preview.c
index 0e6b51e..5c0dabe 100644
--- a/e-util/e-web-view-preview.c
+++ b/e-util/e-web-view-preview.c
@@ -173,19 +173,19 @@ in_scrolled_window (GtkWidget *widget)
static void
e_web_view_preview_init (EWebViewPreview *preview)
{
- GtkWidget *tree_view_sw, *web_view_sw;
+ GtkWidget *tree_view_sw, *web_view;
preview->priv = E_WEB_VIEW_PREVIEW_GET_PRIVATE (preview);
preview->priv->escape_values = TRUE;
tree_view_sw = in_scrolled_window (gtk_tree_view_new ());
- web_view_sw = in_scrolled_window (e_web_view_new ());
+ web_view = e_web_view_new ();
gtk_widget_hide (tree_view_sw);
- gtk_widget_show (web_view_sw);
+ gtk_widget_show (web_view);
gtk_paned_pack1 (GTK_PANED (preview), tree_view_sw, FALSE, TRUE);
- gtk_paned_pack2 (GTK_PANED (preview), web_view_sw, TRUE, TRUE);
+ gtk_paned_pack2 (GTK_PANED (preview), web_view, TRUE, TRUE);
/* rawly 3 lines of a text plus a little bit more */
if (gtk_paned_get_position (GTK_PANED (preview)) < 85)
@@ -211,7 +211,7 @@ e_web_view_preview_get_preview (EWebViewPreview *preview)
{
g_return_val_if_fail (E_IS_WEB_VIEW_PREVIEW (preview), NULL);
- return gtk_bin_get_child (GTK_BIN (gtk_paned_get_child2 (GTK_PANED (preview))));
+ return gtk_paned_get_child2 (GTK_PANED (preview));
}
void
@@ -223,7 +223,7 @@ e_web_view_preview_set_preview (EWebViewPreview *preview,
g_return_if_fail (E_IS_WEB_VIEW_PREVIEW (preview));
g_return_if_fail (GTK_IS_WIDGET (preview_widget));
- old_child = gtk_bin_get_child (GTK_BIN (gtk_paned_get_child2 (GTK_PANED (preview))));
+ old_child = gtk_paned_get_child2 (GTK_PANED (preview));
if (old_child) {
g_return_if_fail (old_child != preview_widget);
gtk_widget_destroy (old_child);
diff --git a/e-util/e-web-view.c b/e-util/e-web-view.c
index ad94c83..838f212 100644
--- a/e-util/e-web-view.c
+++ b/e-util/e-web-view.c
@@ -40,6 +40,8 @@
#include "e-selectable.h"
#include "e-stock-request.h"
+#include "../web-extensions/evolution-web-extension.h"
+
#define E_WEB_VIEW_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_WEB_VIEW, EWebViewPrivate))
@@ -71,6 +73,11 @@ struct _EWebViewPrivate {
gulong antialiasing_changed_handler_id;
GHashTable *old_settings;
+
+ GDBusProxy *web_extension;
+ guint web_extension_watch_name_id;
+
+ WebKitFindController *find_controller;
};
struct _AsyncContext {
@@ -103,7 +110,6 @@ enum {
};
static guint signals[LAST_SIGNAL];
-static GOnce disable_webkit_3rd_party_plugins_once = G_ONCE_INIT;
static const gchar *ui =
"<ui>"
@@ -353,36 +359,6 @@ static GtkActionEntry standard_entries[] = {
};
static void
-web_view_init_web_settings (WebKitWebView *web_view)
-{
- WebKitWebSettings *web_settings;
-
- web_settings = webkit_web_settings_new ();
-
- g_object_set (
- G_OBJECT (web_settings),
- "enable-frame-flattening", TRUE,
- "enable-java-applet", FALSE,
- "enable-html5-database", FALSE,
- "enable-html5-local-storage", FALSE,
- "enable-offline-web-application-cache", FALSE,
- "enable-site-specific-quirks", TRUE,
- "enable-scripts", FALSE,
- "respect-image-orientation", TRUE,
- NULL);
-
- g_object_bind_property (
- web_settings, "enable-caret-browsing",
- web_view, "caret-mode",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- webkit_web_view_set_settings (web_view, web_settings);
-
- g_object_unref (web_settings);
-}
-
-static void
web_view_menu_item_select_cb (EWebView *web_view,
GtkWidget *widget)
{
@@ -401,20 +377,57 @@ web_view_menu_item_select_cb (EWebView *web_view,
}
static void
+webkit_find_controller_found_text_cb (WebKitFindController *find_controller,
+ guint match_count,
+ EWebView *web_view)
+{
+}
+
+static void
+webkit_find_controller_failed_to_found_text_cb (WebKitFindController *find_controller,
+ EWebView *web_view)
+{
+}
+
+static void
+web_view_set_find_controller (EWebView *web_view)
+{
+ WebKitFindController *find_controller;
+
+ find_controller =
+ webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (web_view));
+
+ g_signal_connect (
+ find_controller, "found-text",
+ G_CALLBACK (webkit_find_controller_found_text_cb), web_view);
+
+ g_signal_connect (
+ find_controller, "failed-to-find-text",
+ G_CALLBACK (webkit_find_controller_failed_to_found_text_cb), web_view);
+
+ web_view->priv->find_controller = find_controller;
+}
+
+static void
web_view_update_document_highlights (EWebView *web_view)
{
- WebKitWebView *webkit_web_view;
+ WebKitFindController *find_controller;
GList *head, *link;
- webkit_web_view = WEBKIT_WEB_VIEW (web_view);
+ if (!web_view->priv->find_controller)
+ web_view_set_find_controller (web_view);
- head = g_queue_peek_head_link (&web_view->priv->highlights);
+ find_controller = web_view->priv->find_controller;
- for (link = head; link != NULL; link = g_list_next (link))
- webkit_web_view_mark_text_matches (
- webkit_web_view, link->data, FALSE, 0);
+ head = g_queue_peek_head_link (&web_view->priv->highlights);
- webkit_web_view_set_highlight_text_matches (webkit_web_view, TRUE);
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ webkit_find_controller_search (
+ find_controller,
+ link->data,
+ WEBKIT_FIND_OPTIONS_NONE,
+ G_MAXUINT);
+ }
}
static void
@@ -442,9 +455,10 @@ web_view_connect_proxy_cb (EWebView *web_view,
static gboolean
web_view_context_menu_cb (WebKitWebView *webkit_web_view,
- GtkWidget *default_menu,
+ WebKitContextMenu *context_menu,
+ GdkEvent *event,
WebKitHitTestResult *hit_test_result,
- gboolean triggered_with_keyboard)
+ gpointer user_data)
{
WebKitHitTestResultContext context;
EWebView *web_view;
@@ -459,7 +473,7 @@ web_view_context_menu_cb (WebKitWebView *webkit_web_view,
if (hit_test_result == NULL)
return FALSE;
- g_object_get (hit_test_result, "context", &context, NULL);
+ context = webkit_hit_test_result_get_context (hit_test_result);
if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) {
gchar *image_uri = NULL;
@@ -484,7 +498,7 @@ web_view_context_menu_cb (WebKitWebView *webkit_web_view,
return event_handled;
}
-
+#if 0
static GtkWidget *
web_view_create_plugin_widget_cb (EWebView *web_view,
const gchar *mime_type,
@@ -502,13 +516,15 @@ web_view_create_plugin_widget_cb (EWebView *web_view,
return class->create_plugin_widget (web_view, mime_type, uri, param);
}
-
+#endif
static void
-web_view_hovering_over_link_cb (EWebView *web_view,
- const gchar *title,
- const gchar *uri)
+web_view_mouse_target_changed_cb (EWebView *web_view,
+ WebKitHitTestResult *hit_test_result,
+ guint modifiers,
+ gpointer user_data)
{
EWebViewClass *class;
+ const gchar *title, *uri;
/* XXX WebKitWebView does not provide a class method for
* this signal, so we do so we can override the default
@@ -517,26 +533,40 @@ web_view_hovering_over_link_cb (EWebView *web_view,
class = E_WEB_VIEW_GET_CLASS (web_view);
g_return_if_fail (class->hovering_over_link != NULL);
+ title = webkit_hit_test_result_get_link_title (hit_test_result);
+ uri = webkit_hit_test_result_get_link_uri (hit_test_result);
+
class->hovering_over_link (web_view, title, uri);
}
static gboolean
-web_view_navigation_policy_decision_requested_cb (EWebView *web_view,
- WebKitWebFrame *frame,
- WebKitNetworkRequest *request,
- WebKitWebNavigationAction *navigation_action,
- WebKitWebPolicyDecision *policy_decision)
+web_view_decide_policy_cb (EWebView *web_view,
+ WebKitPolicyDecision *decision,
+ WebKitPolicyDecisionType type)
{
EWebViewClass *class;
- WebKitWebNavigationReason reason;
+ WebKitNavigationPolicyDecision *navigation_decision;
+ WebKitNavigationAction *navigation_action;
+ WebKitNavigationType navigation_type;
+ WebKitURIRequest *request;
const gchar *uri, *frame_uri;
- reason = webkit_web_navigation_action_get_reason (navigation_action);
- if (reason != WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED)
+ if (type != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
+ return FALSE;
+
+ navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
+ navigation_action = webkit_navigation_policy_decision_get_navigation_action (navigation_decision);
+ navigation_type = webkit_navigation_action_get_navigation_type (navigation_action);
+
+ if (navigation_type != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED) {
return FALSE;
+ }
- uri = webkit_network_request_get_uri (request);
- frame_uri = webkit_web_frame_get_uri (frame);
+ request = webkit_navigation_action_get_request (navigation_action);
+ uri = webkit_uri_request_get_uri (request);
+ /* FIXME XXX WK2 */
+// frame_uri = webkit_web_frame_get_uri (frame);
+ frame_uri = "";
/* Allow navigation through fragments in page */
if (uri && *uri && frame_uri && *frame_uri) {
@@ -588,7 +618,7 @@ web_view_navigation_policy_decision_requested_cb (EWebView *web_view,
class = E_WEB_VIEW_GET_CLASS (web_view);
g_return_val_if_fail (class->link_clicked != NULL, FALSE);
- webkit_web_policy_decision_ignore (policy_decision);
+ webkit_policy_decision_ignore (decision);
class->link_clicked (web_view, uri);
@@ -621,7 +651,7 @@ style_updated_cb (EWebView *web_view)
e_web_view_add_css_rule_into_style_sheet (
web_view,
- "-e-web-view-css-sheet",
+ "-e-web-view-style-sheet",
".-e-web-view-background-color",
style);
@@ -640,7 +670,7 @@ style_updated_cb (EWebView *web_view)
e_web_view_add_css_rule_into_style_sheet (
web_view,
- "-e-web-view-css-sheet",
+ "-e-web-view-style-sheet",
".-e-web-view-text-color",
style);
@@ -649,18 +679,15 @@ style_updated_cb (EWebView *web_view)
}
static void
-web_view_load_status_changed_cb (WebKitWebView *webkit_web_view,
- GParamSpec *pspec,
- gpointer user_data)
+web_view_load_changed_cb (WebKitWebView *webkit_web_view,
+ WebKitLoadEvent load_event,
+ gpointer user_data)
{
- WebKitLoadStatus status;
EWebView *web_view;
web_view = E_WEB_VIEW (webkit_web_view);
- status = webkit_web_view_get_load_status (webkit_web_view);
-
- if (status != WEBKIT_LOAD_FINISHED)
+ if (load_event != WEBKIT_LOAD_FINISHED)
return;
style_updated_cb (web_view);
@@ -678,6 +705,46 @@ web_view_load_status_changed_cb (WebKitWebView *webkit_web_view,
}
}
+static GObjectConstructParam*
+find_property(guint n_properties,
+ GObjectConstructParam* properties,
+ GParamSpec* param_spec)
+{
+ while (n_properties--) {
+ if (properties->pspec == param_spec)
+ return properties;
+ properties++;
+ }
+
+ return NULL;
+}
+
+static GObject*
+web_view_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObjectClass* object_class;
+ GParamSpec* param_spec;
+ GObjectConstructParam *param = NULL;
+
+ object_class = G_OBJECT_CLASS(g_type_class_ref(type));
+ g_return_val_if_fail(object_class != NULL, NULL);
+
+ if (construct_properties && n_construct_properties != 0) {
+ param_spec = g_object_class_find_property(object_class, "settings");
+ if ((param = find_property(n_construct_properties, construct_properties, param_spec)))
+ g_value_take_object (param->value, e_web_view_get_default_webkit_settings ());
+ param_spec = g_object_class_find_property(object_class, "user-content-manager");
+ if ((param = find_property(n_construct_properties, construct_properties, param_spec)))
+ g_value_take_object (param->value, webkit_user_content_manager_new ());
+ }
+
+ g_type_class_unref (object_class);
+
+ return G_OBJECT_CLASS (e_web_view_parent_class)->constructor(type, n_construct_properties,
construct_properties);
+}
+
static void
web_view_set_property (GObject *object,
guint property_id,
@@ -824,12 +891,18 @@ web_view_dispose (GObject *object)
priv->antialiasing_changed_handler_id = 0;
}
+ 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;
+ }
+
g_clear_object (&priv->ui_manager);
g_clear_object (&priv->open_proxy);
g_clear_object (&priv->print_proxy);
g_clear_object (&priv->save_as_proxy);
g_clear_object (&priv->aliasing_settings);
g_clear_object (&priv->font_settings);
+ g_clear_object (&priv->web_extension);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_web_view_parent_class)->dispose (object);
@@ -858,8 +931,32 @@ web_view_finalize (GObject *object)
}
static void
+web_view_initialize (WebKitWebView *web_view)
+{
+ const gchar *id = "org.gnome.settings-daemon.plugins.xsettings";
+ GSettings *settings;
+ GSettingsSchema *settings_schema;
+
+ /* Optional schema */
+ settings_schema = g_settings_schema_source_lookup (
+ g_settings_schema_source_get_default (), id, FALSE);
+
+ if (settings_schema)
+ settings = g_settings_new (id);
+ else
+ settings = NULL;
+
+ e_web_view_update_fonts_settings (
+ g_settings_new ("org.gnome.desktop.interface"),
+ settings,
+ NULL, NULL, GTK_WIDGET (web_view));
+}
+
+
+static void
web_view_constructed (GObject *object)
{
+ WebKitSettings *web_settings;
#ifndef G_OS_WIN32
GSettings *settings;
@@ -882,6 +979,16 @@ web_view_constructed (GObject *object)
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_web_view_parent_class)->constructed (object);
+
+ web_settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (object));
+
+ g_object_bind_property (
+ web_settings, "enable-caret-browsing",
+ E_WEB_VIEW (object), "caret-mode",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ web_view_initialize (WEBKIT_WEB_VIEW (object));
}
static gboolean
@@ -919,7 +1026,8 @@ web_view_scroll_event (GtkWidget *widget,
}
}
- return FALSE;
+ return GTK_WIDGET_CLASS (e_web_view_parent_class)->
+ scroll_event (widget, event);
}
static gboolean
@@ -1073,9 +1181,8 @@ web_view_load_string (EWebView *web_view,
if (string == NULL)
string = "";
- webkit_web_view_load_string (
- WEBKIT_WEB_VIEW (web_view),
- string, "text/html", "UTF-8", "evo-file:///");
+ webkit_web_view_load_html (
+ WEBKIT_WEB_VIEW (web_view), string, "evo-file:///");
}
static void
@@ -1131,8 +1238,73 @@ web_view_stop_loading (EWebView *web_view)
}
static void
-web_view_update_actions (EWebView *web_view)
+web_extension_proxy_created_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ EWebView *web_view)
+{
+ GError *error = NULL;
+
+ web_view->priv->web_extension = g_dbus_proxy_new_finish (result, &error);
+ if (!web_view->priv->web_extension) {
+ g_warning ("Error creating web extension proxy: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+web_extension_appeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ EWebView *web_view)
+{
+ g_dbus_proxy_new (
+ connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ NULL,
+ name,
+ EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+ EVOLUTION_WEB_EXTENSION_INTERFACE,
+ NULL,
+ (GAsyncReadyCallback)web_extension_proxy_created_cb,
+ web_view);
+}
+
+static void
+web_extension_vanished_cb (GDBusConnection *connection,
+ const gchar *name,
+ EWebView *web_view)
+{
+ g_clear_object (&web_view->priv->web_extension);
+}
+
+static void
+web_view_watch_web_extension (EWebView *web_view)
+{
+ web_view->priv->web_extension_watch_name_id =
+ g_bus_watch_name (
+ G_BUS_TYPE_SESSION,
+ EVOLUTION_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ (GBusNameAppearedCallback) web_extension_appeared_cb,
+ (GBusNameVanishedCallback) web_extension_vanished_cb,
+ web_view, NULL);
+}
+
+GDBusProxy *
+e_web_view_get_web_extension_proxy (EWebView *web_view)
+{
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ return web_view->priv->web_extension;
+}
+
+static void
+web_view_update_actions_cb (WebKitWebView *webkit_web_view,
+ GAsyncResult *result,
+ gpointer user_data)
{
+ EWebView *web_view;
GtkActionGroup *action_group;
gboolean can_copy;
gboolean scheme_is_http = FALSE;
@@ -1143,8 +1315,11 @@ web_view_update_actions (EWebView *web_view)
const gchar *group_name;
const gchar *uri;
+ web_view = E_WEB_VIEW (webkit_web_view);
+
uri = e_web_view_get_selected_uri (web_view);
- can_copy = webkit_web_view_can_copy_clipboard (WEBKIT_WEB_VIEW (web_view));
+ can_copy = webkit_web_view_can_execute_editing_command_finish (
+ webkit_web_view, result, NULL);
cursor_image_src = e_web_view_get_cursor_image_src (web_view);
/* Parse the URI early so we know if the actions will work. */
@@ -1206,6 +1381,17 @@ web_view_update_actions (EWebView *web_view)
}
static void
+eb_view_update_actions (EWebView *web_view)
+{
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_COPY,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) web_view_update_actions_cb,
+ NULL);
+}
+
+static void
web_view_submit_alert (EAlertSink *alert_sink,
EAlert *alert)
{
@@ -1302,6 +1488,19 @@ web_view_submit_alert (EAlertSink *alert_sink,
}
static void
+web_view_can_execute_editing_command_cb (WebKitWebView *webkit_web_view,
+ GAsyncResult *result,
+ GtkAction *action)
+{
+ gboolean can_do_command;
+
+ can_do_command = webkit_web_view_can_execute_editing_command_finish (
+ webkit_web_view, result, NULL);
+
+ gtk_action_set_sensitive (action, can_do_command);
+}
+
+static void
web_view_selectable_update_actions (ESelectable *selectable,
EFocusTracker *focus_tracker,
GdkAtom *clipboard_targets,
@@ -1315,21 +1514,33 @@ web_view_selectable_update_actions (ESelectable *selectable,
web_view = WEBKIT_WEB_VIEW (selectable);
action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
- sensitive = webkit_web_view_can_cut_clipboard (web_view);
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_CUT,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) web_view_can_execute_editing_command_cb,
+ action);
tooltip = _("Cut the selection");
- gtk_action_set_sensitive (action, sensitive);
gtk_action_set_tooltip (action, tooltip);
action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
- sensitive = webkit_web_view_can_copy_clipboard (web_view);
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_COPY,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) web_view_can_execute_editing_command_cb,
+ action);
tooltip = _("Copy the selection");
- gtk_action_set_sensitive (action, sensitive);
gtk_action_set_tooltip (action, tooltip);
action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
- sensitive = webkit_web_view_can_paste_clipboard (web_view);
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_PASTE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) web_view_can_execute_editing_command_cb,
+ action);
tooltip = _("Paste the clipboard");
- gtk_action_set_sensitive (action, sensitive);
gtk_action_set_tooltip (action, tooltip);
action = e_focus_tracker_get_select_all_action (focus_tracker);
@@ -1385,30 +1596,6 @@ e_web_view_test_change_and_update_fonts_cb (EWebView *web_view,
}
}
-static gpointer
-web_view_disable_webkit_3rd_party_plugins (gpointer unused)
-{
- WebKitWebPluginDatabase *database;
- GSList *installed_plugins, *iterator;
-
- database = webkit_get_web_plugin_database ();
-
- if (!database)
- return NULL;
-
- installed_plugins = webkit_web_plugin_database_get_plugins (database);
-
- if (!installed_plugins)
- return NULL;
-
- for (iterator = installed_plugins; iterator; iterator = iterator->next)
- webkit_web_plugin_set_enabled (iterator->data, FALSE);
-
- webkit_web_plugin_database_plugins_list_free (installed_plugins);
-
- return NULL;
-}
-
static void
e_web_view_class_init (EWebViewClass *class)
{
@@ -1418,6 +1605,7 @@ e_web_view_class_init (EWebViewClass *class)
g_type_class_add_private (class, sizeof (EWebViewPrivate));
object_class = G_OBJECT_CLASS (class);
+ object_class->constructor = web_view_constructor;
object_class->set_property = web_view_set_property;
object_class->get_property = web_view_get_property;
object_class->dispose = web_view_dispose;
@@ -1577,10 +1765,6 @@ e_web_view_class_init (EWebViewClass *class)
NULL, NULL,
e_marshal_BOOLEAN__STRING,
G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
-
- webkit_set_cache_model (WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
- webkit_set_default_web_database_quota (0);
- webkit_application_cache_set_maximum_size (0);
}
static void
@@ -1600,6 +1784,300 @@ e_web_view_selectable_init (ESelectableInterface *iface)
}
static void
+web_view_process_uri_scheme_finished_cb (EWebView *web_view,
+ GAsyncResult *result,
+ WebKitURISchemeRequest *request)
+{
+ GError *error = NULL;
+
+ if (!g_task_propagate_boolean (G_TASK (result), &error)) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_warning ("URI %s cannot be processed: %s",
+ webkit_uri_scheme_request_get_uri (request),
+ error ? error->message : "Unknown error");
+ }
+ g_object_unref (request);
+ if (error)
+ g_error_free (error);
+ }
+}
+
+static void
+web_view_cid_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+ EWebView *web_view)
+{
+}
+
+static void
+web_view_process_file_uri_scheme_request (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ gboolean ret_val = FALSE;
+ const gchar *uri;
+ gchar *content = NULL;
+ gchar *content_type = NULL;
+ gchar *filename = NULL;
+ GInputStream *stream;
+ gsize length = 0;
+ GError *error = NULL;
+ WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
+
+ uri = webkit_uri_scheme_request_get_uri (request);
+
+ filename = g_filename_from_uri (strstr (uri, "file"), NULL, &error);
+ if (!filename)
+ goto out;
+
+ if (!g_file_get_contents (filename, &content, &length, &error))
+ goto out;
+
+ content_type = g_content_type_guess (filename, NULL, 0, NULL);
+
+ stream = g_memory_input_stream_new_from_data (content, length, g_free);
+
+ webkit_uri_scheme_request_finish (request, stream, length, content_type);
+
+ ret_val = TRUE;
+ out:
+ g_free (content_type);
+ g_free (content);
+ g_free (filename);
+
+ if (ret_val)
+ g_object_unref (request);
+
+ if (error)
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, ret_val);
+}
+
+static void
+web_view_file_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+ EWebView *web_view)
+{
+ GTask *task;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ task = g_task_new (
+ web_view, NULL,
+ (GAsyncReadyCallback) web_view_process_uri_scheme_finished_cb,
+ request);
+
+ g_task_set_task_data (task, g_object_ref (request), NULL);
+ g_task_run_in_thread (task, web_view_process_file_uri_scheme_request);
+
+ g_object_unref (task);
+}
+
+static void
+web_view_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+ EWebView *web_view)
+{
+}
+
+static void
+web_view_gtk_stock_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+ EWebView *web_view)
+{
+ SoupURI *uri;
+ GHashTable *query = NULL;
+ GtkStyleContext *context;
+ GtkWidgetPath *path;
+ GtkIconSet *icon_set;
+ gssize size = GTK_ICON_SIZE_BUTTON;
+ gchar *a_size;
+ gchar *buffer = NULL;
+ gchar *content_type = NULL;
+ gsize buff_len = 0;
+ GError *local_error = NULL;
+
+ uri = soup_uri_new (webkit_uri_scheme_request_get_uri (request));
+
+ if (uri && uri->query)
+ query = soup_form_decode (uri->query);
+
+ if (query) {
+ a_size = g_hash_table_lookup (query, "size");
+ if (a_size != NULL)
+ size = atoi (a_size);
+ g_hash_table_destroy (query);
+ }
+
+ /* Try style context first */
+ context = gtk_style_context_new ();
+ path = gtk_widget_path_new ();
+ gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
+ gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
+ gtk_style_context_set_path (context, path);
+ gtk_widget_path_free (path);
+
+ if (icon_set != NULL) {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gtk_icon_set_render_icon_pixbuf (
+ icon_set, context, size);
+ gdk_pixbuf_save_to_buffer (
+ pixbuf, &buffer, &buff_len,
+ "png", &local_error, NULL);
+ g_object_unref (pixbuf);
+ /* Fallback to icon theme */
+ } else {
+ GtkIconTheme *icon_theme;
+ GtkIconInfo *icon_info;
+ const gchar *filename;
+
+ icon_theme = gtk_icon_theme_get_default ();
+
+ icon_info = gtk_icon_theme_lookup_icon (
+ icon_theme, uri->host, size,
+ GTK_ICON_LOOKUP_USE_BUILTIN);
+
+ filename = gtk_icon_info_get_filename (icon_info);
+ if (filename != NULL) {
+ g_file_get_contents (
+ filename, &buffer, &buff_len, &local_error);
+ content_type =
+ g_content_type_guess (filename, NULL, 0, NULL);
+
+ } else {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gtk_icon_info_get_builtin_pixbuf (icon_info);
+ if (pixbuf != NULL) {
+ gdk_pixbuf_save_to_buffer (
+ pixbuf, &buffer, &buff_len,
+ "png", &local_error, NULL);
+ g_object_unref (pixbuf);
+ }
+ }
+
+ gtk_icon_info_free (icon_info);
+ }
+
+ /* Sanity check */
+ g_return_if_fail (
+ ((buffer != NULL) && (local_error == NULL)) ||
+ ((buffer == NULL) && (local_error != NULL)));
+
+ if (!content_type)
+ content_type = g_strdup ("image/png");
+
+ if (buffer != NULL) {
+ GInputStream *stream;
+
+ stream = g_memory_input_stream_new_from_data (
+ buffer, buff_len, (GDestroyNotify) g_free);
+
+ webkit_uri_scheme_request_finish (
+ request, stream, buff_len, content_type);
+
+ g_object_unref (stream);
+ }
+
+ g_object_unref (context);
+ g_free (content_type);
+}
+
+void
+e_web_view_register_uri_scheme (EWebView *web_view,
+ EURIScheme scheme,
+ gpointer user_callback,
+ gpointer user_data)
+{
+ WebKitWebContext *context;
+ gpointer callback = NULL;
+ const gchar *uri_scheme;
+
+ static GHashTable *hash_table = NULL;
+
+ if (!hash_table)
+ hash_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+
+ context = webkit_web_context_get_default ();
+
+ callback = user_callback;
+
+ switch (scheme) {
+ case CID_URI_SCHEME:
+ uri_scheme = "cid";
+ if (!callback)
+ callback = web_view_cid_uri_scheme_appeared_cb;
+ break;
+ case FILE_URI_SCHEME:
+ uri_scheme = "evo-file";
+ if (!callback)
+ callback = web_view_file_uri_scheme_appeared_cb;
+ break;
+ case MAIL_URI_SCHEME:
+ uri_scheme = "mail";
+ if (!callback)
+ callback = web_view_mail_uri_scheme_appeared_cb;
+ break;
+ case EVO_HTTP_URI_SCHEME:
+ uri_scheme = "evo-http";
+ if (!callback)
+ callback = web_view_http_uri_scheme_appeared_cb;
+ break;
+ case EVO_HTTPS_URI_SCHEME:
+ uri_scheme = "evo-https";
+ if (!callback)
+ callback = web_view_http_uri_scheme_appeared_cb;
+ break;
+ case GTK_STOCK_URI_SCHEME:
+ uri_scheme = "gtk-stock";
+ if (!callback)
+ callback = web_view_gtk_stock_uri_scheme_appeared_cb;
+ break;
+ default:
+ return;
+ }
+
+ if (g_hash_table_lookup (hash_table, uri_scheme))
+ return;
+
+ g_hash_table_insert (hash_table, (gpointer) uri_scheme, callback);
+
+ webkit_web_context_register_uri_scheme (
+ context,
+ uri_scheme,
+ (WebKitURISchemeRequestCallback) callback,
+ user_data ? user_data : web_view,
+ NULL);
+
+}
+
+static void
+web_view_update_fonts (EWebView *web_view)
+{
+ e_web_view_update_fonts (web_view);
+}
+
+void
+e_web_view_update_fonts (EWebView *web_view)
+{
+ EWebViewClass *class;
+ PangoFontDescription *ms = NULL, *vw = NULL;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ class = E_WEB_VIEW_GET_CLASS (web_view);
+ if (class->set_fonts != NULL)
+ class->set_fonts (web_view, &ms, &vw);
+
+ e_web_view_update_fonts_settings (
+ web_view->priv->font_settings,
+ web_view->priv->aliasing_settings,
+ ms, vw, GTK_WIDGET (web_view));
+
+ pango_font_description_free (ms);
+ pango_font_description_free (vw);
+}
+
+static void
e_web_view_init (EWebView *web_view)
{
GtkUIManager *ui_manager;
@@ -1612,52 +2090,47 @@ e_web_view_init (EWebView *web_view)
gulong handler_id;
GError *error = NULL;
- g_once (
- &disable_webkit_3rd_party_plugins_once,
- web_view_disable_webkit_3rd_party_plugins, NULL);
-
web_view->priv = E_WEB_VIEW_GET_PRIVATE (web_view);
web_view->priv->old_settings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) g_variant_unref);
/* XXX No WebKitWebView class method pointers to
* override so we have to use signal handlers. */
-
- g_signal_connect (
+#if 0
+ e_signal_connect (
web_view, "create-plugin-widget",
G_CALLBACK (web_view_create_plugin_widget_cb), NULL);
-
- g_signal_connect (
+#endif
+ e_signal_connect (
web_view, "context-menu",
G_CALLBACK (web_view_context_menu_cb), NULL);
- g_signal_connect (
- web_view, "hovering-over-link",
- G_CALLBACK (web_view_hovering_over_link_cb), NULL);
+ u_signal_connect (
+ web_view, "mouse-target-changed",
+ G_CALLBACK (web_view_mouse_target_changed_cb), NULL);
- g_signal_connect (
- web_view, "navigation-policy-decision-requested",
- G_CALLBACK (web_view_navigation_policy_decision_requested_cb),
+ e_signal_connect (
+ web_view, "decide-policy",
+ G_CALLBACK (web_view_decide_policy_cb),
NULL);
- g_signal_connect (
- web_view, "new-window-policy-decision-requested",
- G_CALLBACK (web_view_navigation_policy_decision_requested_cb),
- NULL);
+ e_signal_connect (
+ webkit_web_context_get_default (), "initialize-web-extensions",
+ G_CALLBACK (initialize_web_extensions_cb), NULL);
- g_signal_connect (
+ e_signal_connect (
+ web_view, "load-changed",
+ G_CALLBACK (web_view_load_changed_cb), NULL);
+
+ e_signal_connect (
web_view, "document-load-finished",
G_CALLBACK (style_updated_cb), NULL);
- e_signal_connect_notify (
- web_view, "notify::load-status",
- G_CALLBACK (web_view_load_status_changed_cb), NULL);
-
- g_signal_connect (
+ e_signal_connect (
web_view, "style-updated",
G_CALLBACK (style_updated_cb), NULL);
- g_signal_connect (
+ e_signal_connect (
web_view, "state-flags-changed",
G_CALLBACK (style_updated_cb), NULL);
@@ -1668,10 +2141,10 @@ e_web_view_init (EWebView *web_view)
ui_manager, "connect-proxy",
G_CALLBACK (web_view_connect_proxy_cb), web_view);
- web_view_init_web_settings (WEBKIT_WEB_VIEW (web_view));
+ web_view_watch_web_extension (web_view);
- e_web_view_install_request_handler (web_view, E_TYPE_FILE_REQUEST);
- e_web_view_install_request_handler (web_view, E_TYPE_STOCK_REQUEST);
+ e_web_view_register_uri_scheme (web_view, FILE_URI_SCHEME, NULL, NULL);
+ e_web_view_register_uri_scheme (web_view, GTK_STOCK_URI_SCHEME, NULL, NULL);
settings = e_util_ref_settings ("org.gnome.desktop.interface");
web_view->priv->font_settings = g_object_ref (settings);
@@ -1700,8 +2173,6 @@ e_web_view_init (EWebView *web_view)
g_settings_schema_unref (settings_schema);
}
- e_web_view_update_fonts (web_view);
-
action_group = gtk_action_group_new ("uri");
gtk_action_group_set_translation_domain (action_group, domain);
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
@@ -1808,14 +2279,14 @@ e_web_view_init (EWebView *web_view)
id = "org.gnome.evolution.webview";
e_plugin_ui_register_manager (ui_manager, id, web_view);
e_plugin_ui_enable_manager (ui_manager, id);
-
- e_web_view_clear (E_WEB_VIEW (web_view));
}
GtkWidget *
e_web_view_new (void)
{
- return g_object_new (E_TYPE_WEB_VIEW, NULL);
+ return g_object_new (
+ E_TYPE_WEB_VIEW,
+ NULL);
}
void
@@ -1823,7 +2294,7 @@ e_web_view_clear (EWebView *web_view)
{
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- webkit_web_view_load_html_string (
+ webkit_web_view_load_html (
WEBKIT_WEB_VIEW (web_view),
"<html>"
"<head></head>"
@@ -1940,19 +2411,100 @@ e_web_view_reload (EWebView *web_view)
webkit_web_view_reload (WEBKIT_WEB_VIEW (web_view));
}
-gchar *
-e_web_view_get_html (EWebView *web_view)
+static void
+get_document_content_html_cb (GDBusProxy *web_extension,
+ GAsyncResult *result,
+ GTask *task)
{
- WebKitDOMDocument *document;
- WebKitDOMElement *element;
+ GVariant *result_variant;
+ const gchar *html_content;
+ result_variant = g_dbus_proxy_call_finish (web_extension, result, NULL);
+ if (result_variant) {
+ html_content = g_variant_get_string (result_variant, NULL);
+ g_variant_unref (result_variant);
+ }
+
+ g_task_return_pointer (task, g_strdup (html_content), g_free);
+ g_object_unref (task);
+}
+
+void
+e_web_view_get_content_html (EWebView *web_view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GDBusProxy *web_extension;
+ GTask *task;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ task = g_task_new (web_view, cancellable, callback, user_data);
+
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (web_extension) {
+ g_dbus_proxy_call (
+ web_extension,
+ "GetDocumentContentHtml",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (web_view))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ (GAsyncReadyCallback) get_document_content_html_cb,
+ g_object_ref (task));
+ } else
+ g_task_return_pointer (task, NULL, NULL);
+}
+
+const gchar *
+e_web_view_get_content_html_finish (EWebView *web_view,
+ GAsyncResult *result,
+ GError **error)
+{
g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, web_view), FALSE);
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (web_view));
- element = webkit_dom_document_get_document_element (document);
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+const gchar *
+e_web_view_get_content_html_sync (EWebView *web_view,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GDBusProxy *web_extension;
+
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (web_extension) {
+ GVariant *result;
+ const gchar *html_content = NULL;
+
+ result = g_dbus_proxy_call_sync (
+ web_extension,
+ "GetDocumentContentHTML",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (web_view))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ error);
+
+ if (result) {
+ html_content = g_variant_get_string (result, NULL);
+ g_variant_unref (result);
+ return html_content;
+ }
+ }
- return webkit_dom_html_element_get_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (element));
+ return NULL;
}
gboolean
@@ -1982,8 +2534,10 @@ e_web_view_get_copy_target_list (EWebView *web_view)
{
g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
- return webkit_web_view_get_copy_target_list (
- WEBKIT_WEB_VIEW (web_view));
+ return NULL;
+ /* FIXME XXX WK2 */
+// return webkit_web_view_get_copy_target_list (
+// WEBKIT_WEB_VIEW (web_view));
}
gboolean
@@ -2035,7 +2589,9 @@ e_web_view_get_editable (EWebView *web_view)
{
g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
- return webkit_web_view_get_editable (WEBKIT_WEB_VIEW (web_view));
+ /* FIXME XXX WK2 */
+// return webkit_web_view_get_editable (WEBKIT_WEB_VIEW (web_view));
+ return TRUE;
}
void
@@ -2044,6 +2600,7 @@ e_web_view_set_editable (EWebView *web_view,
{
g_return_if_fail (E_IS_WEB_VIEW (web_view));
+ /* FIXME XXX WK2 */
webkit_web_view_set_editable (WEBKIT_WEB_VIEW (web_view), editable);
}
@@ -2128,8 +2685,10 @@ e_web_view_get_paste_target_list (EWebView *web_view)
{
g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+ /* FIXME XXX WK2
return webkit_web_view_get_paste_target_list (
- WEBKIT_WEB_VIEW (web_view));
+ WEBKIT_WEB_VIEW (web_view)); */
+ return NULL;
}
GtkAction *
@@ -2203,11 +2762,11 @@ e_web_view_add_highlight (EWebView *web_view,
&web_view->priv->highlights,
g_strdup (highlight));
- webkit_web_view_mark_text_matches (
- WEBKIT_WEB_VIEW (web_view), highlight, FALSE, 0);
-
- webkit_web_view_set_highlight_text_matches (
- WEBKIT_WEB_VIEW (web_view), TRUE);
+ webkit_find_controller_search (
+ web_view->priv->find_controller,
+ highlight,
+ WEBKIT_FIND_OPTIONS_NONE,
+ G_MAXUINT);
}
void
@@ -2215,7 +2774,10 @@ e_web_view_clear_highlights (EWebView *web_view)
{
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+ if (!web_view->priv->find_controller)
+ web_view_set_find_controller (web_view);
+
+ webkit_find_controller_search_finish (web_view->priv->find_controller);
while (!g_queue_is_empty (&web_view->priv->highlights))
g_free (g_queue_pop_head (&web_view->priv->highlights));
@@ -2262,7 +2824,8 @@ e_web_view_copy_clipboard (EWebView *web_view)
{
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- webkit_web_view_copy_clipboard (WEBKIT_WEB_VIEW (web_view));
+ webkit_web_view_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view), WEBKIT_EDITING_COMMAND_COPY);
}
void
@@ -2270,7 +2833,8 @@ e_web_view_cut_clipboard (EWebView *web_view)
{
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- webkit_web_view_cut_clipboard (WEBKIT_WEB_VIEW (web_view));
+ webkit_web_view_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view), WEBKIT_EDITING_COMMAND_CUT);
}
gboolean
@@ -2278,7 +2842,9 @@ e_web_view_is_selection_active (EWebView *web_view)
{
g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
- return webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view));
+ /* FIXME XXX WK2
+ return webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view));*/
+ return FALSE;
}
void
@@ -2286,17 +2852,18 @@ e_web_view_paste_clipboard (EWebView *web_view)
{
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- webkit_web_view_paste_clipboard (WEBKIT_WEB_VIEW (web_view));
+ webkit_web_view_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view), WEBKIT_EDITING_COMMAND_PASTE);
}
gboolean
e_web_view_scroll_forward (EWebView *web_view)
{
g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
-
+/* FIXME XXX WK2
webkit_web_view_move_cursor (
WEBKIT_WEB_VIEW (web_view), GTK_MOVEMENT_PAGES, 1);
-
+*/
return TRUE; /* XXX This means nothing. */
}
@@ -2304,10 +2871,10 @@ gboolean
e_web_view_scroll_backward (EWebView *web_view)
{
g_return_val_if_fail (E_IS_WEB_VIEW (web_view), FALSE);
-
+/* FIXME XXX WK2
webkit_web_view_move_cursor (
WEBKIT_WEB_VIEW (web_view), GTK_MOVEMENT_PAGES, -1);
-
+*/
return TRUE; /* XXX This means nothing. */
}
@@ -2316,7 +2883,8 @@ e_web_view_select_all (EWebView *web_view)
{
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- webkit_web_view_select_all (WEBKIT_WEB_VIEW (web_view));
+ webkit_web_view_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view), WEBKIT_EDITING_COMMAND_SELECT_ALL);
}
void
@@ -2340,19 +2908,31 @@ e_web_view_zoom_100 (EWebView *web_view)
void
e_web_view_zoom_in (EWebView *web_view)
{
+ gdouble zoom_level;
+
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- if (webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (web_view)) < 4.9999)
- webkit_web_view_zoom_in (WEBKIT_WEB_VIEW (web_view));
+ /* There is no webkit_web_view_zoom_in function in WK2, so emulate it */
+ zoom_level = webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (web_view));
+ /* zoom-step in WK1 was 0.1 */
+ zoom_level += 0.1;
+ if (zoom_level < 4.9999) {
+ webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (web_view), zoom_level);
}
void
e_web_view_zoom_out (EWebView *web_view)
{
+ gdouble zoom_level;
+
g_return_if_fail (E_IS_WEB_VIEW (web_view));
- if (webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (web_view)) > 0.1999)
- webkit_web_view_zoom_out (WEBKIT_WEB_VIEW (web_view));
+ /* There is no webkit_web_view_zoom_out function in WK2, so emulate it */
+ zoom_level = webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (web_view));
+ /* zoom-step in WK1 was 0.1 */
+ zoom_level -= 0.1;
+ if (zoom_level > 0.1999)
+ webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (web_view), zoom_level);
}
GtkUIManager *
@@ -2476,6 +3056,102 @@ element_is_in_pre_tag (WebKitDOMNode *node)
return FALSE;
}
+static void
+get_selection_content_html_cb (GDBusProxy *web_extension,
+ GAsyncResult *result,
+ GTask *task)
+{
+ GVariant *result_variant;
+ const gchar *html_content;
+
+ result_variant = g_dbus_proxy_call_finish (web_extension, result, NULL);
+ if (result_variant) {
+ html_content = g_variant_get_string (result_variant, NULL);
+ g_variant_unref (result_variant);
+ }
+
+ g_task_return_pointer (task, g_strdup (html_content), g_free);
+ g_object_unref (task);
+}
+
+void
+e_web_view_get_selection_content_html (EWebView *web_view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GDBusProxy *web_extension;
+ GTask *task;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ task = g_task_new (web_view, cancellable, callback, user_data);
+
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (web_extension) {
+ g_dbus_proxy_call (
+ web_extension,
+ "GetSelectionContentHTML",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (web_view))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ (GAsyncReadyCallback) get_selection_content_html_cb,
+ g_object_ref (task));
+ } else
+ g_task_return_pointer (task, NULL, NULL);
+}
+
+const gchar *
+e_web_view_get_selection_content_html_finish (EWebView *web_view,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, web_view), FALSE);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+const gchar *
+e_web_view_get_selection_content_html_sync (EWebView *web_view,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GDBusProxy *web_extension;
+
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (web_extension) {
+ GVariant *result;
+ const gchar *html_content = NULL;
+
+ result = g_dbus_proxy_call_sync (
+ web_extension,
+ "GetSelectionContentHtml",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (web_view))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ error);
+
+ if (result) {
+ html_content = g_variant_get_string (result, NULL);
+ g_variant_unref (result);
+ return html_content;
+ }
+ }
+
+ return NULL;
+}
+
static gchar *
web_view_get_frame_selection_html (WebKitDOMElement *iframe)
{
@@ -2574,61 +3250,98 @@ e_web_view_get_selection_html (EWebView *web_view)
return NULL;
}
+static gdouble
+get_screen_dpi (GdkScreen *screen)
+{
+ gdouble dpi;
+ gdouble dp, di;
+
+ dpi = gdk_screen_get_resolution (screen);
+ if (dpi != -1)
+ return dpi;
+
+ dp = hypot (gdk_screen_get_width (screen), gdk_screen_get_height (screen));
+ di = hypot (gdk_screen_get_width_mm (screen), gdk_screen_get_height_mm (screen)) / 25.4;
+
+ return dp / di;
+}
+
+static guint
+normalize_font_size (GtkWidget *widget,
+ gdouble font_size)
+{
+ /* WebKit2 uses font sizes in pixels. */
+ GdkScreen *screen;
+ gdouble dpi;
+
+ if (widget) {
+ screen = gtk_widget_has_screen (widget) ?
+ gtk_widget_get_screen (widget) : gdk_screen_get_default ();
+ } else {
+ screen = gdk_screen_get_default ();
+ }
+
+ dpi = screen ? get_screen_dpi (screen) : 96;
+
+ return font_size / 72.0 * dpi;
+}
+
void
-e_web_view_update_fonts (EWebView *web_view)
+e_web_view_update_fonts_settings (GSettings *font_settings,
+ GSettings *aliasing_settings,
+ PangoFontDescription *ms_font,
+ PangoFontDescription *vw_font,
+ GtkWidget *view_widget)
{
- EWebViewClass *class;
- GString *stylesheet;
- gchar *base64;
+ gboolean clean_ms = FALSE, clean_vw = FALSE;
gchar *aa = NULL;
- WebKitWebSettings *settings;
- PangoFontDescription *min_size, *ms, *vw;
const gchar *styles[] = { "normal", "oblique", "italic" };
const gchar *smoothing = NULL;
- GtkStyleContext *context;
GdkColor *link = NULL;
GdkColor *visited = NULL;
+ GString *stylesheet;
+ GtkStyleContext *context;
+ PangoFontDescription *min_size, *ms, *vw;
+ WebKitSettings *wk_settings;
+ WebKitUserContentManager *manager;
+ WebKitUserStyleSheet *style_sheet;
- g_return_if_fail (E_IS_WEB_VIEW (web_view));
-
- ms = NULL;
- vw = NULL;
-
- class = E_WEB_VIEW_GET_CLASS (web_view);
- if (class->set_fonts != NULL)
- class->set_fonts (web_view, &ms, &vw);
-
- if (ms == NULL) {
+ if (!ms_font) {
gchar *font;
font = g_settings_get_string (
- web_view->priv->font_settings,
+ font_settings,
"monospace-font-name");
ms = pango_font_description_from_string (
(font != NULL) ? font : "monospace 10");
+ clean_ms = TRUE;
+
g_free (font);
- }
+ } else
+ ms = ms_font;
- if (vw == NULL) {
+ if (!vw_font) {
gchar *font;
font = g_settings_get_string (
- web_view->priv->font_settings,
+ font_settings,
"font-name");
vw = pango_font_description_from_string (
(font != NULL) ? font : "serif 10");
+ clean_vw = TRUE;
+
g_free (font);
- }
+ } else
+ vw = vw_font;
- if (pango_font_description_get_size (ms) < pango_font_description_get_size (vw)) {
+ if (pango_font_description_get_size (ms) < pango_font_description_get_size (vw))
min_size = ms;
- } else {
+ else
min_size = vw;
- }
stylesheet = g_string_new ("");
g_string_append_printf (
@@ -2643,9 +3356,9 @@ e_web_view_update_fonts (EWebView *web_view)
pango_font_description_get_weight (vw),
styles[pango_font_description_get_style (vw)]);
- if (web_view->priv->aliasing_settings != NULL)
+ if (aliasing_settings != NULL)
aa = g_settings_get_string (
- web_view->priv->aliasing_settings, "antialiasing");
+ aliasing_settings, "antialiasing");
if (g_strcmp0 (aa, "none") == 0)
smoothing = "none";
@@ -2671,73 +3384,165 @@ e_web_view_update_fonts (EWebView *web_view)
" font-size: %dpt;\n"
" font-weight: %d;\n"
" font-style: %s;\n"
- "}",
+ "} \n",
pango_font_description_get_family (ms),
pango_font_description_get_size (ms) / PANGO_SCALE,
pango_font_description_get_weight (ms),
styles[pango_font_description_get_style (ms)]);
- context = gtk_widget_get_style_context (GTK_WIDGET (web_view));
- gtk_style_context_get_style (
- context,
- "link-color", &link,
- "visited-link-color", &visited,
- NULL);
+ if (view_widget) {
+ context = gtk_widget_get_style_context (view_widget);
+ gtk_style_context_get_style (
+ context,
+ "link-color", &link,
+ "visited-link-color", &visited,
+ NULL);
- if (link == NULL) {
- link = g_slice_new0 (GdkColor);
- link->blue = G_MAXINT16;
- }
+ if (link == NULL) {
+ link = g_slice_new0 (GdkColor);
+ link->blue = G_MAXINT16;
+ }
- if (visited == NULL) {
- visited = g_slice_new0 (GdkColor);
- visited->red = G_MAXINT16;
- }
+ if (visited == NULL) {
+ visited = g_slice_new0 (GdkColor);
+ visited->red = G_MAXINT16;
+ }
- g_string_append_printf (
- stylesheet,
- "a {\n"
- " color: #%06x;\n"
- "}\n"
- "a:visited {\n"
- " color: #%06x;\n"
- "}\n",
- e_color_to_value (link),
- e_color_to_value (visited));
-
- gdk_color_free (link);
- gdk_color_free (visited);
-
- base64 = g_base64_encode ((guchar *) stylesheet->str, stylesheet->len);
- g_string_free (stylesheet, TRUE);
+ g_string_append_printf (
+ stylesheet,
+ "a {\n"
+ " color: #%06x;\n"
+ "}\n"
+ "a:visited {\n"
+ " color: #%06x;\n"
+ "}\n",
+ e_color_to_value (link),
+ e_color_to_value (visited));
+
+ gdk_color_free (link);
+ gdk_color_free (visited);
+ }
- stylesheet = g_string_new ("data:text/css;charset=utf-8;base64,");
- g_string_append (stylesheet, base64);
- g_free (base64);
+ wk_settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (view_widget));
- settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view));
g_object_set (
- G_OBJECT (settings),
+ wk_settings,
"default-font-size",
- pango_font_description_get_size (vw) / PANGO_SCALE,
+ normalize_font_size (
+ view_widget, pango_font_description_get_size (vw) / PANGO_SCALE),
"default-font-family",
pango_font_description_get_family (vw),
"monospace-font-family",
pango_font_description_get_family (ms),
"default-monospace-font-size",
- pango_font_description_get_size (ms) / PANGO_SCALE,
+ normalize_font_size (
+ view_widget, pango_font_description_get_size (ms) / PANGO_SCALE),
"minimum-font-size",
- pango_font_description_get_size (min_size) / PANGO_SCALE,
- "user-stylesheet-uri",
+ normalize_font_size (
+ view_widget, pango_font_description_get_size (min_size) / PANGO_SCALE),
+ NULL);
+
+ manager = webkit_web_view_get_user_content_manager (WEBKIT_WEB_VIEW (view_widget));
+ webkit_user_content_manager_remove_all_style_sheets (manager);
+
+ webkit_user_style_sheet_new (
stylesheet->str,
+ WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES,
+ WEBKIT_USER_STYLE_LEVEL_USER,
+ NULL,
NULL);
+ webkit_user_content_manager_add_style_sheet (manager, style_sheet);
+
+ webkit_user_style_sheet_unref (style_sheet);
+
g_string_free (stylesheet, TRUE);
+ if (clean_ms)
+ pango_font_description_free (ms);
+ if (clean_vw)
+ pango_font_description_free (vw);
+}
+
+WebKitSettings *
+e_web_view_get_default_webkit_settings (void)
+{
+ return webkit_settings_new_with_settings (
+ "auto-load-images", TRUE,
+ "default-charset", "utf-8",
+ "enable-html5-database", FALSE,
+ "enable-html5-local-storage", FALSE,
+ "enable-java", FALSE,
+ "enable-javascript", FALSE,
+ "enable-offline-web-application-cache", FALSE,
+ "enable-page-cache", FALSE,
+ "enable-plugins", FALSE,
+ "enable-private-browsing", TRUE,
+ "enable-smooth-scrolling", TRUE,
+ "media-playback-allows-inline", FALSE,
+ NULL);
+}
+
+static void
+initialize_web_extensions_cb (WebKitWebContext *web_context,
+ gpointer user_data)
+{
+ /* Set the web extensions dir before the process is launched */
+ webkit_web_context_set_web_extensions_directory (
+ web_context, EVOLUTION_WEB_EXTENSIONS_DIR);
+
+ webkit_web_context_set_cache_model (
+ web_context, WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
+}
+
+void
+e_web_view_update_fonts (EWebView *web_view)
+{
+ EWebViewClass *class;
+ PangoFontDescription *ms = NULL, *vw = NULL;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ class = E_WEB_VIEW_GET_CLASS (web_view);
+ if (class->set_fonts != NULL)
+ class->set_fonts (web_view, &ms, &vw);
+
+ e_web_view_update_fonts_settings (
+ web_view->priv->font_settings,
+ web_view->priv->aliasing_settings,
+ ms, vw, GTK_WIDGET (web_view));
+
pango_font_description_free (ms);
pango_font_description_free (vw);
}
+WebKitWebViewGroup *
+e_web_view_get_web_view_group (void)
+{
+ static WebKitWebViewGroup *web_view_group = NULL;
+
+ if (!web_view_group) {
+ web_view_group = webkit_web_view_group_new ("Evolution WebView Group");
+ web_view_initialize_group (web_view_group);
+ }
+
+ return web_view_group;
+}
+
+void
+e_web_view_initialize_webkit (void)
+{
+ WebKitWebContext *web_context;
+
+ web_context = webkit_web_context_get_default ();
+
+ /* Set the web extensions dir before the process is launched */
+ webkit_web_context_set_web_extensions_directory (
+ web_context, EVOLUTION_WEB_EXTENSIONS_DIR);
+
+ webkit_web_context_set_cache_model (web_context, WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
+}
+
/* Helper for e_web_view_cursor_image_copy() */
static void
web_view_cursor_image_copy_pixbuf_cb (GObject *source_object,
@@ -3149,7 +3954,8 @@ e_web_view_request (EWebView *web_view,
g_return_if_fail (E_IS_WEB_VIEW (web_view));
g_return_if_fail (uri != NULL);
- session = webkit_get_default_session ();
+// session = webkit_get_default_session ();
+ session = NULL;
async_context = g_slice_new0 (AsyncContext);
@@ -3223,154 +4029,51 @@ e_web_view_request_finish (EWebView *web_view,
return g_object_ref (async_context->input_stream);
}
-
+/*
void
e_web_view_install_request_handler (EWebView *web_view,
GType handler_type)
{
SoupSession *session;
- session = webkit_get_default_session ();
+// session = webkit_get_default_session ();
+ session = NULL;
soup_session_add_feature_by_type (session, handler_type);
}
-
+*/
+/**
+ * e_web_view_create_and_add_css_style_sheet:
+ * @web_view: an #EWebView
+ * @style_sheet_id: CSS style sheet's id
+ *
+ * Creates new CSS style sheet with given @style_sheel_id and inserts
+ * it into given @web_view document.
+ **/
void
-e_web_view_create_and_add_css_style_sheet (WebKitDOMDocument *document,
+e_web_view_create_and_add_css_style_sheet (EWebView *web_view,
const gchar *style_sheet_id)
{
- WebKitDOMElement *style_element;
-
- style_element = webkit_dom_document_get_element_by_id (document, style_sheet_id);
-
- if (!style_element) {
- /* Create new <style> element */
- style_element = webkit_dom_document_create_element (document, "style", NULL);
- webkit_dom_element_set_id (
- WEBKIT_DOM_ELEMENT (style_element),
- style_sheet_id);
- webkit_dom_html_style_element_set_media (
- WEBKIT_DOM_HTML_STYLE_ELEMENT (style_element),
- "screen");
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (style_element),
- /* WebKit hack - we have to insert empty TextNode into style element */
- WEBKIT_DOM_NODE (webkit_dom_document_create_text_node (document, "")),
- NULL);
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (webkit_dom_document_get_head (document)),
- WEBKIT_DOM_NODE (style_element),
- NULL);
- }
-}
-
-static void
-add_css_rule_into_style_sheet (WebKitDOMDocument *document,
- const gchar *style_sheet_id,
- const gchar *selector,
- const gchar *style)
-{
- WebKitDOMElement *style_element;
- WebKitDOMStyleSheet *sheet;
- WebKitDOMCSSRuleList *rules_list;
- gint length, ii;
-
- style_element = webkit_dom_document_get_element_by_id (document, style_sheet_id);
-
- if (!style_element) {
- e_web_view_create_and_add_css_style_sheet (document, style_sheet_id);
- style_element = webkit_dom_document_get_element_by_id (document, style_sheet_id);
- }
-
- /* Get sheet that is associated with style element */
- sheet = webkit_dom_html_style_element_get_sheet (WEBKIT_DOM_HTML_STYLE_ELEMENT (style_element));
-
- rules_list = webkit_dom_css_style_sheet_get_css_rules (WEBKIT_DOM_CSS_STYLE_SHEET (sheet));
- length = webkit_dom_css_rule_list_get_length (rules_list);
-
- /* Check if rule exists */
- for (ii = 0; ii < length; ii++) {
- WebKitDOMCSSRule *rule;
- gchar *rule_text;
- gchar *rule_selector, *selector_end;
-
- rule = webkit_dom_css_rule_list_item (rules_list, ii);
-
- if (!WEBKIT_DOM_IS_CSS_RULE (rule))
- continue;
-
- rule_text = webkit_dom_css_rule_get_css_text (rule);
-
- /* Find the start of the style => end of the selector */
- selector_end = g_strstr_len (rule_text, -1, " {");
- if (!selector_end) {
- g_free (rule_text);
- continue;
- }
-
- rule_selector =
- g_utf8_substring (
- rule_text,
- 0,
- g_utf8_pointer_to_offset (rule_text, selector_end));
-
- if (g_strcmp0 (rule_selector, selector) == 0) {
- /* If exists remove it */
- webkit_dom_css_style_sheet_remove_rule (
- WEBKIT_DOM_CSS_STYLE_SHEET (sheet),
- ii, NULL);
- }
-
- g_free (rule_selector);
- g_free (rule_text);
- }
-
- /* Insert the rule at the end, so it will override previously inserted */
- webkit_dom_css_style_sheet_add_rule (
- WEBKIT_DOM_CSS_STYLE_SHEET (sheet),
- selector,
- style,
- webkit_dom_css_rule_list_get_length (
- webkit_dom_css_style_sheet_get_css_rules (
- WEBKIT_DOM_CSS_STYLE_SHEET (sheet))), /* Index */
- NULL);
-}
-
-static void
-add_css_rule_into_style_sheet_recursive (WebKitDOMDocument *document,
- const gchar *style_sheet_id,
- const gchar *selector,
- const gchar *style)
-{
- WebKitDOMNodeList *frames;
- gint ii, length;
-
- /* Add rule to document */
- add_css_rule_into_style_sheet (
- document,
- style_sheet_id,
- selector,
- style);
-
- frames = webkit_dom_document_query_selector_all (document, "iframe", NULL);
- length = webkit_dom_node_list_get_length (frames);
+ GDBusProxy *web_extension;
- /* Add rules to every sub document */
- for (ii = 0; ii < length; ii++) {
- WebKitDOMDocument *iframe_document;
- WebKitDOMNode *node;
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+ g_return_if_fail (style_sheet_id && *style_sheet_id);
- node = webkit_dom_node_list_item (frames, ii);
- iframe_document = webkit_dom_html_iframe_element_get_content_document (
- WEBKIT_DOM_HTML_IFRAME_ELEMENT (node));
-
- add_css_rule_into_style_sheet_recursive (
- iframe_document,
- style_sheet_id,
- selector,
- style);
- }
- g_object_unref (frames);
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (web_extension) {
+ g_dbus_proxy_call (
+ web_extension,
+ "CreateAndAddCSSStyleSheet",
+ g_variant_new (
+ "(ts)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (web_view)),
+ style_sheet_id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+ }
}
/**
@@ -3387,21 +4090,36 @@ add_css_rule_into_style_sheet_recursive (WebKitDOMDocument *document,
* into DOM documents inside iframe elements.
**/
void
-e_web_view_add_css_rule_into_style_sheet (EWebView *view,
+e_web_view_add_css_rule_into_style_sheet (EWebView *web_view,
const gchar *style_sheet_id,
const gchar *selector,
const gchar *style)
{
- g_return_if_fail (E_IS_WEB_VIEW (view));
+ GDBusProxy *web_extension;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
g_return_if_fail (style_sheet_id && *style_sheet_id);
g_return_if_fail (selector && *selector);
g_return_if_fail (style && *style);
- add_css_rule_into_style_sheet_recursive (
- webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)),
- style_sheet_id,
- selector,
- style);
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (web_extension) {
+ g_dbus_proxy_call (
+ web_extension,
+ "AddCSSRuleIntoStyleSheet",
+ g_variant_new (
+ "(tsss)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (web_view)),
+ style_sheet_id,
+ selector,
+ style),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+ }
}
gboolean
diff --git a/e-util/e-web-view.h b/e-util/e-web-view.h
index 1836f70..a1ddde6 100644
--- a/e-util/e-web-view.h
+++ b/e-util/e-web-view.h
@@ -28,7 +28,7 @@
#ifndef E_WEB_VIEW_H
#define E_WEB_VIEW_H
-#include <webkit/webkit.h>
+#include <webkit2/webkit2.h>
#include <e-util/e-activity.h>
/* Standard GObject macros */
@@ -56,6 +56,15 @@ typedef struct _EWebView EWebView;
typedef struct _EWebViewClass EWebViewClass;
typedef struct _EWebViewPrivate EWebViewPrivate;
+typedef enum {
+ CID_URI_SCHEME,
+ FILE_URI_SCHEME,
+ MAIL_URI_SCHEME,
+ EVO_HTTP_URI_SCHEME,
+ EVO_HTTPS_URI_SCHEME,
+ GTK_STOCK_URI_SCHEME
+} EURIScheme;
+
struct _EWebView {
WebKitWebView parent;
EWebViewPrivate *priv;
@@ -101,6 +110,15 @@ struct _EWebViewClass {
GType e_web_view_get_type (void) G_GNUC_CONST;
GtkWidget * e_web_view_new (void);
+WebKitSettings *
+ e_web_view_get_default_webkit_settings
+ (void);
+void e_web_view_update_fonts_settings
+ (GSettings *font_settings,
+ GSettings *aliasing_settings,
+ PangoFontDescription *ms_font,
+ PangoFontDescription *vw_font,
+ GtkWidget *view_widget);
void e_web_view_clear (EWebView *web_view);
void e_web_view_load_string (EWebView *web_view,
const gchar *string);
@@ -111,7 +129,20 @@ gchar * e_web_view_redirect_uri (EWebView *web_view,
gchar * e_web_view_suggest_filename (EWebView *web_view,
const gchar *uri);
void e_web_view_reload (EWebView *web_view);
-gchar * e_web_view_get_html (EWebView *web_view);
+void e_web_view_get_content_html (EWebView *web_view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+const gchar * e_web_view_get_content_html_finish
+ (EWebView *web_view,
+ GAsyncResult *result,
+ GError **error);
+const gchar * e_web_view_get_content_html_sync
+ (EWebView *web_view,
+ GCancellable *cancellable,
+ GError **error);
+GDBusProxy * e_web_view_get_web_extension_proxy
+ (EWebView *web_view);
gboolean e_web_view_get_caret_mode (EWebView *web_view);
void e_web_view_set_caret_mode (EWebView *web_view,
gboolean caret_mode);
@@ -180,7 +211,19 @@ void e_web_view_status_message (EWebView *web_view,
const gchar *status_message);
void e_web_view_stop_loading (EWebView *web_view);
void e_web_view_update_actions (EWebView *web_view);
-gchar * e_web_view_get_selection_html (EWebView *web_view);
+void e_web_view_get_selection_content_html
+ (EWebView *web_view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+const gchar * e_web_view_get_selection_content_html_finish
+ (EWebView *web_view,
+ GAsyncResult *result,
+ GError **error);
+const gchar * e_web_view_get_selection_content_html_sync
+ (EWebView *web_view,
+ GCancellable *cancellable,
+ GError **error);
void e_web_view_update_fonts (EWebView *web_view);
void e_web_view_cursor_image_copy (EWebView *web_view);
void e_web_view_cursor_image_save (EWebView *web_view);
@@ -192,6 +235,10 @@ void e_web_view_request (EWebView *web_view,
GInputStream * e_web_view_request_finish (EWebView *web_view,
GAsyncResult *result,
GError **error);
+void e_web_view_register_uri_scheme (EWebView *web_view,
+ EURIScheme scheme,
+ gpointer user_callback,
+ gpointer user_data);
void e_web_view_install_request_handler
(EWebView *web_view,
GType handler_type);
diff --git a/em-format/Makefile.am b/em-format/Makefile.am
index 7827d79..70ae62d 100644
--- a/em-format/Makefile.am
+++ b/em-format/Makefile.am
@@ -30,6 +30,7 @@ evolution_mail_formatter_include_HEADERS = \
e-mail-formatter-quote.h \
e-mail-formatter-utils.h \
e-mail-inline-filter.h \
+ e-mail-meta-remove-filter.h \
e-mail-parser-extension.h \
e-mail-parser.h \
e-mail-part.h \
@@ -89,6 +90,7 @@ libevolution_mail_formatter_la_SOURCES = \
e-mail-formatter-quote-text-enriched.c \
e-mail-formatter-quote-text-html.c \
e-mail-formatter-quote-text-plain.c \
+ e-mail-meta-remove-filter.c \
e-mail-parser-extension.c \
e-mail-parser.c \
e-mail-parser-application-mbox.c \
diff --git a/em-format/e-mail-formatter-headers.c b/em-format/e-mail-formatter-headers.c
index a16571d..12445f6 100644
--- a/em-format/e-mail-formatter-headers.c
+++ b/em-format/e-mail-formatter-headers.c
@@ -519,7 +519,7 @@ emfe_headers_format (EMailFormatterExtension *extension,
g_string_append_printf (
buffer,
"%s id=\"%s\"><table class=\"-e-mail-formatter-header-color\" border=\"0\" width=\"100%%\" "
- "style=\"direction: %s\">"
+ "style=\"direction: %s; border-spacing: 0px\">"
"<tr>",
(context->mode != E_MAIL_FORMATTER_MODE_PRINTING) ?
"<div class=\"headers -e-mail-formatter-body-color\"" :
@@ -530,7 +530,7 @@ emfe_headers_format (EMailFormatterExtension *extension,
if (is_collapsable)
g_string_append_printf (
buffer,
- "<td valign=\"top\" width=\"16\">"
+ "<td valign=\"top\" width=\"16\" style=\"padding-left: 0px\">"
"<img src=\"evo-file://%s/%s\" class=\"navigable\" "
" id=\"__evo-collapse-headers-img\" />"
"</td>",
diff --git a/em-format/e-mail-formatter.c b/em-format/e-mail-formatter.c
index 2e44fe7..54c0777 100644
--- a/em-format/e-mail-formatter.c
+++ b/em-format/e-mail-formatter.c
@@ -28,6 +28,7 @@
#include "e-mail-formatter-extension.h"
#include "e-mail-formatter-utils.h"
#include "e-mail-part.h"
+#include "e-mail-meta-remove-filter.h"
#define d(x)
@@ -1047,6 +1048,8 @@ e_mail_formatter_format_text (EMailFormatter *formatter,
CamelMimeFilter *filter;
const gchar *charset = NULL;
CamelMimeFilter *windows = NULL;
+ /* FIXME XXX WK2 */
+ CamelMimeFilter *meta_remove = NULL;
CamelMimePart *mime_part;
CamelContentType *mime_type;
diff --git a/em-format/e-mail-meta-remove-filter.c b/em-format/e-mail-meta-remove-filter.c
new file mode 100644
index 0000000..2d0f467
--- /dev/null
+++ b/em-format/e-mail-meta-remove-filter.c
@@ -0,0 +1,267 @@
+/*
+ * e-mail-meta-remove-filter.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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "e-mail-meta-remove-filter.h"
+
+G_DEFINE_TYPE (EMailMetaRemoveFilter, e_mail_meta_remove_filter, CAMEL_TYPE_MIME_FILTER)
+
+static void
+remove_meta_tag (CamelMimeFilter *filter,
+ const gchar *in,
+ gsize len,
+ gsize prespace,
+ gchar **out,
+ gsize *outlen)
+{
+ EMailMetaRemoveFilter *meta_remove = (EMailMetaRemoveFilter *) filter;
+ register const gchar *inptr = in;
+ const gchar *inend = in + len;
+ const gchar *start = NULL;
+ const gchar *end_of_prev_meta = NULL;
+ gboolean in_meta = meta_remove->in_meta;
+ gboolean previously_in_meta = meta_remove->in_meta;
+ gboolean charset_meta = FALSE;
+ gboolean backup = FALSE;
+ GString *new_out = NULL;
+ gsize offset = 0;
+
+ new_out = g_string_new ("");
+
+ if (meta_remove->after_head)
+ goto copy_input;
+
+ while (inptr < inend) {
+ /* Start of meta */
+ if (g_ascii_strncasecmp (inptr, "<meta ", 6) == 0) {
+ /* If there was previous meta tag */
+ if (end_of_prev_meta) {
+ /* And there were some tags between these two meta tags */
+ if (inptr - 1 != end_of_prev_meta) {
+ /* Save them */
+ gchar *tags;
+
+ tags = g_strndup (
+ end_of_prev_meta + 1,
+ inptr - end_of_prev_meta - 2);
+
+ g_string_append (new_out, tags);
+ g_free (tags);
+ }
+ }
+
+ in_meta = TRUE;
+ start = inptr;
+ inptr += 6;
+ }
+
+ /* Meta tags are valid just in head element */
+ if (!in_meta && g_ascii_strncasecmp (inptr, "</head>", 7) == 0) {
+ meta_remove->after_head = TRUE;
+ if (end_of_prev_meta)
+ break;
+ else
+ goto copy_input;
+ }
+
+ if (!in_meta && g_ascii_strncasecmp (inptr, "<body", 5) == 0) {
+ meta_remove->after_head = TRUE;
+ if (end_of_prev_meta)
+ break;
+ else
+ goto copy_input;
+ }
+
+ /* Charset meta */
+ if (in_meta && !meta_remove->remove_all_meta) {
+ if (g_ascii_strncasecmp (inptr, "charset", 7) == 0)
+ charset_meta = TRUE;
+ }
+
+ /* End of meta tag */
+ if (in_meta && g_ascii_strncasecmp (inptr, ">", 1) == 0) {
+ end_of_prev_meta = inptr;
+ in_meta = FALSE;
+ /* Strip meta tag from input */
+ if (meta_remove->remove_all_meta || charset_meta) {
+ if (new_out->len == 0 && !previously_in_meta) {
+ if (start) {
+ /* Copy tags before meta tag */
+ if (start - in > 0) {
+ gchar *beginning;
+
+ beginning = g_strndup (in, start - in);
+ g_string_append (new_out, beginning);
+ g_free (beginning);
+ }
+ } else {
+ /* If meta tag continues from previous buffer
+ * just adjust the offset */
+ offset = end_of_prev_meta + 1 - in;
+ }
+ }
+
+ /* If we wanted to remove just charset meta and we
+ * removed it, quit */
+ if (!meta_remove->remove_all_meta) {
+ meta_remove->after_head = TRUE;
+ break;
+ }
+ }
+ start = NULL;
+ charset_meta = FALSE;
+ }
+
+ inptr++;
+ }
+
+ if (in_meta) {
+ /* Meta tag doesn't end in this buffer */
+ gchar *tags = NULL;
+
+ if (end_of_prev_meta && start) {
+ /* No tags between two meta tags */
+ if (end_of_prev_meta + 1 == start)
+ goto save_output;
+ tags = g_strndup (
+ end_of_prev_meta + 1,
+ start - end_of_prev_meta - 2);
+ } else if (!end_of_prev_meta && start) {
+ tags = g_strndup (in + offset , start - in - offset);
+ }
+
+ if (tags) {
+ g_string_append (new_out, tags);
+ g_free (tags);
+ }
+ } else if (end_of_prev_meta) {
+ gchar *end;
+
+ /* Copy tags after last meta to output */
+ end = g_strndup (end_of_prev_meta + 1, inend - end_of_prev_meta - 1);
+ g_string_append (new_out, end);
+ g_free (end);
+ } else if (!end_of_prev_meta) {
+ /* Meta was not found in this buffer */
+ camel_mime_filter_backup (filter, inend - 6, 6);
+ backup = TRUE;
+ goto copy_input;
+ }
+
+ save_output:
+ *out = (gchar *) new_out->str;
+ *outlen = new_out->len;
+ g_string_free (new_out, FALSE);
+
+ meta_remove->in_meta = in_meta;
+
+ return;
+
+ copy_input:
+ if (backup) {
+ *out = g_strndup (in, inend - in - 6);
+ *outlen = inend - in - 6;
+ } else {
+ *out = (gchar *) in;
+ *outlen = inend - in;
+ }
+
+ meta_remove->in_meta = in_meta;
+
+ g_string_free (new_out, TRUE);
+}
+
+static void
+filter_filter (CamelMimeFilter *filter,
+ const gchar *in,
+ gsize len,
+ gsize prespace,
+ gchar **out,
+ gsize *outlen,
+ gsize *outprespace)
+{
+ remove_meta_tag (filter, in, len, prespace, out, outlen);
+
+ *outprespace = prespace;
+}
+
+static void
+filter_complete (CamelMimeFilter *filter,
+ const gchar *in,
+ gsize len,
+ gsize prespace,
+ gchar **out,
+ gsize *outlen,
+ gsize *outprespace)
+{
+ *out = (gchar *) in;
+ *outlen = len;
+ *outprespace = prespace;
+}
+
+static void
+filter_reset (CamelMimeFilter *filter)
+{
+ EMailMetaRemoveFilter *meta_remove = (EMailMetaRemoveFilter *) filter;
+
+ meta_remove->in_meta = FALSE;
+ meta_remove->after_head = FALSE;
+}
+
+static void
+e_mail_meta_remove_filter_class_init (EMailMetaRemoveFilterClass *class)
+{
+ CamelMimeFilterClass *mime_filter_class;
+
+ mime_filter_class = CAMEL_MIME_FILTER_CLASS (class);
+ mime_filter_class->filter = filter_filter;
+ mime_filter_class->complete = filter_complete;
+ mime_filter_class->reset = filter_reset;
+}
+
+static void
+e_mail_meta_remove_filter_init (EMailMetaRemoveFilter *filter)
+{
+}
+
+/**
+ * e_mail_meta_remove_filter_new:
+ * @remove_all_meta: Whether remove all meta tags from message or just meta
+ * tag with charset attribute
+ *
+ * Creates a new meta_remove filter.
+ *
+ * Returns a new meta_remove filter.
+ **/
+CamelMimeFilter *
+e_mail_meta_remove_filter_new (gboolean remove_all_meta)
+{
+ EMailMetaRemoveFilter *filter = g_object_new (E_TYPE_MAIL_META_REMOVE_FILTER, NULL);
+
+ filter->remove_all_meta = remove_all_meta;
+ filter->in_meta = FALSE;
+ filter->after_head = FALSE;
+
+ return CAMEL_MIME_FILTER (filter);
+}
diff --git a/em-format/e-mail-meta-remove-filter.h b/em-format/e-mail-meta-remove-filter.h
new file mode 100644
index 0000000..e46242a
--- /dev/null
+++ b/em-format/e-mail-meta-remove-filter.h
@@ -0,0 +1,66 @@
+/*
+ * e-mail-meta-remove-filter.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 E_MAIL_META_REMOVE_FILTER_H
+#define E_MAIL_META_REMOVE_FILTER_H
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_META_REMOVE_FILTER \
+ (e_mail_meta_remove_filter_get_type ())
+#define E_MAIL_META_REMOVE_FILTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_META_REMOVE_FILTER, EMailmeta_removeFilter))
+#define E_MAIL_META_REMOVE_FILTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_META_REMOVE_FILTER, EMailmeta_removeFilterClass))
+#define E_IS_MAIL_META_REMOVE_FILTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_META_REMOVE_FILTER))
+#define E_IS_MAIL_META_REMOVE_FILTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_META_REMOVE_FILTER))
+#define E_MAIL_META_REMOVE_FILTER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_META_REMOVE_FILTER, EMailmeta_removeFilterClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailMetaRemoveFilter EMailMetaRemoveFilter;
+typedef struct _EMailMetaRemoveFilterClass EMailMetaRemoveFilterClass;
+
+struct _EMailMetaRemoveFilter {
+ CamelMimeFilter parent;
+
+ gboolean remove_all_meta;
+ gboolean in_meta;
+ gboolean after_head;
+};
+
+struct _EMailMetaRemoveFilterClass {
+ CamelMimeFilterClass parent_class;
+};
+
+GType e_mail_meta_remove_filter_get_type (void);
+CamelMimeFilter *
+ e_mail_meta_remove_filter_new (gboolean remove_all_meta);
+
+G_END_DECLS
+
+#endif /* E_MAIL_META_REMOVE_FILTER_H */
diff --git a/em-format/e-mail-part-headers.c b/em-format/e-mail-part-headers.c
index 9ffa594..db3e7f6 100644
--- a/em-format/e-mail-part-headers.c
+++ b/em-format/e-mail-part-headers.c
@@ -213,29 +213,21 @@ mail_part_headers_constructed (GObject *object)
static void
mail_part_headers_bind_dom_element (EMailPart *part,
- WebKitDOMElement *element)
+ GDBusProxy *web_extension,
+ guint64 page_id,
+ const gchar *element_id)
{
- WebKitDOMDocument *document;
- WebKitDOMElement *photo;
- gchar *addr, *uri;
-
- document = webkit_dom_node_get_owner_document (
- WEBKIT_DOM_NODE (element));
- photo = webkit_dom_document_get_element_by_id (
- document, "__evo-contact-photo");
-
- /* Contact photos disabled, the <img> tag is not there. */
- if (photo == NULL)
- return;
-
- addr = webkit_dom_element_get_attribute (photo, "data-mailaddr");
- uri = g_strdup_printf ("mail://contact-photo?mailaddr=%s", addr);
-
- webkit_dom_html_image_element_set_src (
- WEBKIT_DOM_HTML_IMAGE_ELEMENT (photo), uri);
-
- g_free (addr);
- g_free (uri);
+ if (web_extension) {
+ g_dbus_proxy_call (
+ web_extension,
+ "EMailPartHeadersBindDOMElement",
+ g_variant_new ("(ts)", page_id, element_id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+ }
}
static void
diff --git a/em-format/e-mail-part.c b/em-format/e-mail-part.c
index 8aa21bb..5b76d58 100644
--- a/em-format/e-mail-part.c
+++ b/em-format/e-mail-part.c
@@ -487,17 +487,21 @@ e_mail_part_set_is_attachment (EMailPart *part,
void
e_mail_part_bind_dom_element (EMailPart *part,
- WebKitDOMElement *element)
+ GDBusProxy *web_extension,
+ guint64 page_id,
+ const gchar *element_id)
{
EMailPartClass *class;
g_return_if_fail (E_IS_MAIL_PART (part));
- g_return_if_fail (WEBKIT_DOM_IS_ELEMENT (element));
+ g_return_if_fail (web_extension);
+ g_return_if_fail (page_id != 0);
+ g_return_if_fail (element_id && *element_id);
class = E_MAIL_PART_GET_CLASS (part);
if (class->bind_dom_element != NULL)
- class->bind_dom_element (part, element);
+ class->bind_dom_element (part, web_extension, page_id, element_id);
}
static EMailPartValidityPair *
diff --git a/em-format/e-mail-part.h b/em-format/e-mail-part.h
index 63e8ae1..7d112df 100644
--- a/em-format/e-mail-part.h
+++ b/em-format/e-mail-part.h
@@ -19,7 +19,6 @@
#define E_MAIL_PART_H
#include <camel/camel.h>
-#include <webkit/webkitdom.h>
#include <e-util/e-util.h>
@@ -87,7 +86,9 @@ struct _EMailPartClass {
GObjectClass parent_class;
void (*bind_dom_element) (EMailPart *part,
- WebKitDOMElement *element);
+ GDBusProxy *web_extension,
+ guint64 page_id,
+ const gchar *element_id);
};
GType e_mail_part_get_type (void) G_GNUC_CONST;
@@ -115,7 +116,9 @@ gboolean e_mail_part_get_is_attachment (EMailPart *part);
void e_mail_part_set_is_attachment (EMailPart *part,
gboolean is_attachment);
void e_mail_part_bind_dom_element (EMailPart *part,
- WebKitDOMElement *element);
+ GDBusProxy *web_extension,
+ guint64 page_id,
+ const gchar *element_id);
void e_mail_part_update_validity (EMailPart *part,
CamelCipherValidity *validity,
EMailPartValidityFlags validity_type);
diff --git a/mail/e-http-request.c b/mail/e-http-request.c
index 39ceb56..f9ae4a3 100644
--- a/mail/e-http-request.c
+++ b/mail/e-http-request.c
@@ -25,7 +25,7 @@
#include <libsoup/soup-requester.h>
#include <libsoup/soup-request-http.h>
#include <camel/camel.h>
-#include <webkit/webkit.h>
+#include <webkit2/webkit2.h>
#include <e-util/e-util.h>
#include <libemail-engine/libemail-engine.h>
diff --git a/mail/e-mail-display-popup-extension.c b/mail/e-mail-display-popup-extension.c
index e95dc3e..5c5f891 100644
--- a/mail/e-mail-display-popup-extension.c
+++ b/mail/e-mail-display-popup-extension.c
@@ -39,8 +39,7 @@ e_mail_display_popup_extension_default_init (EMailDisplayPopupExtensionInterface
* on every extension so that they can add their items to the menu.
*/
void
-e_mail_display_popup_extension_update_actions (EMailDisplayPopupExtension *extension,
- WebKitHitTestResult *context)
+e_mail_display_popup_extension_update_actions (EMailDisplayPopupExtension *extension)
{
EMailDisplayPopupExtensionInterface *iface;
@@ -49,5 +48,5 @@ e_mail_display_popup_extension_update_actions (EMailDisplayPopupExtension *exten
iface = E_MAIL_DISPLAY_POPUP_EXTENSION_GET_INTERFACE (extension);
g_return_if_fail (iface->update_actions != NULL);
- iface->update_actions (extension, context);
+ iface->update_actions (extension);
}
diff --git a/mail/e-mail-display-popup-extension.h b/mail/e-mail-display-popup-extension.h
index 67c1374..964b0c5 100644
--- a/mail/e-mail-display-popup-extension.h
+++ b/mail/e-mail-display-popup-extension.h
@@ -19,7 +19,6 @@
#define E_MAIL_DISPLAY_POPUP_EXTENSION_H
#include <glib-object.h>
-#include <webkit/webkit.h>
/* Standard GObject macros */
#define E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION \
@@ -48,15 +47,13 @@ typedef struct _EMailDisplayPopupExtensionInterface EMailDisplayPopupExtensionIn
struct _EMailDisplayPopupExtensionInterface {
GTypeInterface parent_interface;
- void (*update_actions) (EMailDisplayPopupExtension *extension,
- WebKitHitTestResult *context);
+ void (*update_actions) (EMailDisplayPopupExtension *extension);
};
GType e_mail_display_popup_extension_get_type (void);
void e_mail_display_popup_extension_update_actions
- (EMailDisplayPopupExtension *extension,
- WebKitHitTestResult *context);
+ (EMailDisplayPopupExtension *extension);
G_END_DECLS
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index 3f57261..c69d06c 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -36,9 +36,12 @@
#include "e-http-request.h"
#include "e-mail-display-popup-extension.h"
#include "e-mail-request.h"
+#include "e-mail-ui-session.h"
#include "em-composer-utils.h"
#include "em-utils.h"
+#include <web-extensions/evolution-web-extension.h>
+
#define d(x)
#define E_MAIL_DISPLAY_GET_PRIVATE(obj) \
@@ -61,6 +64,8 @@ struct _EMailDisplayPrivate {
guint scheduled_reload;
GHashTable *old_settings;
+
+ guint web_extension_headers_collapsed_signal_id;
};
enum {
@@ -72,8 +77,6 @@ enum {
PROP_PART_LIST
};
-static CamelDataCache *emd_global_http_cache = NULL;
-
static const gchar *ui =
"<ui>"
" <popup name='context'>"
@@ -152,29 +155,6 @@ formatter_image_loading_policy_changed_cb (GObject *object,
e_mail_display_reload (display);
}
-static gboolean
-mail_display_image_exists_in_cache (const gchar *image_uri)
-{
- gchar *filename;
- gchar *hash;
- gboolean exists = FALSE;
-
- g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
-
- hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
- filename = camel_data_cache_get_filename (
- emd_global_http_cache, "http", hash);
-
- if (filename != NULL) {
- exists = g_file_test (filename, G_FILE_TEST_EXISTS);
- g_free (filename);
- }
-
- g_free (hash);
-
- return exists;
-}
-
static void
mail_display_update_formatter_colors (EMailDisplay *display)
{
@@ -188,6 +168,7 @@ mail_display_update_formatter_colors (EMailDisplay *display)
e_mail_formatter_update_style (formatter, state_flags);
}
+#if 0
static void
mail_display_plugin_widget_disconnect_children (GtkWidget *widget,
gpointer mail_display)
@@ -210,7 +191,7 @@ mail_display_plugin_widget_disconnect (gpointer widget_uri,
mail_display_plugin_widget_disconnect_children,
mail_display);
}
-
+#endif
static gboolean
mail_display_process_mailto (EWebView *web_view,
const gchar *mailto_uri,
@@ -240,14 +221,29 @@ mail_display_process_mailto (EWebView *web_view,
}
static gboolean
-mail_display_link_clicked (WebKitWebView *web_view,
- WebKitWebFrame *frame,
- WebKitNetworkRequest *request,
- WebKitWebNavigationAction *navigation_action,
- WebKitWebPolicyDecision *policy_decision,
- gpointer user_data)
+decide_policy_cb (WebKitWebView *web_view,
+ WebKitPolicyDecision *decision,
+ WebKitPolicyDecisionType type)
{
- const gchar *uri = webkit_network_request_get_uri (request);
+ WebKitNavigationPolicyDecision *navigation_decision;
+ WebKitNavigationAction *navigation_action;
+ WebKitURIRequest *request;
+ const gchar *uri;
+
+ if (type != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
+ return FALSE;
+
+ navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
+ navigation_action = webkit_navigation_policy_decision_get_navigation_action (navigation_decision);
+ request = webkit_navigation_action_get_request (navigation_action);
+
+ uri = webkit_uri_request_get_uri (request);
+
+ if (!uri || !*uri) {
+ g_warning ("asdasdasdasdadasdasd");
+ webkit_policy_decision_ignore (decision);
+ return TRUE;
+ }
if (g_str_has_prefix (uri, "file://")) {
gchar *filename;
@@ -255,8 +251,9 @@ mail_display_link_clicked (WebKitWebView *web_view,
filename = g_filename_from_uri (uri, NULL, NULL);
if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
- webkit_web_policy_decision_ignore (policy_decision);
- webkit_network_request_set_uri (request, "about:blank");
+ webkit_policy_decision_ignore (decision);
+ /* FIXME XXX WK2 Not sure if the request will be changed there */
+ webkit_uri_request_set_uri (request, "about:blank");
g_free (filename);
return TRUE;
}
@@ -266,17 +263,17 @@ mail_display_link_clicked (WebKitWebView *web_view,
if (mail_display_process_mailto (E_WEB_VIEW (web_view), uri, NULL)) {
/* do nothing, function handled the "mailto:" uri already */
- webkit_web_policy_decision_ignore (policy_decision);
+ webkit_policy_decision_ignore (decision);
return TRUE;
} else if (g_ascii_strncasecmp (uri, "thismessage:", 12) == 0) {
/* ignore */
- webkit_web_policy_decision_ignore (policy_decision);
+ webkit_policy_decision_ignore (decision);
return TRUE;
} else if (g_ascii_strncasecmp (uri, "cid:", 4) == 0) {
/* ignore */
- webkit_web_policy_decision_ignore (policy_decision);
+ webkit_policy_decision_ignore (decision);
return TRUE;
}
@@ -284,7 +281,7 @@ mail_display_link_clicked (WebKitWebView *web_view,
/* Let WebKit handle it. */
return FALSE;
}
-
+#if 0
static void
mail_display_resource_requested (WebKitWebView *web_view,
WebKitWebFrame *frame,
@@ -725,114 +722,7 @@ exit:
return widget;
}
-
-static void
-toggle_headers_visibility (WebKitDOMElement *button,
- WebKitDOMEvent *event,
- WebKitWebView *web_view)
-{
- WebKitDOMDocument *document;
- WebKitDOMElement *short_headers, *full_headers;
- WebKitDOMCSSStyleDeclaration *css_short, *css_full;
- gboolean expanded;
- const gchar *path;
- gchar *css_value;
-
- document = webkit_web_view_get_dom_document (web_view);
-
- short_headers = webkit_dom_document_get_element_by_id (
- document, "__evo-short-headers");
- if (short_headers == NULL)
- return;
-
- css_short = webkit_dom_element_get_style (short_headers);
-
- full_headers = webkit_dom_document_get_element_by_id (
- document, "__evo-full-headers");
- if (full_headers == NULL)
- return;
-
- css_full = webkit_dom_element_get_style (full_headers);
- css_value = webkit_dom_css_style_declaration_get_property_value (
- css_full, "display");
- expanded = (g_strcmp0 (css_value, "table") == 0);
- g_free (css_value);
-
- webkit_dom_css_style_declaration_set_property (
- css_full, "display",
- expanded ? "none" : "table", "", NULL);
- webkit_dom_css_style_declaration_set_property (
- css_short, "display",
- expanded ? "table" : "none", "", NULL);
-
- if (expanded)
- path = "evo-file://" EVOLUTION_IMAGESDIR "/plus.png";
- else
- path = "evo-file://" EVOLUTION_IMAGESDIR "/minus.png";
-
- webkit_dom_html_image_element_set_src (
- WEBKIT_DOM_HTML_IMAGE_ELEMENT (button), path);
-
- e_mail_display_set_headers_collapsed (
- E_MAIL_DISPLAY (web_view), expanded);
-
- d (printf ("Headers %s!\n", expanded ? "collapsed" : "expanded"));
-}
-
-static void
-toggle_address_visibility (WebKitDOMElement *button,
- WebKitDOMEvent *event)
-{
- WebKitDOMElement *full_addr, *ellipsis;
- WebKitDOMElement *parent;
- WebKitDOMCSSStyleDeclaration *css_full, *css_ellipsis;
- const gchar *path;
- gboolean expanded;
-
- /* <b> element */
- parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (button));
- /* <td> element */
- parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (parent));
-
- full_addr = webkit_dom_element_query_selector (parent, "#__evo-moreaddr", NULL);
-
- if (!full_addr)
- return;
-
- css_full = webkit_dom_element_get_style (full_addr);
-
- ellipsis = webkit_dom_element_query_selector (parent, "#__evo-moreaddr-ellipsis", NULL);
-
- if (!ellipsis)
- return;
-
- css_ellipsis = webkit_dom_element_get_style (ellipsis);
-
- expanded = (g_strcmp0 (
- webkit_dom_css_style_declaration_get_property_value (
- css_full, "display"), "inline") == 0);
-
- webkit_dom_css_style_declaration_set_property (
- css_full, "display", (expanded ? "none" : "inline"), "", NULL);
- webkit_dom_css_style_declaration_set_property (
- css_ellipsis, "display", (expanded ? "inline" : "none"), "", NULL);
-
- if (expanded)
- path = "evo-file://" EVOLUTION_IMAGESDIR "/plus.png";
- else
- path = "evo-file://" EVOLUTION_IMAGESDIR "/minus.png";
-
- if (!WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (button)) {
- button = webkit_dom_element_query_selector (parent, "#__evo-moreaddr-img", NULL);
-
- if (!button)
- return;
- }
-
- webkit_dom_html_image_element_set_src (
- WEBKIT_DOM_HTML_IMAGE_ELEMENT (button), path);
-}
-
+#endif
static void
add_color_css_rule_for_web_view (EWebView *view,
const gchar *color_name,
@@ -930,87 +820,148 @@ setup_image_click_event_listeners_on_document (WebKitDOMDocument *document,
}
static void
+headers_collapsed_signal_cb (GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ EMailDisplay *display)
+{
+ gboolean expanded;
+
+ if (g_strcmp0 (signal_name, "HeadersCollapsed") != 0)
+ return;
+
+ if (parameters)
+ g_variant_get (parameters, "(b)", &expanded);
+
+ e_mail_display_set_headers_collapsed (display, expanded);
+}
+
+static void
setup_dom_bindings (WebKitWebView *web_view,
- WebKitWebFrame *frame,
+ WebKitLoadEvent load_event,
gpointer user_data)
{
- WebKitDOMDocument *document;
+ GDBusProxy *web_extension;
+ EMailDisplay *display;
- document = webkit_web_frame_get_dom_document (frame);
+ if (load_event != WEBKIT_LOAD_FINISHED)
+ return;
- setup_image_click_event_listeners_on_document (document, web_view);
+ display = E_MAIL_DISPLAY (web_view);
+
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (web_view));
+
+
+ if (web_extension) {
+ if (display->priv->web_extension_headers_collapsed_signal_id == 0) {
+ display->priv->web_extension_headers_collapsed_signal_id =
+ g_dbus_connection_signal_subscribe (
+ g_dbus_proxy_get_connection (web_extension),
+ g_dbus_proxy_get_name (web_extension),
+ EVOLUTION_WEB_EXTENSION_INTERFACE,
+ "RecurToggled",
+ EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ (GDBusSignalCallback) headers_collapsed_signal_cb,
+ display,
+ NULL);
+ }
+
+ g_dbus_proxy_call (
+ web_extension,
+ "EMailDisplayBindDOM",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (web_view)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+ }
+}
+
+static void
+mail_element_exists_cb (GDBusProxy *web_extension,
+ GAsyncResult *result,
+ EMailPart *part)
+{
+ gboolean element_exists = FALSE;
+ GVariant *result_variant;
+ guint64 page_id;
+
+ result_variant = g_dbus_proxy_call_finish (web_extension, result, NULL);
+ if (result_variant) {
+ g_variant_get (result_variant, "(bt)", &element_exists, &page_id);
+ g_variant_unref (result_variant);
+ }
+
+ if (element_exists)
+ e_mail_part_bind_dom_element (
+ part,
+ web_extension,
+ page_id,
+ e_mail_part_get_id (part));
+
+ g_object_unref (part);
}
static void
-mail_parts_bind_dom (GObject *object,
- GParamSpec *pspec,
+mail_parts_bind_dom (WebKitWebView *web_view,
+ WebKitLoadEvent load_event,
gpointer user_data)
{
- WebKitWebFrame *frame;
- WebKitLoadStatus load_status;
- WebKitWebView *web_view;
- WebKitDOMDocument *document;
EMailDisplay *display;
GQueue queue = G_QUEUE_INIT;
GList *head, *link;
- const gchar *frame_name;
+ GDBusProxy *web_extension;
- frame = WEBKIT_WEB_FRAME (object);
- load_status = webkit_web_frame_get_load_status (frame);
-
- if (load_status != WEBKIT_LOAD_FINISHED)
+ if (load_event != WEBKIT_LOAD_FINISHED)
return;
- web_view = webkit_web_frame_get_web_view (frame);
display = E_MAIL_DISPLAY (web_view);
if (display->priv->part_list == NULL)
return;
initialize_web_view_colors (display);
- frame_name = webkit_web_frame_get_name (frame);
- if (frame_name == NULL || *frame_name == '\0')
- frame_name = ".message.headers";
- document = webkit_web_view_get_dom_document (web_view);
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
+ if (!web_extension)
+ return;
e_mail_part_list_queue_parts (
- display->priv->part_list, frame_name, &queue);
+ display->priv->part_list, NULL, &queue);
head = g_queue_peek_head_link (&queue);
for (link = head; link != NULL; link = g_list_next (link)) {
EMailPart *part = E_MAIL_PART (link->data);
- WebKitDOMElement *element;
const gchar *part_id;
- /* Iterate only the parts rendered in
- * the frame and all it's subparts. */
- if (!e_mail_part_id_has_prefix (part, frame_name))
- break;
-
part_id = e_mail_part_get_id (part);
- element = find_element_by_id (document, part_id);
- if (element != NULL)
- e_mail_part_bind_dom_element (part, element);
+ g_dbus_proxy_call (
+ web_extension,
+ "ElementExists",
+ g_variant_new (
+ "(ts)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (display)),
+ part_id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback)mail_element_exists_cb,
+ g_object_ref (part));
}
while (!g_queue_is_empty (&queue))
g_object_unref (g_queue_pop_head (&queue));
}
-
-static void
-mail_display_frame_created (WebKitWebView *web_view,
- WebKitWebFrame *frame,
- gpointer user_data)
-{
- d (printf ("Frame %s created!\n", webkit_web_frame_get_name (frame)));
-
- /* Call bind_func of all parts written in this frame */
- g_signal_connect (
- frame, "notify::load-status",
- G_CALLBACK (mail_parts_bind_dom), NULL);
-}
-
+#if 0
static void
mail_display_uri_changed (EMailDisplay *display,
GParamSpec *pspec,
@@ -1031,7 +982,7 @@ mail_display_uri_changed (EMailDisplay *display,
(GDestroyNotify) g_free,
(GDestroyNotify) e_weak_ref_free);
}
-
+#endif
static void
mail_display_set_property (GObject *object,
guint property_id,
@@ -1124,7 +1075,7 @@ mail_display_dispose (GObject *object)
g_source_remove (priv->scheduled_reload);
priv->scheduled_reload = 0;
}
-
+#if 0
if (priv->widgets != NULL) {
g_hash_table_foreach (
priv->widgets,
@@ -1132,12 +1083,20 @@ mail_display_dispose (GObject *object)
g_hash_table_destroy (priv->widgets);
priv->widgets = NULL;
}
-
+#endif
if (priv->settings != NULL)
g_signal_handlers_disconnect_matched (
priv->settings, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, object);
+ if (priv->web_extension_headers_collapsed_signal_id > 0) {
+ g_dbus_connection_signal_unsubscribe (
+ g_dbus_proxy_get_connection (
+ e_web_view_get_web_extension_proxy (E_WEB_VIEW (object))),
+ priv->web_extension_headers_collapsed_signal_id);
+ priv->web_extension_headers_collapsed_signal_id = 0;
+ }
+
g_clear_object (&priv->part_list);
g_clear_object (&priv->formatter);
g_clear_object (&priv->settings);
@@ -1163,12 +1122,89 @@ mail_display_finalize (GObject *object)
}
static void
+mail_display_get_font_settings (GSettings *settings,
+ PangoFontDescription **monospace,
+ PangoFontDescription **variable)
+{
+ gboolean use_custom_font;
+ gchar *monospace_font;
+ gchar *variable_font;
+
+ use_custom_font = g_settings_get_boolean (settings, "use-custom-font");
+
+ if (!use_custom_font) {
+ *monospace = NULL;
+ *variable = NULL;
+ return;
+ }
+
+ monospace_font = g_settings_get_string (settings, "monospace-font");
+ variable_font = g_settings_get_string (settings, "variable-width-font");
+
+ *monospace = (monospace_font != NULL) ?
+ pango_font_description_from_string (monospace_font) : NULL;
+ *variable = (variable_font != NULL) ?
+ pango_font_description_from_string (variable_font) : NULL;
+
+ g_free (monospace_font);
+ g_free (variable_font);
+}
+
+static void
+mail_display_set_fonts (EWebView *web_view,
+ PangoFontDescription **monospace,
+ PangoFontDescription **variable)
+{
+ EMailDisplay *display = E_MAIL_DISPLAY (web_view);
+
+ mail_display_get_font_settings (display->priv->settings, monospace, variable);
+}
+
+static void
+mail_display_web_view_initialize (WebKitWebView *web_view)
+{
+ const gchar *id = "org.gnome.settings-daemon.plugins.xsettings";
+ GSettings *settings;
+ GSettingsSchema *settings_schema;
+ WebKitSettings *webkit_settings;
+ PangoFontDescription *ms = NULL, *vw = NULL;
+
+ webkit_settings = webkit_web_view_get_settings (web_view);
+
+ g_object_set (webkit_settings,
+ "enable-frame-flattening", TRUE,
+ NULL);
+
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ mail_display_get_font_settings (settings, &ms, &vw);
+
+ /* Optional schema */
+ settings_schema = g_settings_schema_source_lookup (
+ g_settings_schema_source_get_default (), id, FALSE);
+
+ if (settings_schema)
+ settings = g_settings_new (id);
+ else
+ settings = NULL;
+
+ e_web_view_update_fonts_settings (
+ g_settings_new ("org.gnome.desktop.interface"),
+ settings,
+ ms, vw, GTK_WIDGET (web_view));
+
+ pango_font_description_free (ms);
+ pango_font_description_free (vw);
+}
+
+static void
mail_display_constructed (GObject *object)
{
e_extensible_load_extensions (E_EXTENSIBLE (object));
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_mail_display_parent_class)->constructed (object);
+
+ mail_display_web_view_initialize (WEBKIT_WEB_VIEW (object));
}
static void
@@ -1197,15 +1233,11 @@ mail_display_button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
EWebView *web_view = E_WEB_VIEW (widget);
- WebKitHitTestResult *hit_test;
GList *list, *link;
if (event->button != 3)
goto chainup;
- hit_test = webkit_web_view_get_hit_test_result (
- WEBKIT_WEB_VIEW (web_view), event);
-
list = e_extensible_list_extensions (
E_EXTENSIBLE (web_view), E_TYPE_EXTENSION);
for (link = list; link != NULL; link = g_list_next (link)) {
@@ -1215,18 +1247,16 @@ mail_display_button_press_event (GtkWidget *widget,
continue;
e_mail_display_popup_extension_update_actions (
- E_MAIL_DISPLAY_POPUP_EXTENSION (extension), hit_test);
+ E_MAIL_DISPLAY_POPUP_EXTENSION (extension));
}
g_list_free (list);
- g_object_unref (hit_test);
-
chainup:
/* Chain up to parent's button_press_event() method. */
return GTK_WIDGET_CLASS (e_mail_display_parent_class)->
button_press_event (widget, event);
}
-
+#if 0
static gchar *
mail_display_redirect_uri (EWebView *web_view,
const gchar *uri)
@@ -1241,54 +1271,6 @@ mail_display_redirect_uri (EWebView *web_view,
if (part_list == NULL)
goto chainup;
- /* Redirect cid:part_id to mail://mail_id/cid:part_id */
- if (g_str_has_prefix (uri, "cid:")) {
- CamelFolder *folder;
- const gchar *message_uid;
-
- folder = e_mail_part_list_get_folder (part_list);
- message_uid = e_mail_part_list_get_message_uid (part_list);
-
- /* Always write raw content of CID object. */
- return e_mail_part_build_uri (
- folder, message_uid,
- "part_id", G_TYPE_STRING, uri,
- "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_CID, NULL);
- }
-
- /* WebKit won't allow to load a local file when displaying
- * "remote" mail:// protocol, so we need to handle this manually. */
- if (g_str_has_prefix (uri, "file:")) {
- gchar *content = NULL;
- gchar *content_type;
- gchar *filename;
- gchar *encoded;
- gchar *new_uri;
- gsize length = 0;
-
- filename = g_filename_from_uri (uri, NULL, NULL);
- if (filename == NULL)
- goto chainup;
-
- if (!g_file_get_contents (filename, &content, &length, NULL)) {
- g_free (filename);
- goto chainup;
- }
-
- encoded = g_base64_encode ((guchar *) content, length);
- content_type = g_content_type_guess (filename, NULL, 0, NULL);
-
- new_uri = g_strdup_printf (
- "data:%s;base64,%s", content_type, encoded);
-
- g_free (content_type);
- g_free (content);
- g_free (filename);
- g_free (encoded);
-
- return new_uri;
- }
-
uri_is_http =
g_str_has_prefix (uri, "http:") ||
g_str_has_prefix (uri, "https:") ||
@@ -1407,29 +1389,26 @@ mail_display_suggest_filename (EWebView *web_view,
return E_WEB_VIEW_CLASS (e_mail_display_parent_class)->
suggest_filename (web_view, uri);
}
-
+#endif
static void
-mail_display_set_fonts (EWebView *web_view,
- PangoFontDescription **monospace,
- PangoFontDescription **variable)
+mail_display_get_font_settings (GSettings *settings,
+ PangoFontDescription **monospace,
+ PangoFontDescription **variable)
{
EMailDisplay *display = E_MAIL_DISPLAY (web_view);
gboolean use_custom_font;
gchar *monospace_font;
gchar *variable_font;
- use_custom_font = g_settings_get_boolean (
- display->priv->settings, "use-custom-font");
+ use_custom_font = g_settings_get_boolean (settings, "use-custom-font");
if (!use_custom_font) {
*monospace = NULL;
*variable = NULL;
return;
}
- monospace_font = g_settings_get_string (
- display->priv->settings, "monospace-font");
- variable_font = g_settings_get_string (
- display->priv->settings, "variable-width-font");
+ monospace_font = g_settings_get_string (settings, "monospace-font");
+ variable_font = g_settings_get_string (settings, "variable-width-font");
*monospace = (monospace_font != NULL) ?
pango_font_description_from_string (monospace_font) : NULL;
@@ -1441,6 +1420,16 @@ mail_display_set_fonts (EWebView *web_view,
}
static void
+mail_display_set_fonts (EWebView *web_view,
+ PangoFontDescription **monospace,
+ PangoFontDescription **variable)
+{
+ EMailDisplay *display = E_MAIL_DISPLAY (web_view);
+
+ mail_display_get_font_settings (display->priv->settings, monospace, variable);
+}
+
+static void
e_mail_display_test_change_and_update_fonts_cb (EMailDisplay *mail_display,
const gchar *key,
GSettings *settings)
@@ -1546,8 +1535,10 @@ e_mail_display_class_init (EMailDisplayClass *class)
widget_class->button_press_event = mail_display_button_press_event;
web_view_class = E_WEB_VIEW_CLASS (class);
+#if 0
web_view_class->redirect_uri = mail_display_redirect_uri;
web_view_class->suggest_filename = mail_display_suggest_filename;
+#endif
web_view_class->set_fonts = mail_display_set_fonts;
g_object_class_install_property (
@@ -1606,12 +1597,754 @@ e_mail_display_class_init (EMailDisplayClass *class)
}
static void
+mail_display_process_uri_scheme_finished_cb (EMailDisplay *display,
+ GAsyncResult *result,
+ WebKitURISchemeRequest *request)
+{
+ GError *error = NULL;
+
+ if (!g_task_propagate_boolean (G_TASK (result), &error)) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_warning ("URI %s cannot be processed: %s",
+ webkit_uri_scheme_request_get_uri (request),
+ error ? error->message : "Unknown error");
+ }
+ g_object_unref (request);
+ if (error)
+ g_error_free (error);
+ }
+}
+
+static void
+mail_cid_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+ EMailDisplay *display)
+{
+ EMailPartList *part_list;
+ EMailPart *part;
+ GInputStream *stream;
+ const gchar *uri;
+ const gchar *mime_type;
+ GByteArray *byte_array;
+ CamelStream *output_stream;
+ GCancellable *cancellable = NULL;
+ CamelDataWrapper *dw;
+ CamelMimePart *mime_part;
+
+ part_list = e_mail_display_get_part_list (display);
+ uri = webkit_uri_scheme_request_get_uri (request);
+ part = e_mail_part_list_ref_part (part_list, uri);
+ mime_type = e_mail_part_get_mime_type (part);
+ mime_part = e_mail_part_ref_mime_part (part);
+ dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
+
+ g_return_if_fail (dw);
+
+ byte_array = g_byte_array_new ();
+ output_stream = camel_stream_mem_new ();
+
+ /* We retain ownership of the byte array. */
+ camel_stream_mem_set_byte_array (
+ CAMEL_STREAM_MEM (output_stream), byte_array);
+
+ camel_data_wrapper_decode_to_stream_sync (
+ dw, output_stream, cancellable, NULL);
+
+ stream = g_memory_input_stream_new_from_bytes (
+ g_byte_array_free_to_bytes (byte_array));
+
+ webkit_uri_scheme_request_finish (request, stream, -1, mime_type);
+
+ g_object_unref (mime_part);
+ g_object_unref (stream);
+ g_object_unref (part);
+}
+
+static gssize
+copy_stream_to_stream (CamelStream *input,
+ GMemoryInputStream *output,
+ GCancellable *cancellable)
+{
+ gchar *buff;
+ gssize read_len = 0;
+ gssize total_len = 0;
+
+ g_seekable_seek (G_SEEKABLE (input), 0, G_SEEK_SET, cancellable, NULL);
+
+ buff = g_malloc (4096);
+ while ((read_len = camel_stream_read (input, buff, 4096, cancellable, NULL)) > 0) {
+
+ g_memory_input_stream_add_data (output, buff, read_len, g_free);
+
+ total_len += read_len;
+
+ buff = g_malloc (4096);
+ }
+
+ /* Free the last unused buffer */
+ g_free (buff);
+
+ return total_len;
+}
+
+static void
+redirect_handler (SoupMessage *msg,
+ gpointer user_data)
+{
+ if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
+ SoupSession *soup_session = user_data;
+ SoupURI *new_uri;
+ const gchar *new_loc;
+
+ new_loc = soup_message_headers_get_list (msg->response_headers, "Location");
+ if (!new_loc)
+ return;
+
+ new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc);
+ if (!new_uri) {
+ soup_message_set_status_full (
+ msg,
+ SOUP_STATUS_MALFORMED,
+ "Invalid Redirect URL");
+ return;
+ }
+
+ soup_message_set_uri (msg, new_uri);
+ soup_session_requeue_message (soup_session, msg);
+
+ soup_uri_free (new_uri);
+ }
+}
+
+static void
+send_and_handle_redirection (SoupSession *session,
+ SoupMessage *message,
+ gchar **new_location)
+{
+ gchar *old_uri = NULL;
+
+ g_return_if_fail (message != NULL);
+
+ if (new_location) {
+ old_uri = soup_uri_to_string (soup_message_get_uri (message), FALSE);
+ }
+
+ soup_message_set_flags (message, SOUP_MESSAGE_NO_REDIRECT);
+ soup_message_add_header_handler (
+ message, "got_body", "Location",
+ G_CALLBACK (redirect_handler), session);
+ soup_message_headers_append (message->request_headers, "Connection", "close");
+ soup_session_send_message (session, message);
+
+ if (new_location) {
+ gchar *new_loc = soup_uri_to_string (soup_message_get_uri (message), FALSE);
+
+ if (new_loc && old_uri && !g_str_equal (new_loc, old_uri)) {
+ *new_location = new_loc;
+ } else {
+ g_free (new_loc);
+ }
+ }
+
+ g_free (old_uri);
+}
+
+static void
+web_view_process_http_uri_scheme_request (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ SoupURI *soup_uri;
+ gchar *evo_uri, *uri;
+ gchar *mail_uri;
+ const gchar *user_cache_dir;
+ const gchar *content_type;
+ GInputStream *stream = NULL;
+ gboolean force_load_images = FALSE;
+ gboolean ret_val = FALSE;
+ EMailImageLoadingPolicy image_policy;
+ gchar *uri_md5;
+ EShell *shell;
+ GSettings *settings;
+ CamelDataCache *cache;
+ CamelStream *cache_stream;
+ GHashTable *query;
+ gint uri_len;
+ WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
+
+ /* Remove the __evo-mail query */
+ soup_uri = soup_uri_new (webkit_uri_scheme_request_get_uri (request));
+
+ if (!soup_uri_get_query (soup_uri)) {
+ g_task_return_boolean (task, FALSE);
+ soup_uri_free (soup_uri);
+ return;
+ }
+
+ query = soup_form_decode (soup_uri_get_query (soup_uri));
+ mail_uri = g_hash_table_lookup (query, "__evo-mail");
+ if (mail_uri)
+ mail_uri = g_strdup (mail_uri);
+
+ g_hash_table_remove (query, "__evo-mail");
+
+ /* Remove __evo-load-images if present (and in such case set
+ * force_load_images to TRUE) */
+ force_load_images = g_hash_table_remove (query, "__evo-load-images");
+
+ soup_uri_set_query_from_form (soup_uri, query);
+ g_hash_table_unref (query);
+
+ evo_uri = soup_uri_to_string (soup_uri, FALSE);
+
+ if (camel_debug_start ("emformat:requests")) {
+ printf ("%s: looking for '%s'\n", G_STRFUNC, evo_uri);
+ camel_debug_end ();
+ }
+
+ /* Remove the "evo-" prefix from scheme */
+ uri_len = strlen (evo_uri);
+ uri = NULL;
+ if (evo_uri && (uri_len > 5)) {
+ /* Remove trailing "?" if there is no URI query */
+ if (evo_uri[uri_len - 1] == '?') {
+ uri = g_strndup (evo_uri + 4, uri_len - 5);
+ } else {
+ uri = g_strdup (evo_uri + 4);
+ }
+ g_free (evo_uri);
+ }
+
+ if (!uri || !*uri)
+ goto cleanup;
+
+ /* Use MD5 hash of the URI as a filname of the resourec cache file.
+ * We were previously using the URI as a filename but the URI is
+ * sometimes too long for a filename. */
+ uri_md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
+
+ /* Open Evolution's cache */
+ user_cache_dir = e_get_user_cache_dir ();
+ cache = camel_data_cache_new (user_cache_dir, NULL);
+ if (cache) {
+ camel_data_cache_set_expire_age (cache, 24 * 60 * 60);
+ camel_data_cache_set_expire_access (cache, 2 * 60 * 60);
+ }
+
+ /* Found item in cache! */
+ cache_stream = camel_data_cache_get (cache, "http", uri_md5, NULL);
+ if (cache_stream)
+ goto process;
+
+ /* If the item is not in the cache and Evolution is in offline mode then
+ * quit regardless any image loading policy */
+ shell = e_shell_get_default ();
+ if (!e_shell_get_online (shell)) {
+ goto cleanup;
+ }
+
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ image_policy = g_settings_get_enum (settings, "image-loading-policy");
+ g_object_unref (settings);
+
+ /* Item not found in cache, but image loading policy allows us to fetch
+ * it from the interwebs */
+ if (!force_load_images && mail_uri &&
+ (image_policy == E_MAIL_IMAGE_LOADING_POLICY_SOMETIMES)) {
+ CamelObjectBag *registry;
+ gchar *decoded_uri;
+ EMailPartList *part_list;
+
+ registry = e_mail_part_list_get_registry ();
+ decoded_uri = soup_uri_decode (mail_uri);
+
+ part_list = camel_object_bag_get (registry, decoded_uri);
+ if (part_list) {
+ EShellBackend *shell_backend;
+ EMailBackend *backend;
+ EMailSession *session;
+ CamelInternetAddress *addr;
+ CamelMimeMessage *message;
+ gboolean known_address = FALSE;
+ GError *error = NULL;
+
+ shell_backend =
+ e_shell_get_backend_by_name (shell, "mail");
+ backend = E_MAIL_BACKEND (shell_backend);
+ session = e_mail_backend_get_session (backend);
+
+ message = e_mail_part_list_get_message (part_list);
+ addr = camel_mime_message_get_from (message);
+
+ e_mail_ui_session_check_known_address_sync (
+ E_MAIL_UI_SESSION (session),
+ addr, FALSE, cancellable,
+ &known_address, &error);
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ if (known_address)
+ force_load_images = TRUE;
+
+ g_object_unref (part_list);
+ }
+
+ g_free (decoded_uri);
+ }
+
+ if ((image_policy == E_MAIL_IMAGE_LOADING_POLICY_ALWAYS) ||
+ force_load_images) {
+
+ SoupSession *session;
+ SoupMessage *message;
+ GError *error;
+ EProxy *proxy;
+
+ session = soup_session_sync_new_with_options (
+ SOUP_SESSION_TIMEOUT, 90,
+ NULL);
+
+ proxy = e_proxy_new ();
+ e_proxy_setup_proxy (proxy);
+
+ if (e_proxy_require_proxy_for_uri (proxy, uri)) {
+ SoupURI *proxy_uri;
+
+ proxy_uri = e_proxy_peek_uri_for (proxy, uri);
+
+ g_object_set (session, SOUP_SESSION_PROXY_URI, proxy_uri, NULL);
+ }
+
+ g_clear_object (&proxy);
+
+ message = soup_message_new (SOUP_METHOD_GET, uri);
+ soup_message_headers_append (
+ message->request_headers, "User-Agent", "Evolution/" VERSION);
+
+ send_and_handle_redirection (session, message, NULL);
+
+ if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
+ g_warning ("Failed to request %s (code %d)", uri, message->status_code);
+ goto cleanup;
+ }
+
+ /* Write the response body to cache */
+ error = NULL;
+ cache_stream = camel_data_cache_add (cache, "http", uri_md5, &error);
+ if (error != NULL) {
+ g_warning (
+ "Failed to create cache file for '%s': %s",
+ uri, error->message);
+ g_clear_error (&error);
+ } else {
+ camel_stream_write (
+ cache_stream, message->response_body->data,
+ message->response_body->length, cancellable, &error);
+
+ if (error != NULL) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning (
+ "Failed to write data to cache stream: %s",
+ error->message);
+ g_clear_error (&error);
+ g_object_unref (cache_stream);
+ goto cleanup;
+ }
+
+ g_seekable_seek (G_SEEKABLE (cache_stream), 0, G_SEEK_SET, cancellable, NULL);
+
+ }
+
+ g_object_unref (message);
+ g_object_unref (session);
+ }
+
+ process:
+ if (cache_stream) {
+ gssize len;
+
+ stream = g_memory_input_stream_new ();
+
+ len = copy_stream_to_stream (
+ cache_stream,
+ G_MEMORY_INPUT_STREAM (stream), cancellable);
+
+ camel_stream_close (cache_stream, cancellable, NULL);
+
+ g_object_unref (cache_stream);
+
+ /* When succesfully read some data from cache then
+ * get mimetype and return the stream to WebKit.
+ * Otherwise try to fetch the resource again from the network. */
+ if (len > 0) {
+ GFile *file;
+ GFileInfo *info;
+ gchar *path;
+
+ path = camel_data_cache_get_filename (cache, "http", uri_md5);
+ file = g_file_new_for_path (path);
+
+ info = g_file_query_info (
+ file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ 0, cancellable, NULL);
+
+ content_type = g_file_info_get_content_type (info);
+
+ webkit_uri_scheme_request_finish (
+ request, stream, len, content_type);
+
+ ret_val = TRUE;
+
+ g_object_unref (request);
+ g_object_unref (stream);
+
+ d (
+ printf ("'%s' found in cache (%d bytes, %s)\n",
+ uri, len, content_type));
+
+ g_object_unref (info);
+ g_object_unref (file);
+ g_free (path);
+ } else {
+ d (printf ("Failed to load '%s' from cache.\n", uri));
+ }
+ }
+ cleanup:
+ if (cache)
+ g_object_unref (cache);
+
+ if (soup_uri)
+ soup_uri_free (soup_uri);
+
+ g_free (uri);
+ g_free (uri_md5);
+ g_free (mail_uri);
+
+ g_task_return_boolean (task, ret_val);
+}
+
+static void
+mail_http_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+ EMailDisplay *display)
+{
+ GTask *task;
+ GCancellable *cancellable;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ cancellable = g_cancellable_new ();
+
+ task = g_task_new (
+ display, cancellable,
+ (GAsyncReadyCallback) mail_display_process_uri_scheme_finished_cb,
+ request);
+
+ g_task_set_task_data (task, g_object_ref (request), NULL);
+ g_task_run_in_thread (task, web_view_process_http_uri_scheme_request);
+
+ g_object_unref (task);
+ g_object_unref (cancellable);
+}
+
+static void
+mail_display_process_mail_uri_scheme_request (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GInputStream *stream = NULL;
+ EMailFormatter *formatter;
+ EMailPartList *part_list;
+ CamelStream *output_stream;
+ GByteArray *byte_array;
+ GHashTable *query;
+ const gchar *val, *uri;
+ const gchar *default_charset, *charset;
+ SoupURI *soup_uri;
+ EMailFormatterContext context = { 0 };
+ EMailDisplay *display = E_MAIL_DISPLAY (source_object);
+ WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
+
+ uri = webkit_uri_scheme_request_get_uri (request);
+
+ part_list = display->priv->part_list;
+
+ if (camel_debug_start ("emformat:requests")) {
+ printf ("%s: found part-list %p for full_uri '%s'\n", G_STRFUNC, part_list, uri);
+ camel_debug_end ();
+ }
+
+ if (!part_list) {
+ g_task_return_boolean (task, FALSE);
+ return;
+ }
+
+ soup_uri = soup_uri_new (uri);
+ if (!soup_uri || !soup_uri->query) {
+ if (soup_uri)
+ soup_uri_free (soup_uri);
+ g_task_return_boolean (task, FALSE);
+ return;
+ }
+ query = soup_form_decode (soup_uri->query);
+
+ val = g_hash_table_lookup (query, "headers_collapsed");
+ if (val && atoi (val) == 1)
+ context.flags |= E_MAIL_FORMATTER_HEADER_FLAG_COLLAPSED;
+
+ val = g_hash_table_lookup (query, "headers_collapsable");
+ if (val && atoi (val) == 1)
+ context.flags |= E_MAIL_FORMATTER_HEADER_FLAG_COLLAPSABLE;
+
+ val = g_hash_table_lookup (query, "mode");
+ if (val)
+ context.mode = atoi (val);
+
+ default_charset = g_hash_table_lookup (query, "formatter_default_charset");
+ charset = g_hash_table_lookup (query, "formatter_charset");
+
+ context.part_list = g_object_ref (part_list);
+ context.uri = g_strdup (uri);
+
+ formatter = display->priv->formatter;
+
+ if (default_charset && *default_charset != '\0')
+ e_mail_formatter_set_default_charset (formatter, default_charset);
+ if (charset && *charset != '\0')
+ e_mail_formatter_set_charset (formatter, charset);
+
+ byte_array = g_byte_array_new ();
+ output_stream = camel_stream_mem_new ();
+
+ /* We retain ownership of the byte array. */
+ camel_stream_mem_set_byte_array (
+ CAMEL_STREAM_MEM (output_stream), byte_array);
+
+ val = g_hash_table_lookup (query, "part_id");
+ if (val) {
+ EMailPart *part;
+ const gchar *mime_type;
+ gchar *part_id;
+
+ part_id = soup_uri_decode (val);
+ part = e_mail_part_list_ref_part (part_list, part_id);
+ if (!part) {
+ if (camel_debug_start ("emformat:requests")) {
+ printf ("%s: part with id '%s' not found\n", G_STRFUNC, val);
+ camel_debug_end ();
+ }
+
+ g_free (part_id);
+ goto no_part;
+ }
+ g_free (part_id);
+
+ mime_type = g_hash_table_lookup (query, "mime_type");
+
+ if (context.mode == E_MAIL_FORMATTER_MODE_SOURCE)
+ mime_type = "application/vnd.evolution.source";
+
+ if (context.mode == E_MAIL_FORMATTER_MODE_CID) {
+ CamelDataWrapper *dw;
+ CamelMimePart *mime_part;
+
+ mime_part = e_mail_part_ref_mime_part (part);
+ dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
+ if (!dw)
+ goto no_part;
+
+ camel_data_wrapper_decode_to_stream_sync (
+ dw, output_stream, cancellable, NULL);
+
+ g_object_unref (mime_part);
+ } else {
+ if (!mime_type)
+ mime_type = e_mail_part_get_mime_type (part);
+
+ e_mail_formatter_format_as (
+ formatter, &context, part,
+ output_stream, mime_type,
+ cancellable);
+ }
+
+ g_object_unref (part);
+ } else {
+ e_mail_formatter_format_sync (
+ formatter, part_list, output_stream,
+ context.flags, context.mode, cancellable);
+ }
+
+ no_part:
+ g_clear_object (&output_stream);
+ g_clear_object (&context.part_list);
+
+ if (byte_array->data == NULL) {
+ gchar *data;
+
+ data = g_strdup_printf (
+ "<p align='center'>%s</p>",
+ _("The message has no text content."));
+ g_byte_array_append (
+ byte_array, (guint8 *) data, strlen (data));
+ g_free (data);
+ }
+
+ stream = g_memory_input_stream_new_from_bytes (
+ g_byte_array_free_to_bytes (byte_array));
+
+ webkit_uri_scheme_request_finish (request, stream, -1, "text/html");
+
+ g_object_unref (stream);
+
+ if (query)
+ g_hash_table_destroy (query);
+
+ if (soup_uri)
+ soup_uri_free (soup_uri);
+
+ g_task_return_boolean (task, TRUE);
+}
+
+static GInputStream *
+get_empty_image_stream (void)
+{
+ GdkPixbuf *pixbuf;
+ gchar *buffer;
+ gsize length;
+
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
+ gdk_pixbuf_fill (pixbuf, 0x00000000); /* transparent black */
+ gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &length, "png", NULL, NULL);
+ g_object_unref (pixbuf);
+
+ return g_memory_input_stream_new_from_data (buffer, length, g_free);
+}
+
+static void
+mail_display_process_contact_photo_uri_scheme_request (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EMailBackend *mail_backend;
+ EMailSession *mail_session;
+ EPhotoCache *photo_cache;
+ CamelInternetAddress *cia;
+ GInputStream *stream = NULL;
+ const gchar *uri;
+ const gchar *email_address;
+ const gchar *escaped_string;
+ gchar *unescaped_string;
+ GError *error = NULL;
+ SoupURI *soup_uri;
+ GHashTable *uri_query;
+ WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
+
+ /* XXX Is this really the only way to obtain
+ * the mail session instance from here? */
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+ mail_backend = E_MAIL_BACKEND (shell_backend);
+ mail_session = e_mail_backend_get_session (mail_backend);
+
+ photo_cache = e_mail_ui_session_get_photo_cache (
+ E_MAIL_UI_SESSION (mail_session));
+
+ uri = webkit_uri_scheme_request_get_uri (request);
+
+ soup_uri = soup_uri_new (uri);
+ if (!soup_uri || !soup_uri->query)
+ goto exit;
+
+ uri_query = soup_form_decode (soup_uri->query);
+ escaped_string = g_hash_table_lookup (uri_query, "mailaddr");
+ if (escaped_string == NULL || *escaped_string == '\0')
+ goto exit;
+
+ cia = camel_internet_address_new ();
+
+ unescaped_string = g_uri_unescape_string (escaped_string, NULL);
+ camel_address_decode (CAMEL_ADDRESS (cia), unescaped_string);
+ g_free (unescaped_string);
+
+ if (camel_internet_address_get (cia, 0, NULL, &email_address))
+ e_photo_cache_get_photo_sync (
+ photo_cache, email_address,
+ cancellable, &stream, &error);
+
+ g_object_unref (cia);
+
+ /* Ignore cancellations. */
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_clear_error (&error);
+ } else if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_clear_error (&error);
+ }
+
+exit:
+ if (!stream)
+ stream = get_empty_image_stream ();
+
+ webkit_uri_scheme_request_finish (request, stream, -1, "image/*");
+
+ g_object_unref (request);
+ g_object_unref (stream);
+
+ if (uri_query)
+ g_hash_table_destroy (uri_query);
+
+ if (soup_uri)
+ soup_uri_free (soup_uri);
+
+ g_task_return_boolean (task, TRUE);
+}
+
+static void
+mail_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request,
+ EMailDisplay *display)
+{
+ GTask *task;
+ GCancellable *cancellable;
+ const gchar *uri;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ cancellable = g_cancellable_new ();
+
+ uri = webkit_uri_scheme_request_get_uri (request);
+
+ task = g_task_new (
+ display, cancellable,
+ (GAsyncReadyCallback) mail_display_process_uri_scheme_finished_cb,
+ request);
+
+ g_task_set_task_data (task, g_object_ref (request), NULL);
+
+ if (g_ascii_strncasecmp (uri, "mail://contact-photo", 20) == 0)
+ g_task_run_in_thread (task, mail_display_process_contact_photo_uri_scheme_request);
+ else
+ g_task_run_in_thread (task, mail_display_process_mail_uri_scheme_request);
+
+ g_object_unref (task);
+ g_object_unref (cancellable);
+}
+
+static void
+mail_display_update_fonts (EMailDisplay *display)
+{
+ e_web_view_update_fonts (E_WEB_VIEW (display));
+}
+
+static void
e_mail_display_init (EMailDisplay *display)
{
GtkUIManager *ui_manager;
- const gchar *user_cache_dir;
- WebKitWebSettings *settings;
- WebKitWebFrame *main_frame;
GtkActionGroup *actions;
display->priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
@@ -1625,26 +2358,21 @@ e_mail_display_init (EMailDisplay *display)
display->priv->force_image_load = FALSE;
display->priv->scheduled_reload = 0;
- webkit_web_view_set_full_content_zoom (WEBKIT_WEB_VIEW (display), TRUE);
-
- settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (display));
- g_object_set (settings, "enable-frame-flattening", TRUE, NULL);
-
g_signal_connect (
- display, "navigation-policy-decision-requested",
- G_CALLBACK (mail_display_link_clicked), NULL);
+ display, "decide-policy",
+ G_CALLBACK (decide_policy_cb), NULL);
+#if 0
g_signal_connect (
display, "resource-request-starting",
G_CALLBACK (mail_display_resource_requested), NULL);
+#endif
g_signal_connect (
display, "process-mailto",
G_CALLBACK (mail_display_process_mailto), NULL);
+#if 0
g_signal_connect (
display, "create-plugin-widget",
G_CALLBACK (mail_display_plugin_widget_requested), NULL);
- g_signal_connect (
- display, "frame-created",
- G_CALLBACK (mail_display_frame_created), NULL);
e_signal_connect_notify (
display, "notify::uri",
G_CALLBACK (mail_display_uri_changed), NULL);
@@ -1657,7 +2385,7 @@ e_mail_display_init (EMailDisplay *display)
g_signal_connect_after (
display, "drag-data-get",
G_CALLBACK (mail_display_drag_data_get), display);
-
+#endif
display->priv->settings = e_util_ref_settings ("org.gnome.evolution.mail");
g_signal_connect_swapped (
display->priv->settings , "changed::monospace-font",
@@ -1673,7 +2401,10 @@ e_mail_display_init (EMailDisplay *display)
main_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (display));
e_signal_connect_notify (
- main_frame, "notify::load-status",
+ main_frame, "load-changed",
+ G_CALLBACK (setup_dom_bindings), NULL);
+ e_signal_connect_notify (
+ main_frame, "load-changed",
G_CALLBACK (mail_parts_bind_dom), NULL);
actions = e_web_view_get_action_group (E_WEB_VIEW (display), "mailto");
@@ -1683,25 +2414,18 @@ e_mail_display_init (EMailDisplay *display)
ui_manager = e_web_view_get_ui_manager (E_WEB_VIEW (display));
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);
- e_web_view_install_request_handler (
- E_WEB_VIEW (display), E_TYPE_MAIL_REQUEST);
- e_web_view_install_request_handler (
- E_WEB_VIEW (display), E_TYPE_HTTP_REQUEST);
- e_web_view_install_request_handler (
- E_WEB_VIEW (display), E_TYPE_FILE_REQUEST);
- e_web_view_install_request_handler (
- E_WEB_VIEW (display), E_TYPE_STOCK_REQUEST);
-
- if (emd_global_http_cache == NULL) {
- user_cache_dir = e_get_user_cache_dir ();
- emd_global_http_cache = camel_data_cache_new (user_cache_dir, NULL);
-
- /* cache expiry - 2 hour access, 1 day max */
- camel_data_cache_set_expire_age (
- emd_global_http_cache, 24 * 60 * 60);
- camel_data_cache_set_expire_access (
- emd_global_http_cache, 2 * 60 * 60);
- }
+ e_web_view_register_uri_scheme (
+ E_WEB_VIEW (display), EVO_HTTP_URI_SCHEME,
+ mail_http_uri_scheme_appeared_cb, display);
+ e_web_view_register_uri_scheme (
+ E_WEB_VIEW (display), EVO_HTTPS_URI_SCHEME,
+ mail_http_uri_scheme_appeared_cb, display);
+ e_web_view_register_uri_scheme (
+ E_WEB_VIEW (display), CID_URI_SCHEME,
+ mail_cid_uri_scheme_appeared_cb, display);
+ e_web_view_register_uri_scheme (
+ E_WEB_VIEW (display), MAIL_URI_SCHEME,
+ mail_mail_uri_scheme_appeared_cb, display);
}
static void
@@ -1919,7 +2643,7 @@ e_mail_display_load (EMailDisplay *display,
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
- display->priv->force_image_load = FALSE;
+ e_mail_display_set_force_load_images (display, FALSE);
part_list = display->priv->part_list;
if (part_list == NULL) {
@@ -2080,84 +2804,43 @@ e_mail_display_set_status (EMailDisplay *display,
g_free (str);
}
-static gchar *
-mail_display_get_frame_selection_text (WebKitDOMElement *iframe)
-{
- WebKitDOMDocument *document;
- WebKitDOMDOMWindow *window;
- WebKitDOMDOMSelection *selection;
- WebKitDOMNodeList *frames;
- gulong ii, length;
-
- document = webkit_dom_html_iframe_element_get_content_document (
- WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe));
- window = webkit_dom_document_get_default_view (document);
- selection = webkit_dom_dom_window_get_selection (window);
- if (selection && (webkit_dom_dom_selection_get_range_count (selection) > 0)) {
- WebKitDOMRange *range;
-
- range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
- if (range != NULL)
- return webkit_dom_range_to_string (range, NULL);
- }
-
- 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++) {
- WebKitDOMNode *node;
- gchar *text;
-
- node = webkit_dom_node_list_item (frames, ii);
-
- text = mail_display_get_frame_selection_text (
- WEBKIT_DOM_ELEMENT (node));
-
- if (text != NULL) {
- g_object_unref (frames);
- return text;
- }
- }
-
- g_object_unref (frames);
-
- return NULL;
-}
-
-gchar *
-e_mail_display_get_selection_plain_text (EMailDisplay *display)
+const gchar *
+e_mail_display_get_selection_plain_text_sync (EMailDisplay *display,
+ GCancellable *cancellable,
+ GError **error)
{
- WebKitDOMDocument *document;
- WebKitDOMNodeList *frames;
- gulong ii, length;
-
- g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
-
- if (!webkit_web_view_has_selection (WEBKIT_WEB_VIEW (display)))
- return NULL;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (display));
- 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++) {
- gchar *text;
- WebKitDOMNode *node;
-
- node = webkit_dom_node_list_item (frames, ii);
-
- text = mail_display_get_frame_selection_text (
- WEBKIT_DOM_ELEMENT (node));
-
- if (text != NULL) {
- g_object_unref (frames);
- return text;
+ GDBusProxy *web_extension;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+/* FIXME XXX
+ if (!webkit_web_view_has_selection (WEBKIT_WEB_VIEW (display)))
+ return NULL;
+*/
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
+ if (web_extension) {
+ GVariant *result;
+ const gchar *text_content = NULL;
+
+ result = g_dbus_proxy_call_sync (
+ web_extension,
+ "GetDocumentContentText",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (display))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ error);
+
+ if (result) {
+ g_variant_get (result, "(&s)", &text_content);
+ g_variant_unref (result);
+ return text_content;
}
}
- g_object_unref (frames);
-
- return NULL;
+ return NULL;
}
void
@@ -2165,7 +2848,7 @@ e_mail_display_load_images (EMailDisplay *display)
{
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
- display->priv->force_image_load = TRUE;
+ e_mail_display_set_force_load_images (display, TRUE);
e_web_view_reload (E_WEB_VIEW (display));
}
@@ -2173,8 +2856,29 @@ void
e_mail_display_set_force_load_images (EMailDisplay *display,
gboolean force_load_images)
{
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- display->priv->force_image_load = force_load_images;
+ GDBusProxy *web_extension;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
+ if (web_extension) {
+ g_dbus_connection_call (
+ g_dbus_proxy_get_connection (web_extension),
+ g_dbus_proxy_get_name (web_extension),
+ EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+ "org.freedesktop.DBus.Properties",
+ "Set",
+ g_variant_new (
+ "(ssv)",
+ EVOLUTION_WEB_EXTENSION_INTERFACE,
+ "ForceImageLoad",
+ g_variant_new_boolean (force_load_images)),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+ }
}
diff --git a/mail/e-mail-display.h b/mail/e-mail-display.h
index 25fd338..7deefd5 100644
--- a/mail/e-mail-display.h
+++ b/mail/e-mail-display.h
@@ -88,8 +88,10 @@ GtkAction * e_mail_display_get_action (EMailDisplay *display,
const gchar *action_name);
void e_mail_display_set_status (EMailDisplay *display,
const gchar *status);
-gchar * e_mail_display_get_selection_plain_text
- (EMailDisplay *display);
+const gchar * e_mail_display_get_selection_plain_text_sync
+ (EMailDisplay *display,
+ GCancellable *cancellable,
+ GError **error);
void e_mail_display_load_images (EMailDisplay *display);
void e_mail_display_set_force_load_images
(EMailDisplay *display,
diff --git a/mail/e-mail-printer.c b/mail/e-mail-printer.c
index 3d93196..dd29a19 100644
--- a/mail/e-mail-printer.c
+++ b/mail/e-mail-printer.c
@@ -23,8 +23,6 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#include <webkit/webkitdom.h>
-
#include "e-util/e-util.h"
#include "em-format/e-mail-formatter-print.h"
@@ -192,7 +190,7 @@ mail_printer_print_timeout_cb (gpointer user_data)
GtkPrintOperation *print_operation;
GtkPrintOperationAction print_action;
EMailPrinter *printer;
- WebKitWebFrame *web_frame;
+// WebKitWebFrame *web_frame;
gulong create_custom_widget_handler_id;
gulong custom_widget_apply_handler_id;
gulong draw_page_handler_id;
@@ -240,12 +238,12 @@ mail_printer_print_timeout_cb (gpointer user_data)
print_operation, "draw-page",
G_CALLBACK (mail_printer_draw_footer_cb),
async_context->cancellable);
-
+/*
web_frame = webkit_web_view_get_main_frame (async_context->web_view);
async_context->print_result = webkit_web_frame_print_full (
web_frame, print_operation, print_action, &error);
-
+*/
/* Sanity check. */
switch (async_context->print_result) {
case GTK_PRINT_OPERATION_RESULT_ERROR:
@@ -294,18 +292,16 @@ exit:
}
static void
-mail_printer_load_status_cb (WebKitWebView *web_view,
- GParamSpec *pspec,
- GSimpleAsyncResult *simple)
+mail_printer_load_changed_cb (WebKitWebView *web_view,
+ WebKitLoadEvent load_event,
+ GSimpleAsyncResult *simple)
{
AsyncContext *async_context;
- WebKitLoadStatus load_status;
GCancellable *cancellable;
GError *error = NULL;
/* Note: we disregard WEBKIT_LOAD_FAILED and print what we can. */
- load_status = webkit_web_view_get_load_status (web_view);
- if (load_status != WEBKIT_LOAD_FINISHED)
+ if (load_event != WEBKIT_LOAD_FINISHED)
return;
/* Signal handlers are holding the only GSimpleAsyncResult
@@ -352,7 +348,7 @@ mail_printer_new_web_view (const gchar *charset,
const gchar *default_charset)
{
WebKitWebView *web_view;
- WebKitWebSettings *web_settings;
+ WebKitSettings *web_settings;
EMailFormatter *formatter;
web_view = g_object_new (
@@ -563,8 +559,8 @@ e_mail_printer_print (EMailPrinter *printer,
async_context->web_view = g_object_ref_sink (web_view);
handler_id = g_signal_connect_data (
- web_view, "notify::load-status",
- G_CALLBACK (mail_printer_load_status_cb),
+ web_view, "load-changed",
+ G_CALLBACK (mail_printer_load_changed_cb),
g_object_ref (simple),
(GClosureNotify) g_object_unref, 0);
async_context->load_status_handler_id = handler_id;
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
index e8e6f80..49f6ec4 100644
--- a/mail/e-mail-reader-utils.c
+++ b/mail/e-mail-reader-utils.c
@@ -2040,7 +2040,7 @@ e_mail_reader_reply_to_message (EMailReader *reader,
EWebView *web_view;
struct _camel_header_raw *header;
const gchar *uid;
- gchar *selection = NULL;
+ const gchar *selection;
gint length;
gchar *mail_uri;
CamelObjectBag *registry;
@@ -2141,7 +2141,7 @@ e_mail_reader_reply_to_message (EMailReader *reader,
if (!e_web_view_is_selection_active (web_view))
goto whole_message;
- selection = e_web_view_get_selection_html (web_view);
+ selection = e_web_view_get_selection_content_html_sync (web_view, NULL, NULL);
if (selection == NULL || *selection == '\0')
goto whole_message;
@@ -2209,8 +2209,6 @@ e_mail_reader_reply_to_message (EMailReader *reader,
g_object_unref (new_message);
- g_free (selection);
-
goto exit;
whole_message:
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index d86bf44..c35af89 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -1890,6 +1890,7 @@ action_mail_zoom_in_cb (GtkAction *action,
EMailReader *reader)
{
EMailDisplay *display;
+ gdouble zoom_level;
display = e_mail_reader_get_mail_display (reader);
@@ -1901,6 +1902,7 @@ action_mail_zoom_out_cb (GtkAction *action,
EMailReader *reader)
{
EMailDisplay *display;
+ gdouble zoom_level;
display = e_mail_reader_get_mail_display (reader);
@@ -2638,33 +2640,21 @@ mail_reader_key_press_event_cb (EMailReader *reader,
const gchar *action_name;
if (!gtk_widget_has_focus (GTK_WIDGET (reader))) {
- WebKitWebFrame *frame;
- WebKitDOMDocument *dom;
- WebKitDOMElement *element;
EMailDisplay *display;
- gchar *name = NULL;
+ GDBusProxy *web_extension;
display = e_mail_reader_get_mail_display (reader);
- frame = webkit_web_view_get_focused_frame (WEBKIT_WEB_VIEW (display));
-
- if (frame != NULL) {
- dom = webkit_web_frame_get_dom_document (frame);
- /* intentionally used "static_cast" */
- element = webkit_dom_html_document_get_active_element (WEBKIT_DOM_HTML_DOCUMENT
(dom));
-
- if (element != NULL)
- name = webkit_dom_node_get_node_name (WEBKIT_DOM_NODE (element));
-
- /* If INPUT or TEXTAREA has focus,
- * then any key press should go there. */
- if (name != NULL &&
- (g_ascii_strcasecmp (name, "INPUT") == 0 ||
- g_ascii_strcasecmp (name, "TEXTAREA") == 0)) {
- g_free (name);
- return FALSE;
- }
- g_free (name);
- }
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
+ if (web_extension) {
+ GVariant *result;
+
+ result = g_dbus_proxy_get_cached_property (web_extension, "NeedInput");
+ if (result) {
+ gboolean need_input = g_variant_get_boolean (result);
+ g_variant_unref (result);
+
+ if (need_input)
+ return FALSE;
}
if ((event->state & GDK_CONTROL_MASK) != 0)
diff --git a/mail/e-mail-request.c b/mail/e-mail-request.c
index 898a3e5..f11b3be 100644
--- a/mail/e-mail-request.c
+++ b/mail/e-mail-request.c
@@ -24,7 +24,7 @@
#include <libsoup/soup-requester.h>
#include <libsoup/soup-request-http.h>
-#include <webkit/webkit.h>
+#include <webkit2/webkit2.h>
#include <glib/gi18n.h>
#include <camel/camel.h>
diff --git a/modules/itip-formatter/Makefile.am b/modules/itip-formatter/Makefile.am
index 2e1168b..a49cea6 100644
--- a/modules/itip-formatter/Makefile.am
+++ b/modules/itip-formatter/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = plugin
+SUBDIRS = plugin web-extension
@EVO_PLUGIN_RULE@
@@ -27,7 +27,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-formatter-itip.c b/modules/itip-formatter/e-mail-formatter-itip.c
index 1439cf1..581e4a3 100644
--- a/modules/itip-formatter/e-mail-formatter-itip.c
+++ b/modules/itip-formatter/e-mail-formatter-itip.c
@@ -69,7 +69,7 @@ emfe_itip_format (EMailFormatterExtension *extension,
buffer = g_string_sized_new (1024);
itip_part->view = itip_view_new (
- itip_part, itip_part->client_cache);
+ itip_part, itip_part->client_cache, "", 0);
itip_view_init_view (itip_part->view);
itip_view_write_for_printing (itip_part->view, buffer);
diff --git a/modules/itip-formatter/e-mail-part-itip.c b/modules/itip-formatter/e-mail-part-itip.c
index bcc48db..b7e9113 100644
--- a/modules/itip-formatter/e-mail-part-itip.c
+++ b/modules/itip-formatter/e-mail-part-itip.c
@@ -76,45 +76,26 @@ mail_part_itip_finalize (GObject *object)
static void
mail_part_itip_bind_dom_element (EMailPart *part,
- WebKitDOMElement *element)
+ GDBusProxy *evolution_web_extension,
+ guint64 page_id,
+ 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 length;
-
- nodes = webkit_dom_element_get_elements_by_tag_name (
- element, "iframe");
- length = webkit_dom_node_list_get_length (nodes);
- if (length > 0)
- element = WEBKIT_DOM_ELEMENT (
- webkit_dom_node_list_item (nodes, 0));
-
- g_object_unref (nodes);
- }
+ /* FIXME XXX WK2 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));
-
- view = itip_view_new (pitip, pitip->client_cache);
- 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));
-
- itip_view_init_view (view);
- g_string_free (buffer, TRUE);
+#endif
+ itip_view_new (pitip, pitip->client_cache, element_id, page_id);
}
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 395eabb..6b16d4e 100644
--- a/modules/itip-formatter/itip-view.c
+++ b/modules/itip-formatter/itip-view.c
@@ -25,7 +25,6 @@
#include <string.h>
#include <glib/gi18n.h>
-#include <webkit/webkitdom.h>
#include <libedataserver/libedataserver.h>
#include <shell/e-shell.h>
@@ -42,6 +41,10 @@
#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)
#define MEETING_ICON "stock_new-meeting"
@@ -107,55 +110,20 @@ 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;
+
+ const gchar *element_id;
+ guint64 page_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,
@@ -614,6 +582,199 @@ set_journal_sender_text (ItipView *view)
}
static void
+enable_button (ItipView *view,
+ const gchar *button_id,
+ gboolean enable)
+{
+ if (!view->priv->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "EnableButton",
+ g_variant_new ("(sb)", button_id, enable),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static void
+show_button (ItipView *view,
+ const gchar *id)
+{
+ if (!view->priv->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "ShowButton",
+ g_variant_new ("(s)", id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static void
+hide_element (ItipView *view,
+ const gchar *element_id,
+ gboolean hide)
+{
+ if (!view->priv->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "HideElement",
+ g_variant_new ("(sb)", element_id, hide),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+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,
+ "ElementIsHidden",
+ 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)
+{
+ if (!view->priv->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "ElementSetInnerHTML",
+ g_variant_new ("(ss)", element_id, inner_html),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static void
+input_set_checked (ItipView *view,
+ const gchar *input_id,
+ gboolean checked)
+{
+ if (!view->priv->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "InputSetChecked",
+ g_variant_new ("(sb)", input_id, checked),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+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)
+{
+ g_return_if_fail (ITIP_IS_VIEW (view));
+
+ if (!view->priv->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "ShowCheckbox",
+ g_variant_new ("(sbb)", id, show, update_second),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static void
+set_area_text (ItipView *view,
+ const gchar *id,
+ const gchar *text)
+{
+ g_return_if_fail (ITIP_IS_VIEW (view));
+
+ if (!view->priv->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "SetAreaText",
+ g_variant_new ("(ss)", id, text ? text : ""),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static void
set_sender_text (ItipView *view)
{
ItipViewPrivate *priv;
@@ -637,21 +798,14 @@ 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;
gchar buffer[256];
time_t now;
struct tm *now_tm;
@@ -696,124 +850,92 @@ 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);
- }
-
- 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);
-
- 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 (!priv->web_extension)
+ return;
- 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 (priv->start_header && priv->start_label) {
+ g_dbus_proxy_call (
+ 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,
+ NULL);
+ } else
+ hide_element (view, TABLE_ROW_START_DATE, TRUE);
+
+ if (priv->end_header && priv->end_label) {
+ g_dbus_proxy_call (
+ 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,
+ NULL);
+ } 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 (button_value);
- response = atoi (responseStr);
-
- 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)
+ g_variant_get (parameters, "(&s)", &button_value);
- 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;
-
- id = webkit_dom_element_get_id (WEBKIT_DOM_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;
@@ -826,6 +948,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)
@@ -889,19 +1026,8 @@ append_info_item_row (ItipView *view,
const gchar *table_id,
ItipViewInfoItem *item)
{
- WebKitDOMElement *table;
- WebKitDOMHTMLElement *row, *cell;
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_element_set_id (WEBKIT_DOM_ELEMENT (row), id);
- g_free (id);
+ gchar *row_id;
switch (item->type) {
case ITIP_VIEW_INFO_ITEM_TYPE_INFO:
@@ -921,31 +1047,27 @@ append_info_item_row (ItipView *view,
icon_name = NULL;
}
- 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 (
- view->priv->dom_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);
+ row_id = g_strdup_printf ("%s_row_%d", table_id, item->id);
+
+ if (!view->priv->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ 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,
+ NULL);
- 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));
}
@@ -955,18 +1077,23 @@ remove_info_item_row (ItipView *view,
const gchar *table_id,
guint id)
{
- WebKitDOMElement *row;
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;
+
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "RemoveElement",
+ g_variant_new ("(s)", row_id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+
+ g_free (row_id);
d (printf ("Removed row %s_row_%d\n", table_id, id));
}
@@ -1054,106 +1181,60 @@ static void
itip_view_rebuild_source_list (ItipView *view)
{
ESourceRegistry *registry;
- WebKitDOMElement *select;
GList *list, *link;
const gchar *extension_name;
- GHashTable *groups;
d (printf ("Assigning a new source list!\n"));
- if (!view->priv->dom_document)
+ 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)),
- NULL);
- }
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "ElementRemoveChildNodes",
+ g_variant_new ("(s)", SELECT_ESOURCE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
if (extension_name == NULL)
return;
list = e_source_registry_list_enabled (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);
-
- 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);
- }
+ g_dbus_proxy_call (
+ 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,
- 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_cb (view);
}
static void
@@ -1271,8 +1352,35 @@ itip_view_dispose (GObject *object)
priv->source_removed_handler_id = 0;
}
+ 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->client_cache);
g_clear_object (&priv->registry);
+ g_clear_object (&priv->web_extension);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (itip_view_parent_class)->dispose (object);
@@ -1288,7 +1396,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);
@@ -1631,130 +1738,149 @@ 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;
-
- doc = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
- view->priv->dom_document = g_object_ref (doc);
-
- 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);
- }
-
- 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 (!view->priv->web_extension)
+ return;
- 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);
- }
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "SaveDocumentFromElement",
+ g_variant_new ("(ts)", view->priv->page_id, element_id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ 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);
- }
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "CreateDOMBindings",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
- 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);
+ }
+
+ 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_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_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);
- 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_TENTATIVE_ALL);
- if (el) {
- webkit_dom_event_target_add_event_listener (
- WEBKIT_DOM_EVENT_TARGET (el), "click",
- G_CALLBACK (button_clicked_cb), FALSE, view);
- }
+ itip_view_create_dom_bindings (view, view->priv->element_id);
- 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);
- }
+ itip_view_init_view (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_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_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
+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_ATTENDEE_STATUS);
- 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)
+{
+ view->priv->web_extension_watch_name_id =
+ g_bus_watch_name (
+ G_BUS_TYPE_SESSION,
+ MODULE_ITIP_FORMATTER_WEB_EXTENSION_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);
- }
+GDBusProxy *
+itip_view_get_web_extension_proxy (ItipView *view)
+{
+ g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
- 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);
- }
+ return view->priv->web_extension;
}
static void
itip_view_init (ItipView *view)
{
view->priv = ITIP_VIEW_GET_PRIVATE (view);
-
}
ItipView *
itip_view_new (EMailPartItip *puri,
- EClientCache *client_cache)
+ EClientCache *client_cache,
+ const gchar *element_id,
+ guint64 page_id)
{
ItipView *view;
@@ -1765,46 +1891,35 @@ itip_view_new (EMailPartItip *puri,
"client-cache", client_cache,
NULL));
view->priv->itip_part = puri;
+ view->priv->element_id = element_id;
+ view->priv->page_id = page_id;
+ itip_view_watch_web_extension (view);
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;
-
g_return_if_fail (ITIP_IS_VIEW (view));
view->priv->mode = mode;
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);
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "ElementHideChildNodes",
+ g_variant_new ("(s)", TABLE_ROW_BUTTONS),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
view->priv->is_recur_set = itip_view_get_recur_check_state (view);
@@ -1870,12 +1985,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:");
@@ -1898,10 +2010,17 @@ 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);
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "ElementSetAccessKey",
+ g_variant_new ("(ss)", TABLE_ROW_ESCB_LABEL, access_key),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+
+ set_inner_html (view, TABLE_ROW_ESCB_LABEL, html_label);
g_free (html_label);
@@ -2055,8 +2174,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)
@@ -2064,19 +2181,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 *
@@ -2091,8 +2196,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)
@@ -2100,19 +2203,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 *
@@ -2127,8 +2218,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)
@@ -2136,19 +2225,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 *
@@ -2163,8 +2240,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)
@@ -2172,19 +2247,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 *
@@ -2199,8 +2262,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)
@@ -2208,18 +2269,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 *
@@ -2326,7 +2380,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);
@@ -2376,8 +2430,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;
}
@@ -2397,8 +2450,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);
@@ -2428,7 +2480,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);
@@ -2514,105 +2566,123 @@ void
itip_view_set_source (ItipView *view,
ESource *source)
{
- WebKitDOMElement *select;
- WebKitDOMElement *row;
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)
+ if (!source)
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);
-
- 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);
+ if (!view->priv->web_extension)
+ return;
- g_free (value);
- break;
- }
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "EnableSelect",
+ g_variant_new ("(sb)", SELECT_ESOURCE, TRUE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
- g_free (value);
- }
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "SelectSetSelected",
+ g_variant_new (
+ "(ss)",
+ SELECT_ESOURCE, e_source_get_uid (source)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
- source_changed_cb (select, NULL, view);
+ source_changed (view);
}
ESource *
itip_view_ref_source (ItipView *view)
{
- WebKitDOMElement *select;
- gchar *uid;
ESource *source;
- gboolean disable = FALSE;
+ gboolean disable = FALSE, enabled = 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) {
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "EnableSelect",
+ g_variant_new ("(sb)", SELECT_ESOURCE, TRUE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+
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) {
+ const gchar *uid;
- g_free (uid);
+ g_variant_get (result, "(&s)", &uid);
+ source = e_source_registry_ref_source (view->priv->registry, uid);
+ g_variant_unref (result);
+ }
if (disable) {
- webkit_dom_html_select_element_set_disabled (
- WEBKIT_DOM_HTML_SELECT_ELEMENT (select), TRUE);
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "EnableSelect",
+ g_variant_new ("(sb)", SELECT_ESOURCE, FALSE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
}
return source;
@@ -2622,201 +2692,139 @@ void
itip_view_set_rsvp (ItipView *view,
gboolean rsvp)
{
- WebKitDOMElement *el;
-
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);
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "EnableTextArea",
+ g_variant_new ("(sb)", TEXTAREA_RSVP_COMMENT, !rsvp),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
}
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;
-
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));
-
if (comment) {
- webkit_dom_html_text_area_element_set_value (
- WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), comment);
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "TextAreaSetValue",
+ g_variant_new (
+ "(ss)", TEXTAREA_RSVP_COMMENT, comment),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
}
}
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 (element_is_hidden (view, TEXTAREA_RSVP_COMMENT))
+ return NULL;
- if (webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el))) {
- 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;
+
+ g_variant_get (result, "(&s)", &value);
+ 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
@@ -2832,64 +2840,24 @@ void
itip_view_set_buttons_sensitive (ItipView *view,
gboolean sensitive)
{
- WebKitDOMElement *el, *cell;
-
g_return_if_fail (ITIP_IS_VIEW (view));
d (printf ("Settings buttons %s\n", sensitive ? "sensitive" : "insensitive"));
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);
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "SetButtonsSensitive",
+ g_variant_new ("(b)", sensitive),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
}
gboolean
@@ -2903,193 +2871,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
@@ -3097,7 +2941,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));
@@ -3121,34 +2964,26 @@ 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;
-
- show_button (view, BUTTON_SAVE);
+ show_button (view, BUTTON_SAVE);
+ enable_button (view, BUTTON_SAVE, TRUE);
- 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);
+ g_dbus_proxy_call (
+ view->priv->web_extension,
+ "BindSaveButton",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
}
}
@@ -3574,14 +3409,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);
}
}
@@ -4550,7 +4378,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;
@@ -4609,8 +4437,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);
@@ -5021,14 +4847,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);
@@ -6262,13 +6081,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 0ffd96f..97ecdfd 100644
--- a/modules/itip-formatter/itip-view.h
+++ b/modules/itip-formatter/itip-view.h
@@ -27,7 +27,6 @@
#include <unistd.h>
#include <gtk/gtk.h>
-#include <webkit/webkitdom.h>
#include <libecal/libecal.h>
@@ -110,14 +109,16 @@ struct _ItipViewClass {
GType itip_view_get_type (void);
ItipView * itip_view_new (struct _EMailPartItip *puri,
- EClientCache *client_cache);
+ EClientCache *client_cache,
+ const gchar *element_id,
+ guint64 page_id);
void itip_view_init_view (ItipView *view);
void itip_view_write (EMailFormatter *formatter,
GString *buffer);
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);
@@ -217,7 +218,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);
@@ -246,6 +247,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
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..0f71a7a
--- /dev/null
+++ b/modules/itip-formatter/module-itip-formatter-dom-utils.c
@@ -0,0 +1,723 @@
+/*
+ * 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"
+
+#define WEBKIT_DOM_USE_UNSTABLE_API
+#include <webkitdom/WebKitDOMHTMLElementUnstable.h>
+
+#include "web-extension/module-itip-formatter-web-extension.h"
+#include "itip-view-elements-defines.h"
+
+#include <e-util/e-util.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));
+#if WEBKIT_CHECK_VERSION(2,2,0) /* XXX should really be (2,1,something) */
+ id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (check1));
+#else
+ id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (check1));
+#endif
+
+ 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;
+ gchar *row_id;
+
+ el = webkit_dom_document_get_element_by_id (document, id);
+ webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
+
+ 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);
+ }
+
+ row_id = g_strconcat ("table_row_", id, NULL);
+ el = webkit_dom_document_get_element_by_id (document, row_id);
+ webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show);
+ g_free (row_id);
+}
+
+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);
+
+#if WEBKIT_CHECK_VERSION(2,2,0) /* XXX should really be (2,1,something) */
+ webkit_dom_element_set_id (WEBKIT_DOM_ELEMENT (row), row_id);
+#else
+ webkit_dom_html_element_set_id (row, row_id);
+#endif
+
+ 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..ab62dff
--- /dev/null
+++ b/modules/itip-formatter/web-extension/Makefile.am
@@ -0,0 +1,25 @@
+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
+
+libmoduleitipformatterwebextension_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(WEB_EXTENSIONS_CFLAGS)
+
+libmoduleitipformatterwebextension_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_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..7fc005d
--- /dev/null
+++ b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
@@ -0,0 +1,619 @@
+/*
+ * 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 <e-util/e-dom-utils.h>
+
+#include "../module-itip-formatter-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;
+
+ g_variant_get (parameters, "(&s)", &button_id);
+
+ /* 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;
+
+ g_variant_get (parameters, "(&s)", &element_id);
+ /* 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;
+
+ g_variant_get (parameters, "(&s)", &element_id);
+ /* 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;
+
+ g_variant_get (parameters, "(&s)", &element_id);
+
+ /* 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;
+
+ g_variant_get (parameters, "(&s)", &input_id);
+
+ /* 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;
+
+ g_variant_get (parameters, "(&s)", &element_id);
+
+ /* 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;
+
+ g_variant_get (parameters, "(&s)", &select_id);
+
+ /* 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;
+
+ g_variant_get (parameters, "(&s)", &select_id);
+
+ /* 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;
+
+ g_variant_get (parameters, "(&s)", &area_id);
+
+ /* 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)
+{
+ g_bus_own_name (
+ G_BUS_TYPE_SESSION,
+ MODULE_ITIP_FORMATTER_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ bus_acquired_cb,
+ NULL, NULL,
+ g_object_ref (extension),
+ g_object_unref);
+}
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 */
diff --git a/modules/mail/Makefile.am b/modules/mail/Makefile.am
index 770975e..efb31c9 100644
--- a/modules/mail/Makefile.am
+++ b/modules/mail/Makefile.am
@@ -1,3 +1,5 @@
+SUBDIRS=web-extension
+
module_LTLIBRARIES = module-mail.la
module_mail_la_CPPFLAGS = \
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index bf2d1a3..ff83c9f 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -112,7 +112,8 @@ message_parsed_cb (GObject *source_object,
parts_list = e_mail_parser_parse_finish (parser, res, NULL);
- soup_session = webkit_get_default_session ();
+// soup_session = webkit_get_default_session ();
+ soup_session = NULL;
mails = g_object_get_data (G_OBJECT (soup_session), "mails");
if (!mails) {
mails = g_hash_table_new_full (
diff --git a/modules/mail/e-mail-shell-view-private.c b/modules/mail/e-mail-shell-view-private.c
index 14b0830..0dd73b6 100644
--- a/modules/mail/e-mail-shell-view-private.c
+++ b/modules/mail/e-mail-shell-view-private.c
@@ -26,6 +26,8 @@
#include "e-util/e-util-private.h"
+#include "web-extension/module-mail-web-extension.h"
+
typedef struct _AsyncContext AsyncContext;
struct _AsyncContext {
@@ -250,35 +252,30 @@ mail_shell_view_folder_tree_popup_event_cb (EShellView *shell_view,
}
static gboolean
-mail_shell_view_mail_display_needs_key (EMailDisplay *mail_display,
- gboolean with_input)
+mail_shell_view_mail_display_needs_key (EMailShellView *mail_shell_view,
+ EMailDisplay *mail_display)
{
- gboolean needs_key = FALSE;
-
if (gtk_widget_has_focus (GTK_WIDGET (mail_display))) {
- WebKitWebFrame *frame;
- WebKitDOMDocument *dom;
- WebKitDOMElement *element;
- gchar *name = NULL;
+ GDBusProxy *web_extension;
- frame = webkit_web_view_get_focused_frame (WEBKIT_WEB_VIEW (mail_display));
- if (!frame)
- return FALSE;
- dom = webkit_web_frame_get_dom_document (frame);
- element = webkit_dom_html_document_get_active_element (WEBKIT_DOM_HTML_DOCUMENT (dom));
+ /* Intentionally use Evolution Web Extension */
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (mail_display));
+ if (web_extension) {
+ GVariant *result;
- if (element)
- name = webkit_dom_node_get_node_name (WEBKIT_DOM_NODE (element));
+ result = g_dbus_proxy_get_cached_property (web_extension, "NeedInput");
+ if (result) {
+ gboolean need_input;
- /* if INPUT or TEXTAREA has focus, then any key press should go there */
- if (name && ((with_input && g_ascii_strcasecmp (name, "INPUT") == 0) || g_ascii_strcasecmp
(name, "TEXTAREA") == 0)) {
- needs_key = TRUE;
- }
+ need_input = g_variant_get_boolean (result);
+ g_variant_unref (result);
- g_free (name);
+ return need_input;
+ }
+ }
}
- return needs_key;
+ return FALSE;
}
static gboolean
@@ -313,42 +310,11 @@ mail_shell_view_key_press_event_cb (EMailShellView *mail_shell_view,
action = ACTION (MAIL_SMART_BACKWARD);
break;
- case GDK_KEY_Home:
- case GDK_KEY_Left:
- case GDK_KEY_Up:
- case GDK_KEY_Right:
- case GDK_KEY_Down:
- case GDK_KEY_Next:
- case GDK_KEY_End:
- case GDK_KEY_Begin:
- /* If Caret mode is enabled don't try to process these keys */
- if (e_web_view_get_caret_mode (E_WEB_VIEW (mail_display)))
- return FALSE;
- case GDK_KEY_Prior:
- if (!mail_shell_view_mail_display_needs_key (mail_display, FALSE) &&
- webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (mail_display)) !=
- webkit_web_view_get_focused_frame (WEBKIT_WEB_VIEW (mail_display))) {
- WebKitDOMDocument *document;
- WebKitDOMDOMWindow *window;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (mail_display));
- window = webkit_dom_document_get_default_view (document);
-
- /* Workaround WebKit bug for key navigation, when inner IFRAME is focused.
- * EMailView's inner IFRAMEs have disabled scrolling, but WebKit doesn't post
- * key navigation events to parent's frame, thus the view doesn't scroll.
- * This is a poor workaround for this issue, the main frame is focused,
- * which has scrolling enabled.
- */
- webkit_dom_dom_window_focus (window);
- }
-
- return FALSE;
default:
return FALSE;
}
- if (mail_shell_view_mail_display_needs_key (mail_display, TRUE))
+ if (mail_shell_view_mail_display_needs_key (mail_shell_view, mail_display))
return FALSE;
gtk_action_activate (action);
@@ -563,12 +529,77 @@ mail_shell_view_search_filter_changed_cb (EMailShellView *mail_shell_view)
e_mail_reader_avoid_next_mark_as_seen (E_MAIL_READER (mail_view));
}
+static void
+web_extension_proxy_created_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ EMailShellView *mail_shell_view)
+{
+ GError *error = NULL;
+
+ mail_shell_view->priv->web_extension = g_dbus_proxy_new_finish (result, &error);
+ if (!mail_shell_view->priv->web_extension) {
+ g_warning ("Error creating web extension proxy: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+web_extension_appeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ EMailShellView *mail_shell_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_MAIL_WEB_EXTENSION_OBJECT_PATH,
+ MODULE_MAIL_WEB_EXTENSION_INTERFACE,
+ NULL,
+ (GAsyncReadyCallback)web_extension_proxy_created_cb,
+ mail_shell_view);
+}
+
+static void
+web_extension_vanished_cb (GDBusConnection *connection,
+ const gchar *name,
+ EMailShellView *mail_shell_view)
+{
+ g_clear_object (&mail_shell_view->priv->web_extension);
+}
+
+static void
+mail_shell_view_watch_web_extension (EMailShellView *mail_shell_view)
+{
+ mail_shell_view->priv->web_extension_watch_name_id =
+ g_bus_watch_name (
+ G_BUS_TYPE_SESSION,
+ MODULE_MAIL_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ (GBusNameAppearedCallback) web_extension_appeared_cb,
+ (GBusNameVanishedCallback) web_extension_vanished_cb,
+ mail_shell_view, NULL);
+}
+
+GDBusProxy *
+e_mail_shell_view_get_web_extension_proxy (EMailShellView *mail_shell_view)
+{
+ g_return_val_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view), NULL);
+
+ return mail_shell_view->priv->web_extension;
+}
+
void
e_mail_shell_view_private_init (EMailShellView *mail_shell_view)
{
e_signal_connect_notify (
mail_shell_view, "notify::view-id",
G_CALLBACK (mail_shell_view_notify_view_id_cb), NULL);
+
+ mail_shell_view_watch_web_extension (mail_shell_view);
}
void
@@ -799,6 +830,12 @@ e_mail_shell_view_private_dispose (EMailShellView *mail_shell_view)
priv->prepare_for_quit_handler_id = 0;
}
+ 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;
+ }
+
+ g_clear_object (&priv->web_extension);
g_clear_object (&priv->mail_shell_backend);
g_clear_object (&priv->mail_shell_content);
g_clear_object (&priv->mail_shell_sidebar);
diff --git a/modules/mail/e-mail-shell-view-private.h b/modules/mail/e-mail-shell-view-private.h
index e42222d..29869f4 100644
--- a/modules/mail/e-mail-shell-view-private.h
+++ b/modules/mail/e-mail-shell-view-private.h
@@ -137,6 +137,9 @@ struct _EMailShellViewPrivate {
GtkToolItem *send_receive_tool_item;
GtkToolItem *send_receive_tool_separator;
+
+ GDBusProxy *web_extension;
+ guint web_extension_watch_name_id;
};
void e_mail_shell_view_private_init
@@ -162,6 +165,8 @@ void e_mail_shell_view_update_sidebar
(EMailShellView *mail_shell_view);
void e_mail_shell_view_update_send_receive_menus
(EMailShellView *mail_shell_view);
+GDBusProxy * e_mail_shell_view_get_web_extension_proxy
+ (EMailShellView *mail_shell_view);
G_END_DECLS
diff --git a/modules/mail/web-extension/Makefile.am b/modules/mail/web-extension/Makefile.am
new file mode 100644
index 0000000..b89d112
--- /dev/null
+++ b/modules/mail/web-extension/Makefile.am
@@ -0,0 +1,23 @@
+webextensions_LTLIBRARIES = libmodulemailwebextension.la
+
+libmodulemailwebextension_la_SOURCES = \
+ module-mail-web-extension.c \
+ module-mail-web-extension.h
+
+libmodulemailwebextension_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(WEB_EXTENSIONS_CFLAGS)
+
+libmodulemailwebextension_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(WEB_EXTENSIONS_LIBS)
+
+libmodulemailwebextension_la_LDFLAGS = \
+ -module -avoid-version -no-undefined
diff --git a/modules/mail/web-extension/module-mail-web-extension.c
b/modules/mail/web-extension/module-mail-web-extension.c
new file mode 100644
index 0000000..a3c9a7e
--- /dev/null
+++ b/modules/mail/web-extension/module-mail-web-extension.c
@@ -0,0 +1,141 @@
+/*
+ * module-mail-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-mail-web-extension.h"
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <webkit2/webkit-web-extension.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.Mail.WebExtension'>"
+" <method name='GetActiveElementName'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='element_name' direction='out'/>"
+" </method>"
+" </interface>"
+"</node>";
+
+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_MAIL_WEB_EXTENSION_INTERFACE) != 0)
+ return;
+
+ if (g_strcmp0 (method_name, "GetActiveElementName") == 0) {
+ gchar *element_name;
+
+ g_variant_get (parameters, "(t)", &page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ element_name = e_dom_utils_get_active_element_name (document);
+
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(s)", element_name));
+
+ g_free (element_name);
+ }
+}
+
+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_MAIL_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)
+{
+ g_bus_own_name (
+ G_BUS_TYPE_SESSION,
+ MODULE_MAIL_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ bus_acquired_cb,
+ NULL, NULL,
+ g_object_ref (extension),
+ g_object_unref);
+}
diff --git a/modules/mail/web-extension/module-mail-web-extension.h
b/modules/mail/web-extension/module-mail-web-extension.h
new file mode 100644
index 0000000..f1fe0a8
--- /dev/null
+++ b/modules/mail/web-extension/module-mail-web-extension.h
@@ -0,0 +1,26 @@
+/*
+ * module-mail-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_MAIL_WEB_EXTENSION_H
+#define MODULE_MAIL_WEB_EXTENSION_H
+
+#define MODULE_MAIL_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.Module.Mail.WebExtension"
+#define MODULE_MAIL_WEB_EXTENSION_OBJECT_PATH "/org/gnome/Evolution/Module/Mail/WebExtension"
+#define MODULE_MAIL_WEB_EXTENSION_INTERFACE "org.gnome.Evolution.Module.Mail.WebExtension"
+
+#endif /* MODULE_MAIL_WEB_EXTENSION_H */
diff --git a/modules/prefer-plain/Makefile.am b/modules/prefer-plain/Makefile.am
index 9b6c8b3..99ec301 100644
--- a/modules/prefer-plain/Makefile.am
+++ b/modules/prefer-plain/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS=plugin
+SUBDIRS=plugin web-extension
module_LTLIBRARIES = module-prefer-plain.la
diff --git a/modules/prefer-plain/e-mail-display-popup-prefer-plain.c
b/modules/prefer-plain/e-mail-display-popup-prefer-plain.c
index c23e5d2..d916e40 100644
--- a/modules/prefer-plain/e-mail-display-popup-prefer-plain.c
+++ b/modules/prefer-plain/e-mail-display-popup-prefer-plain.c
@@ -23,6 +23,8 @@
#include <shell/e-shell-window.h>
#include "mail/e-mail-browser.h"
+#include "web-extension/module-prefer-plain-web-extension.h"
+
#include <libebackend/libebackend.h>
#include <glib/gi18n-lib.h>
@@ -35,12 +37,13 @@ typedef struct _EMailDisplayPopupPreferPlainClass EMailDisplayPopupPreferPlainCl
struct _EMailDisplayPopupPreferPlain {
EExtension parent;
- WebKitDOMDocument *document;
gchar *text_plain_id;
gchar *text_html_id;
GtkActionGroup *action_group;
+ GDBusProxy *web_extension;
+ gint web_extension_watch_name_id;
};
struct _EMailDisplayPopupPreferPlainClass {
@@ -90,20 +93,85 @@ static const gchar *ui_reader =
"</ui>";
static void
-toggle_part (GtkAction *action,
- EMailDisplayPopupExtension *extension)
+web_extension_proxy_created_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ EMailDisplayPopupPreferPlain *pp_extension)
+{
+ GError *error = NULL;
+
+ pp_extension->web_extension = g_dbus_proxy_new_finish (result, &error);
+ if (!pp_extension->web_extension) {
+ g_warning ("Error creating web extension proxy: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+web_extension_appeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ EMailDisplayPopupPreferPlain *pp_extension)
+{
+ 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_PREFER_PLAIN_WEB_EXTENSION_OBJECT_PATH,
+ MODULE_PREFER_PLAIN_WEB_EXTENSION_INTERFACE,
+ NULL,
+ (GAsyncReadyCallback)web_extension_proxy_created_cb,
+ pp_extension);
+}
+
+static void
+web_extension_vanished_cb (GDBusConnection *connection,
+ const gchar *name,
+ EMailDisplayPopupPreferPlain *pp_extension)
+{
+ g_clear_object (&pp_extension->web_extension);
+}
+
+static void
+mail_display_popup_prefer_plain_watch_web_extension (EMailDisplayPopupPreferPlain *pp_extension)
+{
+ pp_extension->web_extension_watch_name_id =
+ g_bus_watch_name (
+ G_BUS_TYPE_SESSION,
+ MODULE_PREFER_PLAIN_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ (GBusNameAppearedCallback) web_extension_appeared_cb,
+ (GBusNameVanishedCallback) web_extension_vanished_cb,
+ pp_extension, NULL);
+}
+
+static void
+toggle_part_get_document_uri_cb (GDBusProxy *web_extension,
+ GAsyncResult *result,
+ EMailDisplayPopupExtension *extension)
{
EMailDisplayPopupPreferPlain *pp_extension = (EMailDisplayPopupPreferPlain *) extension;
- WebKitDOMDocument *doc = pp_extension->document;
- WebKitDOMDOMWindow *window;
- WebKitDOMElement *frame_element;
SoupURI *soup_uri;
GHashTable *query;
gchar *uri;
+ GVariant *result_variant;
- uri = webkit_dom_document_get_document_uri (doc);
- soup_uri = soup_uri_new (uri);
- g_free (uri);
+ result_variant = g_dbus_proxy_call_finish (web_extension, result, NULL);
+ if (result_variant) {
+ const gchar *document_uri;
+
+ g_variant_get (result_variant, "(&s)", &document_uri);
+ soup_uri = soup_uri_new (document_uri);
+ g_variant_unref (result_variant);
+ }
+
+ if (!soup_uri || !soup_uri->query) {
+ if (soup_uri)
+ soup_uri_free (soup_uri);
+ return;
+ }
query = soup_form_decode (soup_uri->query);
g_hash_table_replace (
@@ -123,15 +191,40 @@ toggle_part (GtkAction *action,
uri = soup_uri_to_string (soup_uri, FALSE);
soup_uri_free (soup_uri);
- /* Get frame's window and from the window the actual <iframe> element */
- window = webkit_dom_document_get_default_view (doc);
- frame_element = webkit_dom_dom_window_get_frame_element (window);
- webkit_dom_html_iframe_element_set_src (
- WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame_element), uri);
+ g_dbus_proxy_call (
+ pp_extension->web_extension,
+ "ChangeIFrameSource",
+ g_variant_new ("(s)", uri),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
g_free (uri);
}
+static void
+toggle_part (GtkAction *action,
+ EMailDisplayPopupExtension *extension)
+{
+ EMailDisplayPopupPreferPlain *pp_extension = (EMailDisplayPopupPreferPlain *) extension;
+
+ if (!pp_extension->web_extension)
+ return;
+
+ /* Get URI from saved document */
+ g_dbus_proxy_call (
+ pp_extension->web_extension,
+ "GetDocumentURI",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) toggle_part_get_document_uri_cb,
+ extension);
+}
+
GtkActionEntry entries[] = {
{ "show-plain-text-part",
@@ -217,13 +310,13 @@ create_group (EMailDisplayPopupExtension *extension)
}
static void
-mail_display_popup_prefer_plain_update_actions (EMailDisplayPopupExtension *extension,
- WebKitHitTestResult *context)
+get_document_uri_cb (GDBusProxy *web_extension,
+ GAsyncResult *result,
+ EMailDisplayPopupExtension *extension)
{
EMailDisplay *display;
GtkAction *action;
- WebKitDOMNode *node;
- gchar *uri, *part_id, *pos, *prefix;
+ gchar *part_id, *pos, *prefix;
SoupURI *soup_uri;
GHashTable *query;
EMailPartList *part_list;
@@ -232,31 +325,26 @@ mail_display_popup_prefer_plain_update_actions (EMailDisplayPopupExtension *exte
EMailDisplayPopupPreferPlain *pp_extension;
GQueue queue = G_QUEUE_INIT;
GList *head, *link;
+ GVariant *result_variant;
display = E_MAIL_DISPLAY (e_extension_get_extensible (
E_EXTENSION (extension)));
pp_extension = E_MAIL_DISPLAY_POPUP_PREFER_PLAIN (extension);
- if (!pp_extension->action_group)
- pp_extension->action_group = create_group (extension);
+ result_variant = g_dbus_proxy_call_finish (web_extension, result, NULL);
+ if (result_variant) {
+ const gchar *document_uri;
- g_object_get (context, "inner-node", &node, NULL);
-
- if (!node) {
- gtk_action_group_set_visible (pp_extension->action_group, FALSE);
- return;
+ g_variant_get (result_variant, "(&s)", &document_uri);
+ soup_uri = soup_uri_new (document_uri);
+ g_variant_unref (result_variant);
}
- pp_extension->document = webkit_dom_node_get_owner_document (node);
- uri = webkit_dom_document_get_document_uri (pp_extension->document);
-
- soup_uri = soup_uri_new (uri);
if (!soup_uri || !soup_uri->query) {
gtk_action_group_set_visible (pp_extension->action_group, FALSE);
if (soup_uri)
soup_uri_free (soup_uri);
- g_free (uri);
return;
}
@@ -264,28 +352,19 @@ mail_display_popup_prefer_plain_update_actions (EMailDisplayPopupExtension *exte
part_id = g_hash_table_lookup (query, "part_id");
if (part_id == NULL) {
gtk_action_group_set_visible (pp_extension->action_group, FALSE);
- g_hash_table_destroy (query);
- soup_uri_free (soup_uri);
- g_free (uri);
- return;
+ goto out;
}
pos = strstr (part_id, ".alternative-prefer-plain.");
if (!pos) {
gtk_action_group_set_visible (pp_extension->action_group, FALSE);
- g_hash_table_destroy (query);
- soup_uri_free (soup_uri);
- g_free (uri);
- return;
+ goto out;
}
/* Don't display the actions on any other than text/plain or text/html parts */
if (!strstr (pos, "plain_text") && !strstr (pos, "text_html")) {
gtk_action_group_set_visible (pp_extension->action_group, FALSE);
- g_hash_table_destroy (query);
- soup_uri_free (soup_uri);
- g_free (uri);
- return;
+ goto out;
}
/* Check whether the displayed part is text_plain */
@@ -353,9 +432,63 @@ mail_display_popup_prefer_plain_update_actions (EMailDisplayPopupExtension *exte
}
g_free (prefix);
+ out:
g_hash_table_destroy (query);
soup_uri_free (soup_uri);
- g_free (uri);
+}
+
+static void
+mail_display_popup_prefer_plain_update_actions (EMailDisplayPopupExtension *extension)
+{
+ EMailDisplay *display;
+ EMailDisplayPopupPreferPlain *pp_extension;
+ gint32 x, y;
+ GdkDeviceManager *device_manager;
+ GdkDevice *pointer;
+
+ display = E_MAIL_DISPLAY (e_extension_get_extensible (
+ E_EXTENSION (extension)));
+
+ pp_extension = E_MAIL_DISPLAY_POPUP_PREFER_PLAIN (extension);
+
+ if (!pp_extension->action_group)
+ pp_extension->action_group = create_group (extension);
+
+ /* In WK2 you can't get the node on what WebKitHitTest was performed,
+ * we have to use other way */
+ device_manager = gdk_display_get_device_manager (
+ gtk_widget_get_display (GTK_WIDGET(display)));
+ pointer = gdk_device_manager_get_client_pointer (device_manager);
+ gdk_window_get_device_position (
+ gtk_widget_get_window (GTK_WIDGET (display)), pointer, &x, &y, NULL);
+
+ if (!pp_extension->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ pp_extension->web_extension,
+ "SaveDocumentFromPoint",
+ g_variant_new (
+ "(tii)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (display)),
+ x, y),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+
+ /* Get URI from saved document */
+ g_dbus_proxy_call (
+ pp_extension->web_extension,
+ "GetDocumentURI",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) get_document_uri_cb,
+ extension);
}
void
@@ -376,6 +509,13 @@ e_mail_display_popup_prefer_plain_dispose (GObject *object)
extension->action_group = NULL;
}
+ if (extension->web_extension_watch_name_id > 0) {
+ g_bus_unwatch_name (extension->web_extension_watch_name_id);
+ extension->web_extension_watch_name_id = 0;
+ }
+
+ g_clear_object (&extension->web_extension);
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_mail_display_popup_prefer_plain_parent_class)->
dispose (object);
@@ -428,5 +568,7 @@ e_mail_display_popup_prefer_plain_init (EMailDisplayPopupPreferPlain *extension)
extension->action_group = NULL;
extension->text_html_id = NULL;
extension->text_plain_id = NULL;
- extension->document = NULL;
+ extension->web_extension = NULL;
+
+ mail_display_popup_prefer_plain_watch_web_extension (extension);
}
diff --git a/modules/prefer-plain/web-extension/Makefile.am b/modules/prefer-plain/web-extension/Makefile.am
new file mode 100644
index 0000000..d11385e
--- /dev/null
+++ b/modules/prefer-plain/web-extension/Makefile.am
@@ -0,0 +1,23 @@
+webextensions_LTLIBRARIES = libmodulepreferplainwebextension.la
+
+libmodulepreferplainwebextension_la_SOURCES = \
+ module-prefer-plain-web-extension.c \
+ module-prefer-plain-web-extension.h
+
+libmodulepreferplainwebextension_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(WEB_EXTENSIONS_CFLAGS)
+
+libmodulepreferplainwebextension_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(WEB_EXTENSIONS_LIBS)
+
+libmodulepreferplainwebextension_la_LDFLAGS = \
+ -module -avoid-version -no-undefined
diff --git a/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
b/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
new file mode 100644
index 0000000..e83efb0
--- /dev/null
+++ b/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
@@ -0,0 +1,176 @@
+/*
+ * module-prefer-plain-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-prefer-plain-web-extension.h"
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <webkit2/webkit-web-extension.h>
+
+#define WEBKIT_DOM_USE_UNSTABLE_API
+#include <webkitdom/WebKitDOMDOMWindowUnstable.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.PreferPlain.WebExtension'>"
+" <method name='ChangeIFrameSource'>"
+" <arg type='s' name='new_uri' direction='in'/>"
+" </method>"
+" <method name='SaveDocumentFromPoint'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='i' name='x' direction='in'/>"
+" <arg type='i' name='y' direction='in'/>"
+" </method>"
+" <method name='GetDocumentURI'>"
+" <arg type='s' name='document_uri' direction='out'/>"
+" </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_PREFER_PLAIN_WEB_EXTENSION_INTERFACE) != 0)
+ return;
+
+ if (g_strcmp0 (method_name, "ChangeIFrameSource") == 0) {
+ WebKitDOMDOMWindow *window;
+ WebKitDOMElement *frame_element;
+ const gchar *new_uri;
+
+ g_variant_get (parameters, "(&s)", &new_uri);
+
+ /* Get frame's window and from the window the actual <iframe> element */
+ window = webkit_dom_document_get_default_view (document_saved);
+ frame_element = webkit_dom_dom_window_get_frame_element (window);
+ webkit_dom_html_iframe_element_set_src (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame_element), new_uri);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "SaveDocumentFromPoint") == 0) {
+ gint32 x = 0, y = 0;
+
+ g_variant_get (parameters, "(tii)", &page_id, &x, &y);
+ 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 = e_dom_utils_get_document_from_point (document, x, y);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "GetDocumentURI") == 0) {
+ gchar *document_uri;
+
+ if (document_saved)
+ document_uri = webkit_dom_document_get_document_uri (document_saved);
+ else
+ document_uri = g_strdup ("");
+
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(s)", document_uri));
+
+ g_free (document_uri);
+ }
+}
+
+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_PREFER_PLAIN_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)
+{
+ g_bus_own_name (
+ G_BUS_TYPE_SESSION,
+ MODULE_PREFER_PLAIN_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ bus_acquired_cb,
+ NULL, NULL,
+ g_object_ref (extension),
+ g_object_unref);
+}
diff --git a/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.h
b/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.h
new file mode 100644
index 0000000..a50a992
--- /dev/null
+++ b/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.h
@@ -0,0 +1,26 @@
+/*
+ * module-prefer-plain-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_PREFER_PLAIN_WEB_EXTENSION_H
+#define MODULE_PREFER_PLAIN_WEB_EXTENSION_H
+
+#define MODULE_PREFER_PLAIN_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.Module.PreferPlain.WebExtension"
+#define MODULE_PREFER_PLAIN_WEB_EXTENSION_OBJECT_PATH "/org/gnome/Evolution/Module/PreferPlain/WebExtension"
+#define MODULE_PREFER_PLAIN_WEB_EXTENSION_INTERFACE "org.gnome.Evolution.Module.PreferPlain.WebExtension"
+
+#endif /* MODULE_PREFER_PLAIN_WEB_EXTENSION_H */
diff --git a/modules/text-highlight/Makefile.am b/modules/text-highlight/Makefile.am
index ab5df67..2a0f45f 100644
--- a/modules/text-highlight/Makefile.am
+++ b/modules/text-highlight/Makefile.am
@@ -1,3 +1,5 @@
+SUBDIRS = web-extension
+
module_LTLIBRARIES = module-text-highlight.la
module_text_highlight_la_CPPFLAGS = \
diff --git a/modules/text-highlight/e-mail-display-popup-text-highlight.c
b/modules/text-highlight/e-mail-display-popup-text-highlight.c
index eb072a0..d90ab27 100644
--- a/modules/text-highlight/e-mail-display-popup-text-highlight.c
+++ b/modules/text-highlight/e-mail-display-popup-text-highlight.c
@@ -23,6 +23,8 @@
#include <shell/e-shell-window.h>
#include "mail/e-mail-browser.h"
+#include "web-extension/module-text-highlight-web-extension.h"
+
#include <libebackend/libebackend.h>
#include <glib/gi18n-lib.h>
@@ -36,7 +38,8 @@ typedef struct _EMailDisplayPopupTextHighlight {
GtkActionGroup *action_group;
- WebKitDOMDocument *document;
+ GDBusProxy *web_extension;
+ gint web_extension_watch_name_id;
} EMailDisplayPopupTextHighlight;
typedef struct _EMailDisplayPopupTextHighlightClass {
@@ -107,33 +110,85 @@ static GtkActionEntry entries[] = {
};
static void
-reformat (GtkAction *old,
- GtkAction *action,
- gpointer user_data)
+web_extension_proxy_created_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ EMailDisplayPopupTextHighlight *th_extension)
+{
+ GError *error = NULL;
+
+ th_extension->web_extension = g_dbus_proxy_new_finish (result, &error);
+ if (!th_extension->web_extension) {
+ g_warning ("Error creating web extension proxy: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+web_extension_appeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ EMailDisplayPopupTextHighlight *th_extension)
+{
+ 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_TEXT_HIGHLIGHT_WEB_EXTENSION_OBJECT_PATH,
+ MODULE_TEXT_HIGHLIGHT_WEB_EXTENSION_INTERFACE,
+ NULL,
+ (GAsyncReadyCallback)web_extension_proxy_created_cb,
+ th_extension);
+}
+
+static void
+web_extension_vanished_cb (GDBusConnection *connection,
+ const gchar *name,
+ EMailDisplayPopupTextHighlight *th_extension)
+{
+ g_clear_object (&th_extension->web_extension);
+}
+
+static void
+mail_display_popup_prefer_plain_watch_web_extension (EMailDisplayPopupTextHighlight *th_extension)
+{
+ th_extension->web_extension_watch_name_id =
+ g_bus_watch_name (
+ G_BUS_TYPE_SESSION,
+ MODULE_TEXT_HIGHLIGHT_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ (GBusNameAppearedCallback) web_extension_appeared_cb,
+ (GBusNameVanishedCallback) web_extension_vanished_cb,
+ th_extension, NULL);
+}
+
+static void
+reformat_get_document_uri_cb (GDBusProxy *web_extension,
+ GAsyncResult *result,
+ GtkAction *action)
{
- EMailDisplayPopupTextHighlight *th_extension;
- WebKitDOMDocument *doc;
- WebKitDOMDOMWindow *window;
- WebKitDOMElement *frame_element;
SoupURI *soup_uri;
GHashTable *query;
gchar *uri;
+ GVariant *result_variant;
- th_extension = E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT (user_data);
- doc = th_extension->document;
- if (!doc)
- return;
+ result_variant = g_dbus_proxy_call_finish (web_extension, result, NULL);
+ if (result_variant) {
+ const gchar *document_uri;
- uri = webkit_dom_document_get_document_uri (doc);
- soup_uri = soup_uri_new (uri);
- g_free (uri);
+ g_variant_get (result_variant, "(&s)", &document_uri);
+ soup_uri = soup_uri_new (document_uri);
+ g_variant_unref (result_variant);
+ }
if (!soup_uri)
- goto exit;
+ return;
if (!soup_uri->query) {
soup_uri_free (soup_uri);
- goto exit;
+ return;
}
query = soup_form_decode (soup_uri->query);
@@ -149,16 +204,31 @@ reformat (GtkAction *old,
soup_uri_free (soup_uri);
/* Get frame's window and from the window the actual <iframe> element */
- window = webkit_dom_document_get_default_view (doc);
- frame_element = webkit_dom_dom_window_get_frame_element (window);
- webkit_dom_html_iframe_element_set_src (
- WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame_element), uri);
+ g_dbus_proxy_call (
+ web_extension,
+ "ChangeIFrameSource",
+ g_variant_new ("(s)", uri),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
g_free (uri);
- /* The frame has been reloaded, the document pointer is invalid now */
-exit:
- th_extension->document = NULL;
+ if (!th_extension->web_extension)
+ return;
+
+ /* Get URI from saved document */
+ g_dbus_proxy_call (
+ th_extension->web_extension,
+ "GetDocumentURI",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) reformat_get_document_uri_cb,
+ action);
}
static GtkActionGroup *
@@ -272,34 +342,28 @@ create_group (EMailDisplayPopupExtension *extension)
}
static void
-update_actions (EMailDisplayPopupExtension *extension,
- WebKitHitTestResult *context)
+get_document_uri_cb (GDBusProxy *web_extension,
+ GAsyncResult *result,
+ EMailDisplayPopupTextHighlight *th_extension)
{
- EMailDisplayPopupTextHighlight *th_extension;
- WebKitDOMNode *node;
- WebKitDOMDocument *document;
- gchar *uri;
-
- th_extension = E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT (extension);
+ GVariant *result_variant;
+ gchar *document_uri;
- if (th_extension->action_group == NULL) {
- th_extension->action_group = create_group (extension);
+ result_variant = g_dbus_proxy_call_finish (web_extension, result, NULL);
+ if (result_variant) {
+ g_variant_get (result_variant, "(s)", &document_uri);
+ g_variant_unref (result_variant);
}
- th_extension->document = NULL;
- g_object_get (G_OBJECT (context), "inner-node", &node, NULL);
- document = webkit_dom_node_get_owner_document (node);
- uri = webkit_dom_document_get_document_uri (document);
-
/* If the part below context menu was made by text-highlight formatter,
* then try to check what formatter it's using at the moment and set
* it as active in the popup menu */
- if (uri && strstr (uri, ".text-highlight") != NULL) {
+ if (document_uri && strstr (document_uri, ".text-highlight") != NULL) {
SoupURI *soup_uri;
gtk_action_group_set_visible (
th_extension->action_group, TRUE);
- soup_uri = soup_uri_new (uri);
+ soup_uri = soup_uri_new (document_uri);
if (soup_uri && soup_uri->query) {
GHashTable *query = soup_form_decode (soup_uri->query);
gchar *highlighter;
@@ -329,12 +393,63 @@ update_actions (EMailDisplayPopupExtension *extension,
th_extension->action_group, FALSE);
}
- /* Set the th_extension->document AFTER changing the active action to
- * prevent the reformat() from doing some crazy reformatting
- * (reformat() returns immediatelly when th_extension->document is NULL) */
- th_extension->document = document;
- g_free (uri);
+ g_free (document_uri);
+}
+
+static void
+update_actions (EMailDisplayPopupExtension *extension)
+{
+ EMailDisplay *display;
+ EMailDisplayPopupTextHighlight *th_extension;
+ gint32 x, y;
+ GdkDeviceManager *device_manager;
+ GdkDevice *pointer;
+
+ display = E_MAIL_DISPLAY (e_extension_get_extensible (
+ E_EXTENSION (extension)));
+
+ th_extension = E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT (extension);
+
+ if (th_extension->action_group == NULL) {
+ th_extension->action_group = create_group (extension);
+ }
+
+ /* In WK2 you can't get the node on what WebKitHitTest was performed,
+ * we have to use other way */
+ device_manager = gdk_display_get_device_manager (
+ gtk_widget_get_display (GTK_WIDGET(display)));
+ pointer = gdk_device_manager_get_client_pointer (device_manager);
+ gdk_window_get_device_position (
+ gtk_widget_get_window (GTK_WIDGET (display)), pointer, &x, &y, NULL);
+
+ if (!th_extension->web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ th_extension->web_extension,
+ "SaveDocumentFromPoint",
+ g_variant_new (
+ "(tii)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (display)),
+ x, y),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+
+ /* Get URI from saved document */
+ g_dbus_proxy_call (
+ th_extension->web_extension,
+ "GetDocumentURI",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) get_document_uri_cb,
+ th_extension);
}
void
@@ -370,4 +485,6 @@ static void
e_mail_display_popup_text_highlight_init (EMailDisplayPopupTextHighlight *extension)
{
extension->action_group = NULL;
+
+ mail_display_popup_prefer_plain_watch_web_extension (extension);
}
diff --git a/modules/text-highlight/web-extension/Makefile.am
b/modules/text-highlight/web-extension/Makefile.am
new file mode 100644
index 0000000..e9e3faf
--- /dev/null
+++ b/modules/text-highlight/web-extension/Makefile.am
@@ -0,0 +1,23 @@
+webextensions_LTLIBRARIES = libmoduletexthighlightwebextension.la
+
+libmoduletexthighlightwebextension_la_SOURCES = \
+ module-text-highlight-web-extension.c \
+ module-text-highlight-web-extension.h
+
+libmoduletexthighlightwebextension_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(WEB_EXTENSIONS_CFLAGS)
+
+libmoduletexthighlightwebextension_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(WEB_EXTENSIONS_LIBS)
+
+libmoduletexthighlightwebextension_la_LDFLAGS = \
+ -module -avoid-version -no-undefined
diff --git a/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
b/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
new file mode 100644
index 0000000..229b981
--- /dev/null
+++ b/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
@@ -0,0 +1,176 @@
+/*
+ * module-text-highlight-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-text-highlight-web-extension.h"
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <webkit2/webkit-web-extension.h>
+
+#define WEBKIT_DOM_USE_UNSTABLE_API
+#include <webkitdom/WebKitDOMDOMWindowUnstable.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.TextHighlight.WebExtension'>"
+" <method name='ChangeIFrameSource'>"
+" <arg type='s' name='new_uri' direction='in'/>"
+" </method>"
+" <method name='SaveDocumentFromPoint'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='i' name='x' direction='in'/>"
+" <arg type='i' name='y' direction='in'/>"
+" </method>"
+" <method name='GetDocumentURI'>"
+" <arg type='s' name='document_uri' direction='out'/>"
+" </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_TEXT_HIGHLIGHT_WEB_EXTENSION_INTERFACE) != 0)
+ return;
+
+ if (g_strcmp0 (method_name, "ChangeIFrameSource") == 0) {
+ WebKitDOMDOMWindow *window;
+ WebKitDOMElement *frame_element;
+ const gchar *new_uri;
+
+ g_variant_get (parameters, "(&s)", &new_uri);
+
+ /* Get frame's window and from the window the actual <iframe> element */
+ window = webkit_dom_document_get_default_view (document_saved);
+ frame_element = webkit_dom_dom_window_get_frame_element (window);
+ webkit_dom_html_iframe_element_set_src (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame_element), new_uri);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "SaveDocumentFromPoint") == 0) {
+ gint32 x = 0, y = 0;
+
+ g_variant_get (parameters, "(tii)", &page_id, &x, &y);
+ 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 = e_dom_utils_get_document_from_point (document, x, y);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "GetDocumentURI") == 0) {
+ gchar *document_uri;
+
+ if (document_saved)
+ document_uri = webkit_dom_document_get_document_uri (document_saved);
+ else
+ document_uri = g_strdup ("");
+
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(s)", document_uri));
+
+ g_free (document_uri);
+ }
+}
+
+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_TEXT_HIGHLIGHT_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)
+{
+ g_bus_own_name (
+ G_BUS_TYPE_SESSION,
+ MODULE_TEXT_HIGHLIGHT_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ bus_acquired_cb,
+ NULL, NULL,
+ g_object_ref (extension),
+ g_object_unref);
+}
diff --git a/modules/text-highlight/web-extension/module-text-highlight-web-extension.h
b/modules/text-highlight/web-extension/module-text-highlight-web-extension.h
new file mode 100644
index 0000000..7308f65
--- /dev/null
+++ b/modules/text-highlight/web-extension/module-text-highlight-web-extension.h
@@ -0,0 +1,26 @@
+/*
+ * module-text-highlight-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_TEXT_HIGHLIGHT_WEB_EXTENSION_H
+#define MODULE_TEXT_HIGHLIGHT_WEB_EXTENSION_H
+
+#define MODULE_TEXT_HIGHLIGHT_WEB_EXTENSION_SERVICE_NAME
"org.gnome.Evolution.Module.TextHighlight.WebExtension"
+#define MODULE_TEXT_HIGHLIGHT_WEB_EXTENSION_OBJECT_PATH
"/org/gnome/Evolution/Module/TextHighlight/WebExtension"
+#define MODULE_TEXT_HIGHLIGHT_WEB_EXTENSION_INTERFACE
"org.gnome.Evolution.Module.TextHighlight.WebExtension"
+
+#endif /* MODULE_TEXT_HIGHLIGHT_WEB_EXTENSION_H */
diff --git a/modules/vcard-inline/e-mail-formatter-vcard.c b/modules/vcard-inline/e-mail-formatter-vcard.c
index f13d677..40e573c 100644
--- a/modules/vcard-inline/e-mail-formatter-vcard.c
+++ b/modules/vcard-inline/e-mail-formatter-vcard.c
@@ -146,9 +146,12 @@ mail_formatter_vcard_format (EMailFormatterExtension *extension,
str = g_strdup_printf (
"<button type=\"button\" "
"name=\"set-display-mode\" "
+ "id=\"%s\" "
"class=\"org-gnome-vcard-display-mode-button\" "
"value=\"%d\" "
+ "style=\"margin-left: 0px\""
"accesskey=\"%s\">%s</button>",
+ e_mail_part_get_id (part),
mode, access_key, html_label);
g_output_stream_write_all (
stream, str, strlen (str), NULL, cancellable, NULL);
@@ -166,8 +169,10 @@ mail_formatter_vcard_format (EMailFormatterExtension *extension,
"class=\"org-gnome-vcard-save-button\" "
"value=\"%s\" "
"accesskey=\"%s\">%s</button><br>"
- "<iframe width=\"100%%\" height=\"auto\" frameborder=\"0\""
- "src=\"%s\" name=\"%s\"></iframe>"
+ "<iframe width=\"100%%\" height=\"auto\" "
+ " class=\"-e-mail-formatter-frame-color -e-web-view-background-color\" "
+ " style=\"border: 1px solid;\""
+ " src=\"%s\" name=\"%s\"></iframe>"
"</div>",
e_mail_part_get_id (part),
access_key, html_label, uri,
diff --git a/modules/vcard-inline/e-mail-part-vcard.c b/modules/vcard-inline/e-mail-part-vcard.c
index 4335f30..4768295 100644
--- a/modules/vcard-inline/e-mail-part-vcard.c
+++ b/modules/vcard-inline/e-mail-part-vcard.c
@@ -32,6 +32,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 (
@@ -85,8 +91,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;
@@ -94,9 +104,19 @@ save_vcard_cb (WebKitDOMEventTarget *button,
ESourceRegistry *registry;
ESourceSelector *selector;
GSList *contact_list;
- const gchar *extension_name;
+ const gchar *extension_name, *button_value, *part_id;
GtkWidget *dialog;
+ if (g_strcmp0 (signal_name, "VCardInlineSaveButtonPressed") != 0)
+ return;
+
+ g_variant_get (parameters, "(&s)", &button_value);
+
+ part_id = e_mail_part_get_id (E_MAIL_PART (vcard_part));
+
+ if (!strstr (part_id, button_value))
+ return;
+
shell = e_shell_get_default ();
registry = e_shell_get_registry (shell);
extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
@@ -131,8 +151,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;
@@ -140,47 +164,54 @@ display_mode_toggle_cb (WebKitDOMEventTarget *button,
gchar *html_label;
gchar *access_key;
const gchar *part_id;
+ const gchar *button_id;
+
+ if (g_strcmp0 (signal_name, "VCardInlineDisplayModeToggled") != 0)
+ return;
+
+ if (!vcard_part->priv->web_extension)
+ return;
+
+ g_variant_get (parameters, "(&s)", &button_id);
part_id = e_mail_part_get_id (E_MAIL_PART (vcard_part));
+ if (!strstr (part_id, button_id))
+ return;
+
mode = eab_contact_formatter_get_display_mode (vcard_part->formatter);
if (mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) {
mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
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);
}
+ g_dbus_proxy_call (
+ vcard_part->priv->web_extension,
+ "VCardInlineUpdateButton",
+ g_variant_new (
+ "(tsss)",
+ vcard_part->priv->page_id,
+ button_id,
+ html_label,
+ access_key),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+
+ 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 (
@@ -188,8 +219,19 @@ 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);
+ g_dbus_proxy_call (
+ vcard_part->priv->web_extension,
+ "VCardInlineSetIFrameSrc",
+ g_variant_new (
+ "(tss)",
+ vcard_part->priv->page_id,
+ button_id,
+ uri),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
g_free (uri);
}
@@ -202,11 +244,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);
}
@@ -249,60 +302,55 @@ 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;
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);
- g_object_unref (list);
-
- /* 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);
- g_object_unref (list);
-
- /* 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);
- g_object_unref (list);
-
- 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);
+
+ g_dbus_proxy_call (
+ 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,
+ NULL);
}
static void
diff --git a/modules/vcard-inline/e-mail-part-vcard.h b/modules/vcard-inline/e-mail-part-vcard.h
index d9409c5..9aeb595 100644
--- a/modules/vcard-inline/e-mail-part-vcard.h
+++ b/modules/vcard-inline/e-mail-part-vcard.h
@@ -21,7 +21,6 @@
#include <em-format/e-mail-part.h>
#include <addressbook/gui/widgets/eab-contact-formatter.h>
-#include <webkit/webkitdom.h>
/* Standard GObject macros */
#define E_TYPE_MAIL_PART_VCARD \
@@ -57,9 +56,6 @@ struct _EMailPartVCard {
GtkWidget *message_label;
EABContactFormatter *formatter;
- WebKitDOMElement *iframe;
- WebKitDOMElement *toggle_button;
- WebKitDOMElement *save_button;
CamelFolder *folder;
gchar *message_uid;
diff --git a/modules/web-inspector/evolution-web-inspector.c b/modules/web-inspector/evolution-web-inspector.c
index 6ccba80..fd8606a 100644
--- a/modules/web-inspector/evolution-web-inspector.c
+++ b/modules/web-inspector/evolution-web-inspector.c
@@ -85,51 +85,24 @@ web_inspector_key_press_event_cb (WebKitWebView *web_view,
return handled;
}
-static WebKitWebView *
-web_inspector_inspect_web_view_cb (WebKitWebInspector *inspector)
-{
- GtkWidget *web_view;
- GtkWidget *window;
- const gchar *title;
-
- title = _("Evolution Web Inspector");
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), title);
- gtk_widget_set_size_request (window, 600, 400);
- gtk_widget_show (window);
-
- web_view = webkit_web_view_new ();
- gtk_container_add (GTK_CONTAINER (window), web_view);
- gtk_widget_show (web_view);
-
- return WEBKIT_WEB_VIEW (web_view);
-}
-
static void
web_inspector_constructed (GObject *object)
{
EWebInspector *extension;
WebKitWebView *web_view;
- WebKitWebSettings *settings;
- WebKitWebInspector *inspector;
+ WebKitSettings *settings;
/* Chain up to parent's method. */
G_OBJECT_CLASS (e_web_inspector_parent_class)->constructed (object);
extension = E_WEB_INSPECTOR (object);
web_view = web_inspector_get_web_view (extension);
- settings = webkit_web_view_get_settings (web_view);
- inspector = webkit_web_view_get_inspector (web_view);
-
- g_object_set (settings, "enable-developer-extras", TRUE, NULL);
++ settings = webkit_web_view_get_settings (web_view);
+ webkit_settings_set_enable_developer_extras (settings, TRUE);
g_signal_connect (
web_view, "key-press-event",
G_CALLBACK (web_inspector_key_press_event_cb), NULL);
-
- g_signal_connect (
- inspector, "inspect-web-view",
- G_CALLBACK (web_inspector_inspect_web_view_cb), NULL);
}
static void
diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c
index 065df23..a07feed 100644
--- a/plugins/mail-to-task/mail-to-task.c
+++ b/plugins/mail-to-task/mail-to-task.c
@@ -828,7 +828,7 @@ typedef struct {
ECalClientSourceType source_type;
CamelFolder *folder;
GPtrArray *uids;
- gchar *selected_text;
+ const gchar *selected_text;
gboolean with_attendees;
}AsyncData;
@@ -1037,7 +1037,6 @@ do_mail_to_event (AsyncData *data)
g_object_unref (folder);
g_object_unref (data->source);
- g_free (data->selected_text);
g_free (data);
data = NULL;
@@ -1073,24 +1072,21 @@ text_contains_nonwhitespace (const gchar *text,
return p - text < len - 1 && c != 0;
}
-/* should be freed with g_free after done with it */
-static gchar *
+static const gchar *
get_selected_text (EMailReader *reader)
{
EMailDisplay *display;
- gchar *text = NULL;
+ const gchar *text = NULL;
display = e_mail_reader_get_mail_display (reader);
if (!e_web_view_is_selection_active (E_WEB_VIEW (display)))
return NULL;
- text = e_mail_display_get_selection_plain_text (display);
+ text = e_mail_display_get_selection_plain_text_sync (display, NULL, NULL);
- if (text == NULL || !text_contains_nonwhitespace (text, strlen (text))) {
- g_free (text);
+ if (text == NULL || !text_contains_nonwhitespace (text, strlen (text)))
return NULL;
- }
return text;
}
@@ -1203,6 +1199,7 @@ mail_to_event (ECalClientSourceType source_type,
data->uids = g_ptr_array_ref (uids);
data->with_attendees = with_attendees;
+ /* FIXME XXX WK2 move data->selected_text to const gchar * */
if (uids->len == 1)
data->selected_text = get_selected_text (reader);
else
diff --git a/shell/main.c b/shell/main.c
index 972c0bd..0bc42d4 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -52,7 +52,7 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
-#include <webkit/webkit.h>
+#include <webkit2/webkit2.h>
#include "e-shell.h"
#include "e-shell-migrate.h"
@@ -571,6 +571,7 @@ main (gint argc,
g_object_unref (settings);
#endif
+ /* FIXME XXX WK2 - Look if we still need this it looks like it's not. */
/* Workaround https://bugzilla.gnome.org/show_bug.cgi?id=683548 */
if (!quit)
g_type_ensure (WEBKIT_TYPE_WEB_VIEW);
diff --git a/web-extensions/Makefile.am b/web-extensions/Makefile.am
new file mode 100644
index 0000000..3577cfb
--- /dev/null
+++ b/web-extensions/Makefile.am
@@ -0,0 +1,23 @@
+webextensions_LTLIBRARIES = libevolutionwebextension.la
+
+libevolutionwebextension_la_SOURCES = \
+ evolution-web-extension.c \
+ evolution-web-extension.h
+
+libevolutionwebextension_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(WEB_EXTENSIONS_CFLAGS)
+
+libevolutionwebextension_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(WEB_EXTENSIONS_LIBS)
+
+libevolutionwebextension_la_LDFLAGS = \
+ -module -avoid-version -no-undefined
diff --git a/web-extensions/evolution-web-extension.c b/web-extensions/evolution-web-extension.c
new file mode 100644
index 0000000..908e79e
--- /dev/null
+++ b/web-extensions/evolution-web-extension.c
@@ -0,0 +1,636 @@
+/*
+ * evolution-web-extension.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "evolution-web-extension.h"
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <webkit2/webkit-web-extension.h>
+
+#include <libemail-engine/e-mail-enums.h>
+
+#include <string.h>
+
+#include <e-util/e-dom-utils.h>
+#include <libedataserver/libedataserver.h>
+
+/* FIXME Clean it */
+static GDBusConnection *dbus_connection;
+static gboolean need_input = FALSE;
+static gboolean force_image_load = FALSE;
+static CamelDataCache *emd_global_http_cache = NULL;
+
+static const char introspection_xml[] =
+"<node>"
+" <interface name='org.gnome.Evolution.WebExtension'>"
+" <signal name='HeadersCollapsed'>"
+" <arg type='b' name='expanded' direction='out'/>"
+" </signal>"
+" <method name='ReplaceLocalImageLinks'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" </method>"
+" <method name='GetDocumentContentHTML'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='html_content' direction='out'/>"
+" </method>"
+" <method name='GetSelectionContentHTML'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='html_content' direction='out'/>"
+" </method>"
+" <method name='GetSelectionContentText'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='text_content' direction='out'/>"
+" </method>"
+" <method name='CreateAndAddCSSStyleSheet'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='style_sheet_id' direction='in'/>"
+" </method>"
+" <method name='AddCSSRuleIntoStyleSheet'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='style_sheet_id' direction='in'/>"
+" <arg type='s' name='selector' direction='in'/>"
+" <arg type='s' name='style' direction='in'/>"
+" </method>"
+" <method name='EABContactFormatterBindDOM'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" </method>"
+" <method name='EMailDisplayBindDOM'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" </method>"
+" <method name='ElementExists'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='element_id' direction='in'/>"
+" <arg type='b' name='element_exists' direction='out'/>"
+" <arg type='t' name='page_id' direction='out'/>"
+" </method>"
+" <method name='GetActiveElementName'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='element_name' direction='out'/>"
+" </method>"
+" <method name='EMailPartHeadersBindDOMElement'>"
+" <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_id' direction='out'/>"
+" </signal>"
+" <signal name='VCardInlineSaveButtonPressed'>"
+" <arg type='s' name='button_value' 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_id' 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='button_id' direction='in'/>"
+" <arg type='s' name='src' direction='in'/>"
+" </method>"
+" <property type='b' name='NeedInput' access='readwrite'/>"
+" <property type='b' name='ForceImageLoad' access='readwrite'/>"
+" </interface>"
+"</node>";
+
+static gboolean
+image_exists_in_cache (const gchar *image_uri)
+{
+ gchar *filename;
+ gchar *hash;
+ gboolean exists = FALSE;
+
+ g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
+
+ hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
+ filename = camel_data_cache_get_filename (
+ emd_global_http_cache, "http", hash);
+
+ if (filename != NULL) {
+ exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+ g_free (filename);
+ }
+
+ g_free (hash);
+
+ return exists;
+}
+
+static EMailImageLoadingPolicy
+get_image_loading_policy (void)
+{
+ GSettings *settings;
+ EMailImageLoadingPolicy image_policy;
+
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ image_policy = g_settings_get_enum (settings, "image-loading-policy");
+ g_object_unref (settings);
+
+ return image_policy;
+}
+
+static void
+redirect_http_uri (WebKitWebPage *web_page,
+ WebKitURIRequest *request)
+{
+ const gchar *uri, *page_uri;
+ gchar *new_uri, *mail_uri, *enc;
+ SoupURI *soup_uri;
+ GHashTable *query;
+ gboolean image_exists;
+ EMailImageLoadingPolicy image_policy;
+
+ uri = webkit_uri_request_get_uri (request);
+ page_uri = webkit_web_page_get_uri (web_page);
+
+ /* Check Evolution's cache */
+ image_exists = image_exists_in_cache (uri);
+
+ /* If the URI is not cached and we are not allowed to load it
+ * then redirect to invalid URI, so that webkit would display
+ * a native placeholder for it. */
+ image_policy = get_image_loading_policy ();
+ if (!image_exists && !force_image_load &&
+ (image_policy == E_MAIL_IMAGE_LOADING_POLICY_NEVER)) {
+ webkit_uri_request_set_uri (request, "about:blank");
+ return;
+ }
+
+ new_uri = g_strconcat ("evo-", uri, NULL);
+ mail_uri = g_strndup (page_uri, strstr (page_uri, "?") - page_uri);
+
+ soup_uri = soup_uri_new (new_uri);
+ if (soup_uri->query)
+ query = soup_form_decode (soup_uri->query);
+ else
+ query = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ g_free, g_free);
+
+ enc = soup_uri_encode (mail_uri, NULL);
+ g_hash_table_insert (query, g_strdup ("__evo-mail"), enc);
+
+ if (force_image_load) {
+ g_hash_table_insert (
+ query,
+ g_strdup ("__evo-load-images"),
+ g_strdup ("true"));
+ }
+
+ g_free (mail_uri);
+
+ soup_uri_set_query_from_form (soup_uri, query);
+ g_free (new_uri);
+
+ new_uri = soup_uri_to_string (soup_uri, FALSE);
+
+ webkit_uri_request_set_uri (request, new_uri);
+
+ soup_uri_free (soup_uri);
+ g_hash_table_unref (query);
+ g_free (new_uri);
+}
+
+static gboolean
+web_page_send_request (WebKitWebPage *web_page,
+ WebKitURIRequest *request,
+ WebKitURIResponse *redirected_response,
+ gpointer user_data)
+{
+ const char *request_uri;
+ const char *page_uri;
+ gboolean uri_is_http;
+
+ request_uri = webkit_uri_request_get_uri (request);
+ page_uri = webkit_web_page_get_uri (web_page);
+
+ /* Always load the main resource. */
+ if (g_strcmp0 (request_uri, page_uri) == 0)
+ return FALSE;
+
+ uri_is_http =
+ g_str_has_prefix (request_uri, "http:") ||
+ g_str_has_prefix (request_uri, "https:") ||
+ g_str_has_prefix (request_uri, "evo-http:") ||
+ g_str_has_prefix (request_uri, "evo-https:");
+
+ if (uri_is_http)
+ redirect_http_uri (web_page, request);
+
+ return FALSE;
+}
+
+static void
+web_page_document_loaded (WebKitWebPage *web_page,
+ gpointer user_data)
+{
+
+}
+
+static void
+web_page_created_callback (WebKitWebExtension *extension,
+ WebKitWebPage *web_page,
+ gpointer user_data)
+{
+ g_signal_connect_object (
+ web_page, "send-request",
+ G_CALLBACK (web_page_send_request),
+ NULL, 0);
+
+ g_signal_connect_object (
+ web_page, "document-loaded",
+ G_CALLBACK (web_page_document_loaded),
+ NULL, 0);
+
+}
+
+static WebKitWebPage *
+get_webkit_web_page_or_return_dbus_error (GDBusMethodInvocation *invocation,
+ WebKitWebExtension *web_extension,
+ guint64 page_id)
+{
+ WebKitWebPage *web_page = webkit_web_extension_get_page (web_extension, page_id);
+ if (!web_page) {
+ g_dbus_method_invocation_return_error (
+ invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid page ID: %"G_GUINT64_FORMAT, page_id);
+ }
+ return web_page;
+}
+
+static void
+handle_method_call (GDBusConnection *connection,
+ const char *sender,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ WebKitWebExtension *web_extension = WEBKIT_WEB_EXTENSION (user_data);
+ WebKitWebPage *web_page;
+ WebKitDOMDocument *document;
+ guint64 page_id;
+
+ if (g_strcmp0 (interface_name, EVOLUTION_WEB_EXTENSION_INTERFACE) != 0)
+ return;
+
+ if (g_strcmp0 (method_name, "ReplaceLocalImageLinks") == 0) {
+ g_variant_get (parameters, "(t)", &page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ e_dom_utils_replace_local_image_links (document);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "GetDocumentContentHTML") == 0) {
+ gchar *html_content;
+
+ g_variant_get (parameters, "(t)", &page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ html_content = e_dom_utils_get_document_content_html (document);
+
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(s)", html_content));
+
+ g_free (html_content);
+ } else if (g_strcmp0 (method_name, "GetSelectionContentHTML") == 0) {
+ gchar *html_content;
+
+ g_variant_get (parameters, "(t)", &page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ html_content = e_dom_utils_get_selection_content_html (document);
+
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(s)", html_content));
+
+ g_free (html_content);
+ } else if (g_strcmp0 (method_name, "GetSelectionContentText") == 0) {
+ gchar *text_content;
+
+ g_variant_get (parameters, "(t)", &page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ text_content = e_dom_utils_get_selection_content_html (document);
+
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(s)", text_content));
+
+ g_free (text_content);
+ } else if (g_strcmp0 (method_name, "AddCSSRuleIntoStyleSheet") == 0) {
+ const gchar *style_sheet_id, *selector, *style;
+
+ g_variant_get (
+ parameters,
+ "(t&s&s&s)",
+ &page_id, &style_sheet_id, &selector, &style);
+
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ e_dom_utils_add_css_rule_into_style_sheet (document, style_sheet_id, selector, style);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "CreateAndAddCSSStyleSheet") == 0) {
+ const gchar *style_sheet_id;
+
+ g_variant_get (parameters, "(t&s)", &page_id, &style_sheet_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ e_dom_utils_create_and_add_css_style_sheet (document, style_sheet_id);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "EABContactFormatterBindDOM") == 0) {
+ g_variant_get (parameters, "(t)", &page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ e_dom_utils_eab_contact_formatter_bind_dom (document);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "EMailDisplayBindDOM") == 0) {
+ g_variant_get (parameters, "(t)", &page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ e_dom_utils_e_mail_display_bind_dom (document, connection);
+ e_dom_utils_bind_focus_on_elements (document, connection);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "ElementExists") == 0) {
+ const gchar *element_id;
+ gboolean element_exists;
+
+ 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);
+ element_exists = e_dom_utils_element_exists (document, element_id);
+
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(bt)", element_exists, page_id));
+ } else if (g_strcmp0 (method_name, "GetActiveElementName") == 0) {
+ gchar *element_name;
+
+ g_variant_get (parameters, "(t)", &page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ element_name = e_dom_utils_get_active_element_name (document);
+
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(s)", element_name));
+
+ g_free (element_name);
+ } else if (g_strcmp0 (method_name, "EMailPartHeadersBindDOMElement") == 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_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_module_vcard_inline_bind_dom (
+ document, element_id, connection);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "VCardInlineUpdateButton") == 0) {
+ const gchar *button_id, *html_label, *access_key;
+
+ g_variant_get (
+ parameters,
+ "(t&s&s&s)",
+ &page_id, &button_id, &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_module_vcard_inline_update_button (
+ document, button_id, html_label, access_key);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "VCardInlineSetIFrameSrc") == 0) {
+ const gchar *src, *button_id;
+
+ g_variant_get (parameters, "(t&s&s)", &page_id, &button_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_module_vcard_inline_set_iframe_src (document, button_id, src);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ }
+}
+
+static GVariant *
+handle_get_property (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GError **error,
+ gpointer user_data)
+{
+ GVariant *variant;
+
+ if (g_strcmp0 (property_name, "NeedInput") == 0) {
+ variant = g_variant_new_boolean (need_input);
+ } else if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
+ variant = g_variant_new_boolean (force_image_load);
+ }
+
+ return variant;
+}
+
+static gboolean
+handle_set_property (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GVariant *variant,
+ GError **error,
+ gpointer user_data)
+{
+ GError *local_error = NULL;
+ GVariantBuilder *builder;
+
+ builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+
+ if (g_strcmp0 (property_name, "NeedInput") == 0) {
+ gboolean value = g_variant_get_boolean (variant);
+
+ if (value == need_input)
+ goto exit;
+
+ need_input = value;
+
+ g_variant_builder_add (builder,
+ "{sv}",
+ "NeedInput",
+ g_variant_new_boolean (need_input));
+ } else if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
+ gboolean value = g_variant_get_boolean (variant);
+
+ if (value == force_image_load)
+ goto exit;
+
+ force_image_load = value;
+
+ g_variant_builder_add (builder,
+ "{sv}",
+ "ForceImageLoad",
+ g_variant_new_boolean (force_image_load));
+ }
+
+ g_dbus_connection_emit_signal (connection,
+ NULL,
+ object_path,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ g_variant_new (
+ "(sa{sv}as)",
+ interface_name,
+ builder,
+ NULL),
+ &local_error);
+
+ g_assert_no_error (local_error);
+
+ exit:
+ g_variant_builder_unref (builder);
+
+ return TRUE;
+}
+
+static const GDBusInterfaceVTable interface_vtable = {
+ handle_method_call,
+ handle_get_property,
+ handle_set_property
+};
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ guint registration_id;
+ GError *error = NULL;
+ static GDBusNodeInfo *introspection_data = NULL;
+
+ if (!introspection_data)
+ introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+
+ registration_id =
+ g_dbus_connection_register_object (
+ connection,
+ EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
+ introspection_data->interfaces[0],
+ &interface_vtable,
+ g_object_ref (user_data),
+ g_object_unref,
+ &error);
+
+ if (!registration_id) {
+ g_warning ("Failed to register object: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ dbus_connection = connection;
+ g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&dbus_connection);
+
+ if (emd_global_http_cache == NULL) {
+ emd_global_http_cache = camel_data_cache_new (
+ e_get_user_cache_dir (), NULL);
+
+ /* cache expiry - 2 hour access, 1 day max */
+ camel_data_cache_set_expire_age (
+ emd_global_http_cache, 24 * 60 * 60);
+ camel_data_cache_set_expire_access (
+ emd_global_http_cache, 2 * 60 * 60);
+ }
+ }
+}
+
+/* Forward declaration */
+G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *extension);
+
+G_MODULE_EXPORT void
+webkit_web_extension_initialize (WebKitWebExtension *extension)
+{
+ g_signal_connect (
+ extension, "page-created",
+ G_CALLBACK (web_page_created_callback),
+ NULL);
+
+ g_bus_own_name (
+ G_BUS_TYPE_SESSION,
+ EVOLUTION_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ bus_acquired_cb,
+ NULL, NULL,
+ g_object_ref (extension),
+ g_object_unref);
+}
diff --git a/web-extensions/evolution-web-extension.h b/web-extensions/evolution-web-extension.h
new file mode 100644
index 0000000..ccee49f
--- /dev/null
+++ b/web-extensions/evolution-web-extension.h
@@ -0,0 +1,26 @@
+/*
+ * evolution-web-extension.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef EVOLUTION_WEB_EXTENSION_H
+#define EVOLUTION_WEB_EXTENSION_H
+
+#define EVOLUTION_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.WebExtension"
+#define EVOLUTION_WEB_EXTENSION_OBJECT_PATH "/org/gnome/Evolution/WebExtension"
+#define EVOLUTION_WEB_EXTENSION_INTERFACE "org.gnome.Evolution.WebExtension"
+
+#endif /* EVOLUTION_WEB_EXTENSION_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]