summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Popela <tpopela@redhat.com>2016-02-02 11:34:46 +0100
committerTomas Popela <tpopela@redhat.com>2016-02-02 11:47:06 +0100
commit72fa566afe888d6d1b766b05198b64f88625f520 (patch)
treee5d2f5bbbb5c56c88d3a3ba878f0b0b7672faf13
parentc45c433d0d65497bffe1268023e729e62cb91b76 (diff)
downloadevolution-72fa566afe888d6d1b766b05198b64f88625f520.tar.gz
Bug 759873 - Cursor jumps to bottom of mail when replying to a mail
Preserve the selection when generating the plain text version of message. Also improve the code that is used for marking citations and selection markers to avoid a manipulation with the inner HTML of the elements.
-rw-r--r--e-util/e-html-editor-view.c134
1 files changed, 78 insertions, 56 deletions
diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c
index 427a85f16e..1a2d66bd9b 100644
--- a/e-util/e-html-editor-view.c
+++ b/e-util/e-html-editor-view.c
@@ -7261,6 +7261,37 @@ check_if_end_paragraph (const gchar *input,
return FALSE;
}
+static void
+replace_selection_markers (gchar **text)
+{
+ if (!text)
+ return;
+
+ if (strstr (*text, "##SELECTION_START##")) {
+ GString *tmp;
+
+ tmp = e_str_replace_string (
+ *text,
+ "##SELECTION_START##",
+ "<span id=\"-x-evo-selection-start-marker\"></span>");
+
+ g_free (*text);
+ *text = g_string_free (tmp, FALSE);
+ }
+
+ if (strstr (*text, "##SELECTION_END##")) {
+ GString *tmp;
+
+ tmp = e_str_replace_string (
+ *text,
+ "##SELECTION_START##",
+ "<span id=\"-x-evo-selection-start-marker\"></span>");
+
+ g_free (*text);
+ *text = g_string_free (tmp, FALSE);
+ }
+}
+
/* This parses the HTML code (that contains just text, &nbsp; and BR elements)
* into paragraphs.
* HTML code in that format we can get by taking innerText from some element,
@@ -7366,9 +7397,6 @@ parse_html_into_paragraphs (EHTMLEditorView *view,
empty = !*truncated && strlen (rest) > 0;
- if (strchr (" +-@*=\t;#", *rest))
- preserve_block = FALSE;
-
rest_to_insert = g_regex_replace_eval (
regex_nbsp,
empty ? rest : truncated,
@@ -7380,6 +7408,11 @@ parse_html_into_paragraphs (EHTMLEditorView *view,
NULL);
g_free (truncated);
+ replace_selection_markers (&rest_to_insert);
+
+ if (strchr (" +-@*=\t;#", *rest))
+ preserve_block = FALSE;
+
if (surround_links_with_anchor (rest_to_insert)) {
gboolean is_email_address =
strstr (rest_to_insert, "@") &&
@@ -7558,6 +7591,8 @@ parse_html_into_paragraphs (EHTMLEditorView *view,
NULL);
g_free (truncated);
+ replace_selection_markers (&rest_to_insert);
+
if (surround_links_with_anchor (rest_to_insert)) {
gboolean is_email_address =
strstr (rest_to_insert, "@") &&
@@ -7753,42 +7788,19 @@ e_html_editor_view_insert_quoted_text (EHTMLEditorView *view,
static void
mark_citation (WebKitDOMElement *citation)
{
- gchar *inner_html, *surrounded;
-
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (citation));
-
- surrounded = g_strconcat (
- "<span>##CITATION_START##</span>", inner_html,
- "<span>##CITATION_END##</span>", NULL);
+ webkit_dom_html_element_insert_adjacent_text (
+ WEBKIT_DOM_HTML_ELEMENT (citation),
+ "beforebegin",
+ "##CITATION_START##",
+ NULL);
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (citation), surrounded, NULL);
+ webkit_dom_html_element_insert_adjacent_text (
+ WEBKIT_DOM_HTML_ELEMENT (citation),
+ "afterend",
+ "##CITATION_END##",
+ NULL);
element_add_class (citation, "marked");
-
- g_free (inner_html);
- g_free (surrounded);
-}
-
-static gint
-create_text_markers_for_citations_in_document (WebKitDOMDocument *document)
-{
- gint count = 0;
- WebKitDOMElement *citation;
-
- citation = webkit_dom_document_query_selector (
- document, "blockquote[type=cite]:not(.marked)", NULL);
-
- while (citation) {
- mark_citation (citation);
- count++;
-
- citation = webkit_dom_document_query_selector (
- document, "blockquote[type=cite]:not(.marked)", NULL);
- }
-
- return count;
}
static gint
@@ -7812,6 +7824,30 @@ create_text_markers_for_citations_in_element (WebKitDOMElement *element)
}
static void
+create_text_markers_for_selection_in_element (WebKitDOMElement *element)
+{
+ WebKitDOMElement *selection_marker;
+
+ selection_marker = webkit_dom_element_query_selector (
+ element, "#-x-evo-selection-start-marker", NULL);
+ if (selection_marker)
+ webkit_dom_html_element_insert_adjacent_text (
+ WEBKIT_DOM_HTML_ELEMENT (selection_marker),
+ "afterend",
+ "##SELECTION_START##",
+ NULL);
+
+ selection_marker = webkit_dom_element_query_selector (
+ element, "#-x-evo-selection-end-marker", NULL);
+ if (selection_marker)
+ webkit_dom_html_element_insert_adjacent_text (
+ WEBKIT_DOM_HTML_ELEMENT (selection_marker),
+ "afterend",
+ "##SELECTION_END##",
+ NULL);
+}
+
+static void
quote_plain_text_elements_after_wrapping_in_document (WebKitDOMDocument *document)
{
gint length, ii;
@@ -10074,16 +10110,12 @@ convert_element_from_html_to_plain_text (EHTMLEditorView *view,
gboolean *wrap,
gboolean *quote)
{
- EHTMLEditorSelection *selection;
gint blockquotes_count;
gchar *inner_text, *inner_html;
- gboolean restore = TRUE;
WebKitDOMDocument *document;
WebKitDOMElement *top_signature, *signature, *blockquote, *main_blockquote;
WebKitDOMNode *signature_clone, *from;
- selection = e_html_editor_view_get_selection (view);
-
document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
top_signature = webkit_dom_element_query_selector (
@@ -10097,19 +10129,8 @@ convert_element_from_html_to_plain_text (EHTMLEditorView *view,
document, "blockquote", NULL);
if (main_blockquote) {
- WebKitDOMElement *input_start;
-
webkit_dom_element_set_attribute (
blockquote, "type", "cite", NULL);
-
- input_start = webkit_dom_element_query_selector (
- element, "#-x-evo-input-start", NULL);
-
- restore = input_start ? TRUE : FALSE;
-
- if (input_start)
- add_selection_markers_into_element_start (
- document, WEBKIT_DOM_ELEMENT (input_start), NULL, NULL);
from = WEBKIT_DOM_NODE (main_blockquote);
} else {
if (signature) {
@@ -10121,8 +10142,8 @@ convert_element_from_html_to_plain_text (EHTMLEditorView *view,
from = WEBKIT_DOM_NODE (element);
}
- blockquotes_count = create_text_markers_for_citations_in_element (
- WEBKIT_DOM_ELEMENT (from));
+ blockquotes_count = create_text_markers_for_citations_in_element (WEBKIT_DOM_ELEMENT (from));
+ create_text_markers_for_selection_in_element (WEBKIT_DOM_ELEMENT (from));
inner_text = webkit_dom_html_element_get_inner_text (
WEBKIT_DOM_HTML_ELEMENT (from));
@@ -10189,9 +10210,6 @@ convert_element_from_html_to_plain_text (EHTMLEditorView *view,
g_free (inner_text);
g_free (inner_html);
-
- if (restore)
- e_html_editor_selection_restore (selection);
}
static gchar *
@@ -10218,6 +10236,8 @@ process_content_for_plain_text (EHTMLEditorView *view)
selection = e_html_editor_view_get_selection (view);
+ e_html_editor_selection_save (selection);
+
/* If composer is in HTML mode we have to move the content to plain version */
if (view->priv->html_mode) {
if (converted || is_from_new_message) {
@@ -10334,6 +10354,8 @@ process_content_for_plain_text (EHTMLEditorView *view)
else
g_object_unref (source);
+ e_html_editor_selection_restore (selection);
+
/* Return text content between <body> and </body> */
return g_string_free (plain_text, FALSE);
}