diff options
author | Tomas Popela <tpopela@redhat.com> | 2016-02-02 11:34:46 +0100 |
---|---|---|
committer | Tomas Popela <tpopela@redhat.com> | 2016-02-02 11:47:06 +0100 |
commit | 72fa566afe888d6d1b766b05198b64f88625f520 (patch) | |
tree | e5d2f5bbbb5c56c88d3a3ba878f0b0b7672faf13 | |
parent | c45c433d0d65497bffe1268023e729e62cb91b76 (diff) | |
download | evolution-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.c | 134 |
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, 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); } |