[evolution] The "Reply from preview selection" feature is wrong for multipart messages
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] The "Reply from preview selection" feature is wrong for multipart messages
- Date: Mon, 24 Oct 2016 12:27:32 +0000 (UTC)
commit b14222e7fca56d81aee81e06e2320c7a37c4a890
Author: Tomas Popela <tpopela redhat com>
Date: Mon Oct 24 14:22:22 2016 +0200
The "Reply from preview selection" feature is wrong for multipart messages
Introduce e_mail_display_get_selection_content_multipart_sync() that
will return a current selection with the right mime type (that's
reflecting whether the plain text part of the HTML one is currently
displayed).
src/mail/e-mail-display.c | 44 ++++++++
src/mail/e-mail-display.h | 5 +
src/mail/e-mail-reader-utils.c | 17 ++-
src/web-extensions/e-dom-utils.c | 182 ++++++++++++++++++++++++++--------
src/web-extensions/e-dom-utils.h | 3 +
src/web-extensions/e-web-extension.c | 31 ++++++-
6 files changed, 233 insertions(+), 49 deletions(-)
---
diff --git a/src/mail/e-mail-display.c b/src/mail/e-mail-display.c
index 073002f..7e5070b 100644
--- a/src/mail/e-mail-display.c
+++ b/src/mail/e-mail-display.c
@@ -2462,6 +2462,50 @@ e_mail_display_set_status (EMailDisplay *display,
}
gchar *
+e_mail_display_get_selection_content_multipart_sync (EMailDisplay *display,
+ gboolean *is_html,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GDBusProxy *web_extension;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ if (!e_web_view_is_selection_active (E_WEB_VIEW (display)))
+ return NULL;
+
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
+ if (web_extension) {
+ GVariant *result;
+
+ result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_full (
+ web_extension,
+ "GetSelectionContentMultipart",
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (
+ WEBKIT_WEB_VIEW (display))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ error);
+
+ if (result) {
+ gchar *content = NULL;
+ gboolean text_html = FALSE;
+
+ g_variant_get (result, "(sb)", &content, &text_html);
+ g_variant_unref (result);
+ if (is_html)
+ *is_html = text_html;
+ return content;
+ }
+ }
+
+ return NULL;
+}
+
+gchar *
e_mail_display_get_selection_plain_text_sync (EMailDisplay *display,
GCancellable *cancellable,
GError **error)
diff --git a/src/mail/e-mail-display.h b/src/mail/e-mail-display.h
index 1a75ba4..e1d6fd9 100644
--- a/src/mail/e-mail-display.h
+++ b/src/mail/e-mail-display.h
@@ -94,6 +94,11 @@ 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_content_multipart_sync
+ (EMailDisplay *display,
+ gboolean *is_html,
+ GCancellable *cancellable,
+ GError **error);
gchar * e_mail_display_get_selection_plain_text_sync
(EMailDisplay *display,
GCancellable *cancellable,
diff --git a/src/mail/e-mail-reader-utils.c b/src/mail/e-mail-reader-utils.c
index e95f743..a996990 100644
--- a/src/mail/e-mail-reader-utils.c
+++ b/src/mail/e-mail-reader-utils.c
@@ -2398,7 +2398,7 @@ e_mail_reader_reply_to_message (EMailReader *reader,
EMailReplyStyle reply_style;
EWebView *web_view;
struct _camel_header_raw *header;
- gboolean src_is_html = FALSE;
+ gboolean src_is_text_html = FALSE;
const gchar *uid;
gchar *selection = NULL;
gint length;
@@ -2502,12 +2502,17 @@ e_mail_reader_reply_to_message (EMailReader *reader,
goto whole_message;
content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (src_message));
- src_is_html = camel_content_type_is (content_type, "text", "html");
- if (src_is_html)
- selection = e_web_view_get_selection_content_html_sync (web_view, NULL, NULL);
- else
+ if (camel_content_type_is (content_type, "text", "plain")) {
selection = e_mail_display_get_selection_plain_text_sync (display, NULL, NULL);
+ src_is_text_html = TRUE;
+ } else if (camel_content_type_is (content_type, "text", "html")) {
+ selection = e_web_view_get_selection_content_html_sync (E_WEB_VIEW (display), NULL, NULL);
+ src_is_text_html = FALSE;
+ } else if (camel_content_type_is (content_type, "multipart", "*")) {
+ selection = e_mail_display_get_selection_content_multipart_sync (display, &src_is_text_html,
NULL, NULL);
+ }
+
if (selection == NULL || *selection == '\0')
goto whole_message;
@@ -2540,7 +2545,7 @@ e_mail_reader_reply_to_message (EMailReader *reader,
CAMEL_MIME_PART (new_message),
selection,
length,
- src_is_html ? "text/html; charset=utf-8" : "text/plain; charset=utf-8");
+ src_is_text_html ? "text/html; charset=utf-8" : "text/plain; charset=utf-8");
ccd = g_new0 (CreateComposerData, 1);
ccd->reader = g_object_ref (reader);
diff --git a/src/web-extensions/e-dom-utils.c b/src/web-extensions/e-dom-utils.c
index 4d790ca..0330346 100644
--- a/src/web-extensions/e-dom-utils.c
+++ b/src/web-extensions/e-dom-utils.c
@@ -159,6 +159,36 @@ element_is_in_pre_tag (WebKitDOMNode *node)
}
static gchar *
+dom_selection_get_content_html (WebKitDOMDOMSelection *dom_selection,
+ WebKitDOMDocument *content_document)
+{
+ gchar *inner_html;
+ WebKitDOMDocumentFragment *fragment;
+ WebKitDOMNode *node;
+ WebKitDOMElement *element;
+ WebKitDOMRange *range = NULL;
+
+ range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, 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);
+
+ inner_html = webkit_dom_element_get_inner_html (element);
+
+ node = webkit_dom_range_get_start_container (range, NULL);
+ if (element_is_in_pre_tag (node)) {
+ gchar *tmp = inner_html;
+ inner_html = g_strconcat ("<pre>", tmp, "</pre>", NULL);
+ g_free (tmp);
+ }
+
+ g_clear_object (&range);
+ return inner_html;
+}
+
+static gchar *
get_frame_selection_html (WebKitDOMElement *iframe)
{
WebKitDOMDocument *content_document;
@@ -177,37 +207,10 @@ get_frame_selection_html (WebKitDOMElement *iframe)
dom_selection = webkit_dom_dom_window_get_selection (dom_window);
g_clear_object (&dom_window);
if (dom_selection && (webkit_dom_dom_selection_get_range_count (dom_selection) > 0)) {
- WebKitDOMRange *range = NULL;
- WebKitDOMElement *element;
- WebKitDOMDocumentFragment *fragment;
-
- range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
- if (range != NULL) {
- gchar *inner_html;
- WebKitDOMNode *node;
-
- 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);
-
- inner_html = webkit_dom_element_get_inner_html (element);
-
- node = webkit_dom_range_get_start_container (range, NULL);
- if (element_is_in_pre_tag (node)) {
- gchar *tmp = inner_html;
- inner_html = g_strconcat ("<pre>", tmp, "</pre>", NULL);
- g_free (tmp);
- }
+ gchar *html = dom_selection_get_content_html (dom_selection, content_document);
+ g_clear_object (&dom_selection);
- g_clear_object (&range);
- g_clear_object (&dom_selection);
- return inner_html;
- }
+ return html;
}
g_clear_object (&dom_selection);
@@ -216,16 +219,15 @@ get_frame_selection_html (WebKitDOMElement *iframe)
length = webkit_dom_html_collection_get_length (frames);
for (ii = 0; ii < length; ii++) {
WebKitDOMNode *node;
- gchar *text;
+ gchar *html;
node = webkit_dom_html_collection_item (frames, ii);
- text = get_frame_selection_html (
- WEBKIT_DOM_ELEMENT (node));
+ html = get_frame_selection_html (WEBKIT_DOM_ELEMENT (node));
- if (text != NULL) {
+ if (html != NULL) {
g_clear_object (&frames);
- return text;
+ return html;
}
}
@@ -266,6 +268,20 @@ e_dom_utils_get_selection_content_html (WebKitDOMDocument *document)
}
static gchar *
+dom_selection_get_content_text (WebKitDOMDOMSelection *dom_selection)
+{
+ WebKitDOMRange *range = NULL;
+ gchar *text = NULL;
+
+ range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+ if (range)
+ text = webkit_dom_range_to_string (range, NULL);
+ g_clear_object (&range);
+
+ return text;
+}
+
+static gchar *
get_frame_selection_content_text (WebKitDOMElement *iframe)
{
WebKitDOMDocument *content_document;
@@ -284,13 +300,7 @@ get_frame_selection_content_text (WebKitDOMElement *iframe)
dom_selection = webkit_dom_dom_window_get_selection (dom_window);
g_clear_object (&dom_window);
if (dom_selection && (webkit_dom_dom_selection_get_range_count (dom_selection) > 0)) {
- WebKitDOMRange *range = NULL;
- gchar *text = NULL;
-
- range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
- if (range)
- text = webkit_dom_range_to_string (range, NULL);
- g_clear_object (&range);
+ gchar *text = dom_selection_get_content_text (dom_selection);
g_clear_object (&dom_selection);
return text;
}
@@ -345,6 +355,94 @@ e_dom_utils_get_selection_content_text (WebKitDOMDocument *document)
return NULL;
}
+static gchar *
+get_frame_selection_content_multipart (WebKitDOMElement *iframe,
+ gboolean *is_html)
+{
+ WebKitDOMDocument *content_document;
+ WebKitDOMDOMWindow *dom_window = NULL;
+ WebKitDOMDOMSelection *dom_selection = NULL;
+ WebKitDOMHTMLCollection *frames = NULL;
+ gulong ii, length;
+
+ content_document = webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe));
+
+ if (!content_document)
+ return NULL;
+
+ dom_window = webkit_dom_document_get_default_view (content_document);
+ dom_selection = webkit_dom_dom_window_get_selection (dom_window);
+ g_clear_object (&dom_window);
+ if (dom_selection && (webkit_dom_dom_selection_get_range_count (dom_selection) > 0)) {
+ gchar *content;
+ gchar *uri = webkit_dom_document_get_document_uri (content_document);
+
+ /* The URI is url encoded.. */
+ if (strstr (uri, "mime_type=text%2Fplain")) {
+ content = dom_selection_get_content_text (dom_selection);
+ if (is_html)
+ *is_html = FALSE;
+ } else {
+ content = dom_selection_get_content_html (dom_selection, content_document);
+ if (is_html)
+ *is_html = TRUE;
+ }
+
+ g_clear_object (&dom_selection);
+ return content;
+ }
+ g_clear_object (&dom_selection);
+
+ frames = webkit_dom_document_get_elements_by_tag_name_as_html_collection (content_document, "iframe");
+ length = webkit_dom_html_collection_get_length (frames);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node;
+ gchar *content;
+
+ node = webkit_dom_html_collection_item (frames, ii);
+
+ content = get_frame_selection_content_multipart (WEBKIT_DOM_ELEMENT (node), is_html);
+
+ if (content != NULL) {
+ g_clear_object (&frames);
+ return content;
+ }
+ }
+
+ g_clear_object (&frames);
+ return NULL;
+}
+
+gchar *
+e_dom_utils_get_selection_content_multipart (WebKitDOMDocument *document,
+ gboolean *is_html)
+{
+ WebKitDOMHTMLCollection *frames = NULL;
+ gulong ii, length;
+
+ frames = webkit_dom_document_get_elements_by_tag_name_as_html_collection (document, "iframe");
+ length = webkit_dom_html_collection_get_length (frames);
+
+ for (ii = 0; ii < length; ii++) {
+ gchar *text;
+ WebKitDOMNode *node;
+
+ node = webkit_dom_html_collection_item (frames, ii);
+
+ text = get_frame_selection_content_multipart (
+ WEBKIT_DOM_ELEMENT (node), is_html);
+
+ if (text != NULL) {
+ g_clear_object (&frames);
+ return text;
+ }
+ }
+
+ g_clear_object (&frames);
+ return NULL;
+}
+
void
e_dom_utils_create_and_add_css_style_sheet (WebKitDOMDocument *document,
const gchar *style_sheet_id)
diff --git a/src/web-extensions/e-dom-utils.h b/src/web-extensions/e-dom-utils.h
index 0a7d536..5f0d503 100644
--- a/src/web-extensions/e-dom-utils.h
+++ b/src/web-extensions/e-dom-utils.h
@@ -42,6 +42,9 @@ gchar * e_dom_utils_get_selection_content_html
(WebKitDOMDocument *document);
gchar * e_dom_utils_get_selection_content_text
(WebKitDOMDocument *document);
+gchar * e_dom_utils_get_selection_content_multipart
+ (WebKitDOMDocument *document,
+ gboolean *is_html);
void e_dom_utils_create_and_add_css_style_sheet
(WebKitDOMDocument *document,
const gchar *style_sheet_id);
diff --git a/src/web-extensions/e-web-extension.c b/src/web-extensions/e-web-extension.c
index d053d2e..c63ce89 100644
--- a/src/web-extensions/e-web-extension.c
+++ b/src/web-extensions/e-web-extension.c
@@ -105,6 +105,11 @@ static const char introspection_xml[] =
" <arg type='t' name='page_id' direction='in'/>"
" <arg type='s' name='text_content' direction='out'/>"
" </method>"
+" <method name='GetSelectionContentMultipart'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='content' direction='out'/>"
+" <arg type='b' name='is_html' direction='out'/>"
+" </method>"
" <method name='CreateAndAddCSSStyleSheet'>"
" <arg type='t' name='page_id' direction='in'/>"
" <arg type='s' name='style_sheet_id' direction='in'/>"
@@ -538,6 +543,26 @@ handle_method_call (GDBusConnection *connection,
"(@s)",
g_variant_new_take_string (
html_content ? html_content : g_strdup (""))));
+ } else if (g_strcmp0 (method_name, "GetSelectionContentMultipart") == 0) {
+ gchar *text_content;
+ gboolean is_html = FALSE;
+
+ 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_multipart (document, &is_html);
+
+ g_dbus_method_invocation_return_value (
+ invocation,
+ g_variant_new (
+ "(@sb)",
+ g_variant_new_take_string (
+ text_content ? text_content : g_strdup ("")),
+ is_html));
} else if (g_strcmp0 (method_name, "GetSelectionContentText") == 0) {
gchar *text_content;
@@ -551,7 +576,11 @@ handle_method_call (GDBusConnection *connection,
text_content = e_dom_utils_get_selection_content_text (document);
g_dbus_method_invocation_return_value (
- invocation, g_variant_new_take_string (text_content));
+ invocation,
+ g_variant_new (
+ "(@s)",
+ g_variant_new_take_string (
+ text_content ? text_content : g_strdup (""))));
} else if (g_strcmp0 (method_name, "AddCSSRuleIntoStyleSheet") == 0) {
const gchar *style_sheet_id, *selector, *style;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]