From d73ddbba36468ffdf4d443b95e7d5dd9ff406f8d Mon Sep 17 00:00:00 2001 From: Tomas Popela Date: Mon, 2 Feb 2015 12:50:47 +0100 Subject: [PATCH] Backport the WebKit composer patches --- evolution-3.13.10-composer-backports.patch | 742 +++++++++++++++++++++ evolution.spec | 9 +- 2 files changed, 750 insertions(+), 1 deletion(-) create mode 100644 evolution-3.13.10-composer-backports.patch diff --git a/evolution-3.13.10-composer-backports.patch b/evolution-3.13.10-composer-backports.patch new file mode 100644 index 0000000..59e0c62 --- /dev/null +++ b/evolution-3.13.10-composer-backports.patch @@ -0,0 +1,742 @@ +diff --git a/e-util/e-html-editor-selection.c b/e-util/e-html-editor-selection.c +index 254f820..baa5b38 100644 +--- a/e-util/e-html-editor-selection.c ++++ b/e-util/e-html-editor-selection.c +@@ -1347,22 +1347,22 @@ set_block_alignment (WebKitDOMElement *element, + static WebKitDOMNode * + get_parent_block_node_from_child (WebKitDOMNode *node) + { +- WebKitDOMElement *parent = WEBKIT_DOM_ELEMENT ( +- webkit_dom_node_get_parent_node (node)); ++ WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node); + +- if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) || +- element_has_tag (parent, "b") || +- element_has_tag (parent, "i") || +- element_has_tag (parent, "u")) +- parent = WEBKIT_DOM_ELEMENT ( +- webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (parent))); ++ if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-temp-text-wrapper") || ++ element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quoted") || ++ element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quote-character") || ++ element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-signature") || ++ WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) || ++ element_has_tag (WEBKIT_DOM_ELEMENT (parent), "b") || ++ element_has_tag (WEBKIT_DOM_ELEMENT (parent), "i") || ++ element_has_tag (WEBKIT_DOM_ELEMENT (parent), "u")) ++ parent = webkit_dom_node_get_parent_node (parent); + +- if (element_has_class (parent, "-x-evo-temp-text-wrapper") || +- element_has_class (parent, "-x-evo-signature")) +- parent = WEBKIT_DOM_ELEMENT ( +- webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (parent))); ++ if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quoted")) ++ parent = webkit_dom_node_get_parent_node (parent); + +- return WEBKIT_DOM_NODE (parent); ++ return parent; + } + + /** +@@ -3771,7 +3771,7 @@ e_html_editor_selection_set_monospaced (EHTMLEditorSelection *selection, + range, WEBKIT_DOM_NODE (monospace), NULL); + + e_html_editor_selection_move_caret_into_element ( +- document, monospace); ++ document, monospace, FALSE); + } + } else { + gboolean is_bold, is_italic, is_underline, is_strikethrough; +@@ -4857,7 +4857,8 @@ e_html_editor_selection_replace_image_src (EHTMLEditorSelection *selection, + + void + e_html_editor_selection_move_caret_into_element (WebKitDOMDocument *document, +- WebKitDOMElement *element) ++ WebKitDOMElement *element, ++ gboolean to_start) + { + WebKitDOMDOMWindow *window; + WebKitDOMDOMSelection *window_selection; +@@ -4871,8 +4872,8 @@ e_html_editor_selection_move_caret_into_element (WebKitDOMDocument *document, + new_range = webkit_dom_document_create_range (document); + + webkit_dom_range_select_node_contents ( +- new_range, WEBKIT_DOM_NODE (element), NULL); +- webkit_dom_range_collapse (new_range, FALSE, NULL); ++ new_range, WEBKIT_DOM_NODE (element), NULL); ++ webkit_dom_range_collapse (new_range, to_start, NULL); + webkit_dom_dom_selection_remove_all_ranges (window_selection); + webkit_dom_dom_selection_add_range (window_selection, new_range); + } +@@ -5071,13 +5072,13 @@ e_html_editor_selection_restore_caret_position (EHTMLEditorSelection *selection) + remove_node (WEBKIT_DOM_NODE (element)); + + e_html_editor_selection_move_caret_into_element ( +- document, WEBKIT_DOM_ELEMENT (next_sibling)); ++ document, WEBKIT_DOM_ELEMENT (next_sibling), FALSE); + + goto out; + } + } + +- e_html_editor_selection_move_caret_into_element (document, element); ++ e_html_editor_selection_move_caret_into_element (document, element, FALSE); + + if (fix_after_quoting) { + prev_sibling = webkit_dom_node_get_previous_sibling ( +@@ -6054,6 +6055,8 @@ e_html_editor_selection_save (EHTMLEditorSelection *selection) + parent_node, marker_node, split_node, NULL); + } + ++ webkit_dom_node_normalize (parent_node); ++ + end_marker: + marker = webkit_dom_document_create_element (document, "SPAN", NULL); + webkit_dom_element_set_id (marker, "-x-evo-selection-end-marker"); +@@ -6084,8 +6087,15 @@ e_html_editor_selection_save (EHTMLEditorSelection *selection) + WEBKIT_DOM_NODE (marker), + next_sibling, + NULL); +- return; ++ } else { ++ webkit_dom_node_insert_before ( ++ node, ++ WEBKIT_DOM_NODE (marker), ++ webkit_dom_node_get_next_sibling ( ++ webkit_dom_node_get_parent_node (parent_node)), ++ NULL); + } ++ return; + } + + if (WEBKIT_DOM_IS_TEXT (container)) { +@@ -6138,11 +6148,27 @@ e_html_editor_selection_save (EHTMLEditorSelection *selection) + if (split_node) { + parent_node = webkit_dom_node_get_parent_node (split_node); + +- webkit_dom_node_insert_before ( +- parent_node, marker_node, split_node, NULL); +- } else +- webkit_dom_node_append_child ( +- WEBKIT_DOM_NODE (container), marker_node, NULL); ++ if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent_node)) { ++ webkit_dom_node_append_child ( ++ webkit_dom_node_get_previous_sibling (split_node), ++ marker_node, ++ NULL); ++ } else ++ webkit_dom_node_insert_before ( ++ parent_node, marker_node, split_node, NULL); ++ } else { ++ WebKitDOMNode *first_child; ++ ++ first_child = webkit_dom_node_get_first_child (container); ++ if (offset == 0 && WEBKIT_DOM_IS_TEXT (first_child)) ++ webkit_dom_node_insert_before ( ++ WEBKIT_DOM_NODE (container), marker_node, webkit_dom_node_get_first_child (container), NULL); ++ else ++ webkit_dom_node_append_child ( ++ WEBKIT_DOM_NODE (container), marker_node, NULL); ++ } ++ ++ webkit_dom_node_normalize (parent_node); + + check: + if ((next_sibling = webkit_dom_node_get_next_sibling (marker_node))) { +diff --git a/e-util/e-html-editor-selection.h b/e-util/e-html-editor-selection.h +index 3290dfe..5ae9492 100644 +--- a/e-util/e-html-editor-selection.h ++++ b/e-util/e-html-editor-selection.h +@@ -185,7 +185,8 @@ void e_html_editor_selection_insert_image + const gchar *image_uri); + void e_html_editor_selection_move_caret_into_element + (WebKitDOMDocument *document, +- WebKitDOMElement *element); ++ WebKitDOMElement *element, ++ gboolean to_start); + void e_html_editor_selection_clear_caret_position_marker + (EHTMLEditorSelection *selection); + WebKitDOMNode * +diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c +index cb97da3..aeea625 100644 +--- a/e-util/e-html-editor-view.c ++++ b/e-util/e-html-editor-view.c +@@ -699,12 +699,18 @@ get_parent_block_node_from_child (WebKitDOMNode *node) + WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node); + + if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-temp-text-wrapper") || ++ element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quoted") || ++ element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quote-character") || ++ element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-signature") || + WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) || + element_has_tag (WEBKIT_DOM_ELEMENT (parent), "b") || + element_has_tag (WEBKIT_DOM_ELEMENT (parent), "i") || + element_has_tag (WEBKIT_DOM_ELEMENT (parent), "u")) + parent = webkit_dom_node_get_parent_node (parent); + ++ if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quoted")) ++ parent = webkit_dom_node_get_parent_node (parent); ++ + return parent; + } + +@@ -1044,17 +1050,21 @@ move_elements_to_body (WebKitDOMDocument *document) + list = webkit_dom_document_query_selector_all ( + document, "span.-x-evo-to-body[data-credits]", NULL); + for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) { +- WebKitDOMNode *child; ++ char *credits; ++ WebKitDOMElement *pre_element; + WebKitDOMNode *node = webkit_dom_node_list_item (list, ii); + +- while ((child = webkit_dom_node_get_first_child (node))) { +- webkit_dom_node_insert_before ( +- WEBKIT_DOM_NODE (body), +- child, +- webkit_dom_node_get_first_child ( +- WEBKIT_DOM_NODE (body)), +- NULL); +- } ++ pre_element = webkit_dom_document_create_element (document, "pre", NULL); ++ credits = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "data-credits"); ++ webkit_dom_html_element_set_inner_text (WEBKIT_DOM_HTML_ELEMENT (pre_element), credits, NULL); ++ g_free (credits); ++ ++ webkit_dom_node_insert_before ( ++ WEBKIT_DOM_NODE (body), ++ WEBKIT_DOM_NODE (pre_element), ++ webkit_dom_node_get_first_child ( ++ WEBKIT_DOM_NODE (body)), ++ NULL); + + remove_node (node); + } +@@ -2131,6 +2141,57 @@ register_input_event_listener_on_body (EHTMLEditorView *view) + } + + static void ++remove_empty_blocks (WebKitDOMDocument *document) ++{ ++ gint ii, length; ++ WebKitDOMNodeList *list; ++ ++ list = webkit_dom_document_query_selector_all ( ++ document, "blockquote[type=cite] > :empty", NULL); ++ ++ length = webkit_dom_node_list_get_length (list); ++ for (ii = 0; ii < length; ii++) ++ remove_node (webkit_dom_node_list_item (list, ii)); ++ ++ g_object_unref (list); ++} ++ ++/* Following two functions are used when deleting the selection inside ++ * the quoted content. The thing is that normally the quote marks are not ++ * selectable by user. But this caused a lof of problems for WebKit when removing ++ * the selection. This will avoid it as when the delete or backspace key is pressed ++ * we will make the quote marks user selectable so they will act as any other text. ++ * On HTML keyup event callback we will make them again non-selectable. */ ++static void ++disable_quote_marks_select (WebKitDOMDocument *document) ++{ ++ WebKitDOMHTMLHeadElement *head; ++ WebKitDOMElement *style_element; ++ ++ head = webkit_dom_document_get_head (document); ++ ++ if (!webkit_dom_document_get_element_by_id (document, "-x-evo-quote-style")) { ++ style_element = webkit_dom_document_create_element (document, "style", NULL); ++ webkit_dom_element_set_id (style_element, "-x-evo-quote-style"); ++ webkit_dom_html_element_set_inner_html ( ++ WEBKIT_DOM_HTML_ELEMENT (style_element), ++ ".-x-evo-quoted { -webkit-user-select: none; }", ++ NULL); ++ webkit_dom_node_append_child ( ++ WEBKIT_DOM_NODE (head), WEBKIT_DOM_NODE (style_element), NULL); ++ } ++} ++ ++static void ++enable_quote_marks_select (WebKitDOMDocument *document) ++{ ++ WebKitDOMElement *style_element; ++ ++ if ((style_element = webkit_dom_document_get_element_by_id (document, "-x-evo-quote-style"))) ++ remove_node (WEBKIT_DOM_NODE (style_element)); ++} ++ ++static void + body_keyup_event_cb (WebKitDOMElement *element, + WebKitDOMUIEvent *event, + EHTMLEditorView *view) +@@ -2150,99 +2211,100 @@ body_keyup_event_cb (WebKitDOMElement *element, + * BackSpace or Delete. */ + gint level; + WebKitDOMElement *selection_start_marker, *selection_end_marker; +- WebKitDOMElement *br_element; ++ WebKitDOMElement *tmp_element; + WebKitDOMDocument *document; +- WebKitDOMNode *node, *parent; ++ WebKitDOMNode *parent; ++ ++ if (e_html_editor_view_get_html_mode (view)) ++ return; + + document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element)); + ++ disable_quote_marks_select (document); ++ /* Remove empty blocks if presented. */ ++ remove_empty_blocks (document); ++ + e_html_editor_selection_save (selection); + selection_start_marker = webkit_dom_document_get_element_by_id ( + document, "-x-evo-selection-start-marker"); + selection_end_marker = webkit_dom_document_get_element_by_id ( + document, "-x-evo-selection-end-marker"); + +- level = get_citation_level ( +- WEBKIT_DOM_NODE (selection_start_marker), FALSE); +- if (level == 0) +- goto restore; +- +- node = webkit_dom_node_get_previous_sibling ( +- WEBKIT_DOM_NODE (selection_start_marker)); +- +- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (node)) +- node = webkit_dom_node_get_previous_sibling (node); +- +- if (node) +- goto restore; +- +- parent = get_parent_block_node_from_child ( +- WEBKIT_DOM_NODE (selection_start_marker)); +- +- node = webkit_dom_node_get_previous_sibling (parent); +- if (!node) { +- /* Situation where the start of the selection was in the +- * multiple quoted content and that start on the beginning +- * of the citation. +- * +- * > +- * >> | +- * >> xx|x +- * */ +- node = webkit_dom_node_get_parent_node (parent); +- if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node)) +- goto restore; +- node = webkit_dom_node_get_previous_sibling (node); +- if (!node) +- goto restore; +- if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (webkit_dom_node_get_parent_node (node))) +- goto restore; ++ /* If we deleted a selection the caret will be inside the quote marks, fix it. */ ++ parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (selection_start_marker)); ++ if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quote-character")) { ++ webkit_dom_node_insert_before ( ++ webkit_dom_node_get_parent_node ( ++ webkit_dom_node_get_parent_node (parent)), ++ WEBKIT_DOM_NODE (selection_end_marker), ++ webkit_dom_node_get_next_sibling ( ++ webkit_dom_node_get_parent_node (parent)), ++ NULL); ++ webkit_dom_node_insert_before ( ++ webkit_dom_node_get_parent_node ( ++ webkit_dom_node_get_parent_node (parent)), ++ WEBKIT_DOM_NODE (selection_start_marker), ++ webkit_dom_node_get_next_sibling ( ++ webkit_dom_node_get_parent_node (parent)), ++ NULL); + } + +- br_element = webkit_dom_element_query_selector ( +- WEBKIT_DOM_ELEMENT (node), "span.-x-evo-quote-character > br", NULL); +- if (br_element) { +- WebKitDOMNode *tmp; +- +- if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node)) { +- /* We have to select the right block when the selection +- * started on the end of the citation that is +- * inside another citation. +- * +- * >>| +- * > xx|x +- */ +- /* */ +- node = webkit_dom_node_get_parent_node ( +- WEBKIT_DOM_NODE (br_element)); +- /* */ +- node = webkit_dom_node_get_parent_node (node); +- /* right block */ +- node = webkit_dom_node_get_parent_node (node); +- } ++ /* Under some circumstances we will end with block inside the citation ++ * that has the quote marks removed and we have to reinsert them back. */ ++ level = get_citation_level (WEBKIT_DOM_NODE (selection_start_marker), FALSE); ++ if (level > 0) { ++ WebKitDOMNode *prev_sibling; + +- webkit_dom_node_append_child ( +- node, WEBKIT_DOM_NODE (selection_start_marker), NULL); ++ prev_sibling = webkit_dom_node_get_previous_sibling ( ++ WEBKIT_DOM_NODE (selection_start_marker)); ++ if (!prev_sibling || ++ (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling) && ++ !webkit_dom_node_get_previous_sibling (prev_sibling))) { ++ WebKitDOMElement *block; ++ ++ block = WEBKIT_DOM_ELEMENT (get_parent_block_node_from_child ( ++ WEBKIT_DOM_NODE (selection_start_marker))); ++ if (element_has_class (block, "-x-evo-paragraph")) { ++ gint length, word_wrap_length; ++ ++ word_wrap_length = e_html_editor_selection_get_word_wrap_length (selection); ++ length = word_wrap_length - 2 * (level - 1); ++ block = e_html_editor_selection_wrap_paragraph_length ( ++ selection, block, length); ++ webkit_dom_node_normalize (WEBKIT_DOM_NODE (block)); ++ } ++ quote_plain_text_element_after_wrapping ( ++ document, block, level); ++ } ++ } + +- while ((tmp = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (selection_end_marker)))) +- webkit_dom_node_append_child (node, tmp, NULL); ++ /* Situation where the start of the selection was in the beginning ++ * of the block in quoted content and the end in the beginning of ++ * content that is after the citation or the selection end was in ++ * the end of the quoted content (showed by ^). The correct structure ++ * in these cases is to have empty block after the citation. ++ * ++ * > |xxx ++ * > xxx^ ++ * |xxx ++ * */ ++ tmp_element = webkit_dom_document_get_element_by_id (document, "-x-evo-tmp-block"); ++ if (tmp_element) { ++ remove_wrapping_from_element (tmp_element); ++ remove_quoting_from_element (tmp_element); ++ webkit_dom_element_remove_attribute (tmp_element, "id"); ++ ++ parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (tmp_element)); ++ while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (webkit_dom_node_get_parent_node (parent))) ++ parent = webkit_dom_node_get_parent_node (parent); + + webkit_dom_node_insert_before ( +- node, +- WEBKIT_DOM_NODE (selection_end_marker), +- webkit_dom_node_get_next_sibling ( +- WEBKIT_DOM_NODE (selection_start_marker)), ++ webkit_dom_node_get_parent_node (parent), ++ WEBKIT_DOM_NODE (tmp_element), ++ webkit_dom_node_get_next_sibling (parent), + NULL); +- +- if (!WEBKIT_DOM_IS_HTMLBR_ELEMENT (webkit_dom_node_get_last_child (node))) +- webkit_dom_node_append_child ( +- node, WEBKIT_DOM_NODE (br_element), NULL); +- else +- remove_node (WEBKIT_DOM_NODE (br_element)); +- +- remove_node (parent); + } +- restore: ++ + e_html_editor_selection_restore (selection); + } else if (key_code == HTML_KEY_CODE_CONTROL) + html_editor_view_set_links_active (view, FALSE); +@@ -2825,6 +2887,127 @@ change_quoted_block_to_normal (EHTMLEditorView *view) + } + + static gboolean ++fix_structure_after_delete_before_quoted_content (EHTMLEditorView *view) ++{ ++ EHTMLEditorSelection *selection; ++ gboolean collapsed = FALSE; ++ WebKitDOMDocument *document; ++ WebKitDOMElement *selection_start_marker, *selection_end_marker; ++ WebKitDOMNode *block, *node; ++ ++ selection = e_html_editor_view_get_selection (view); ++ ++ collapsed = e_html_editor_selection_is_collapsed (selection); ++ ++ e_html_editor_selection_save (selection); ++ ++ document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); ++ selection_start_marker = webkit_dom_document_query_selector ( ++ document, "span#-x-evo-selection-start-marker", NULL); ++ selection_end_marker = webkit_dom_document_query_selector ( ++ document, "span#-x-evo-selection-end-marker", NULL); ++ ++ if (!selection_start_marker || !selection_end_marker) ++ return FALSE; ++ ++ if (collapsed) { ++ WebKitDOMNode *next_sibling; ++ ++ block = get_parent_block_node_from_child ( ++ WEBKIT_DOM_NODE (selection_start_marker)); ++ ++ next_sibling = webkit_dom_node_get_next_sibling (block); ++ ++ /* Next block is quoted content */ ++ if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (next_sibling)) ++ goto restore; ++ ++ /* Delete was pressed in block without any content */ ++ if (webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (selection_start_marker))) ++ goto restore; ++ ++ /* If there is just BR element go ahead */ ++ node = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (selection_end_marker)); ++ if (node && !WEBKIT_DOM_IS_HTMLBR_ELEMENT (node)) ++ goto restore; ++ else { ++ /* Remove the empty block and move caret into the beginning of the citation */ ++ remove_node (block); ++ ++ e_html_editor_selection_move_caret_into_element ( ++ document, WEBKIT_DOM_ELEMENT (next_sibling), TRUE); ++ ++ return TRUE; ++ } ++ } else { ++ WebKitDOMNode *end_block; ++ ++ /* Let the quote marks be selectable to nearly correctly remove the ++ * selection. Corrections after are done in body_keyup_event_cb. */ ++ enable_quote_marks_select (document); ++ ++ node = webkit_dom_node_get_previous_sibling ( ++ WEBKIT_DOM_NODE (selection_start_marker)); ++ ++ if (!node || !WEBKIT_DOM_IS_ELEMENT (node)) ++ goto restore; ++ ++ if (!element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-quoted")) ++ goto restore; ++ ++ webkit_dom_node_insert_before ( ++ webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (node)), ++ WEBKIT_DOM_NODE (selection_start_marker), ++ WEBKIT_DOM_NODE (node), ++ NULL); ++ ++ block = get_parent_block_node_from_child ( ++ WEBKIT_DOM_NODE (selection_start_marker)); ++ end_block = get_parent_block_node_from_child ( ++ WEBKIT_DOM_NODE (selection_end_marker)); ++ ++ /* Situation where the start of the selection is in the beginning ++ * of the block in quoted content and the end in the beginning of ++ * content that is after the citation or the selection end is in ++ * the end of the quoted content (showed by ^). We have to ++ * mark the start block to correctly restore the structure ++ * afterwards. ++ * ++ * > |xxx ++ * > xxx^ ++ * |xxx ++ * */ ++ if (get_citation_level (end_block, FALSE) > 0) { ++ WebKitDOMNode *parent; ++ ++ if (webkit_dom_node_get_next_sibling (end_block)) ++ goto restore; ++ ++ parent = webkit_dom_node_get_parent_node (end_block); ++ while (parent && WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent)) { ++ WebKitDOMNode *next_parent = webkit_dom_node_get_parent_node (parent); ++ ++ if (webkit_dom_node_get_next_sibling (parent) && ++ !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (next_parent)) ++ goto restore; ++ ++ parent = next_parent; ++ } ++ } ++ node = webkit_dom_node_get_next_sibling ( ++ WEBKIT_DOM_NODE (selection_end_marker)); ++ if (!node || WEBKIT_DOM_IS_HTMLBR_ELEMENT (node)) { ++ webkit_dom_element_set_id ( ++ WEBKIT_DOM_ELEMENT (block), "-x-evo-tmp-block"); ++ } ++ } ++ restore: ++ e_html_editor_selection_restore (selection); ++ ++ return FALSE; ++} ++ ++static gboolean + html_editor_view_key_press_event (GtkWidget *widget, + GdkEventKey *event) + { +@@ -2916,6 +3099,10 @@ html_editor_view_key_press_event (GtkWidget *widget, + return TRUE; + } + ++ if (event->keyval == GDK_KEY_Delete || event->keyval == GDK_KEY_BackSpace) ++ if (fix_structure_after_delete_before_quoted_content (view)) ++ return TRUE; ++ + /* Chain up to parent's key_press_event() method. */ + return GTK_WIDGET_CLASS (e_html_editor_view_parent_class)-> + key_press_event (widget, event); +@@ -4570,6 +4757,9 @@ clear_attributes (WebKitDOMDocument *document) + while (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head))) + remove_node (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head))); + ++ /* Make the quote marks non-selectable. */ ++ disable_quote_marks_select (document); ++ + /* Remove non Evolution attributes from BODY element */ + attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body)); + length = webkit_dom_named_node_map_get_length (attributes); +@@ -4718,16 +4908,20 @@ html_editor_convert_view_content (EHTMLEditorView *view, + document, "span.-x-evo-to-body[data-credits]", NULL); + length = webkit_dom_node_list_get_length (list); + for (ii = 0; ii < length; ii++) { +- WebKitDOMNode *node, *child; ++ char *credits; ++ WebKitDOMElement *pre_element; ++ WebKitDOMNode *node = webkit_dom_node_list_item (list, ii); + +- node = webkit_dom_node_list_item (list, ii); +- while ((child = webkit_dom_node_get_first_child (node))) { +- webkit_dom_node_insert_before ( +- WEBKIT_DOM_NODE (wrapper), +- child, +- WEBKIT_DOM_NODE (content_wrapper), +- NULL); +- } ++ pre_element = webkit_dom_document_create_element (document, "pre", NULL); ++ credits = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "data-credits"); ++ webkit_dom_html_element_set_inner_text (WEBKIT_DOM_HTML_ELEMENT (pre_element), credits, NULL); ++ g_free (credits); ++ ++ webkit_dom_node_insert_before ( ++ WEBKIT_DOM_NODE (wrapper), ++ WEBKIT_DOM_NODE (pre_element), ++ WEBKIT_DOM_NODE (content_wrapper), ++ NULL); + + remove_node (node); + } +@@ -4927,6 +5121,8 @@ html_editor_view_insert_converted_html_into_selection (EHTMLEditorView *view, + document, "-x-evo-selection-end-marker"); + current_block = get_parent_block_node_from_child ( + WEBKIT_DOM_NODE (selection_start_marker)); ++ if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (current_block)) ++ current_block = NULL; + + element = webkit_dom_document_create_element (document, "div", NULL); + if (is_html) { +@@ -6230,9 +6426,6 @@ process_elements (EHTMLEditorView *view, + remove_base_attributes (WEBKIT_DOM_ELEMENT (child)); + remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child)); + } +- if (!changing_mode && to_plain_text) +- if (!webkit_dom_node_has_child_nodes (child)) +- g_string_append (buffer, "\n"); + } + + /* Signature */ +@@ -6261,7 +6454,6 @@ process_elements (EHTMLEditorView *view, + WEBKIT_DOM_HTML_ELEMENT (child)); + g_string_append (buffer, content); + g_free (content); +- skip_node = TRUE; + } + skip_node = TRUE; + goto next; +@@ -7043,6 +7235,9 @@ html_editor_view_load_status_changed (EHTMLEditorView *view) + webkit_dom_element_set_attribute ( + WEBKIT_DOM_ELEMENT (body), "data-message", "", NULL); + ++ /* Make the quote marks non-selectable. */ ++ disable_quote_marks_select (document); ++ + if (view->priv->convert_in_situ) { + html_editor_convert_view_content (view, NULL); + view->priv->convert_in_situ = FALSE; +@@ -7057,7 +7252,7 @@ html_editor_view_load_status_changed (EHTMLEditorView *view) + if (webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (body), "data-evo-draft")) { + /* Restore the selection how it was when the draft was saved */ + e_html_editor_selection_move_caret_into_element ( +- document, WEBKIT_DOM_ELEMENT (body)); ++ document, WEBKIT_DOM_ELEMENT (body), FALSE); + e_html_editor_selection_restore ( + e_html_editor_view_get_selection (view)); + } +@@ -7812,7 +8007,8 @@ e_html_editor_view_update_fonts (EHTMLEditorView *view) + " font-family: '%s';\n" + " font-size: %dpt;\n" + " font-weight: %d;\n" +- " font-style: %s;\n", ++ " font-style: %s;\n" ++ " -webkit-line-break: after-white-space;\n", + pango_font_description_get_family (vw), + pango_font_description_get_size (vw) / PANGO_SCALE, + pango_font_description_get_weight (vw), +@@ -8007,13 +8203,6 @@ e_html_editor_view_update_fonts (EHTMLEditorView *view) + + g_string_append (stylesheet, "}\n"); + +- g_string_append ( +- stylesheet, +- ".-x-evo-quoted " +- "{\n" +- " -webkit-user-select: none;\n" +- "}\n"); +- + g_string_append_printf ( + stylesheet, + ".-x-evo-quote-character " +diff --git a/em-format/e-mail-formatter-quote.c b/em-format/e-mail-formatter-quote.c +index 4df8be6..1916bba 100644 +--- a/em-format/e-mail-formatter-quote.c ++++ b/em-format/e-mail-formatter-quote.c +@@ -122,7 +122,7 @@ mail_formatter_quote_run (EMailFormatter *formatter, + * the special span element and it will be moved to body in EHTMLEditorView */ + if (qf->priv->credits && *qf->priv->credits) { + gchar *credits = g_strdup_printf ( +- "
%s
", ++ "", + qf->priv->credits); + g_output_stream_write_all ( + stream, credits, strlen (credits), NULL, cancellable, NULL); +@@ -133,7 +133,7 @@ mail_formatter_quote_run (EMailFormatter *formatter, + * after the message and cite it in EHTMLEditorView because of reasons + * mentioned above */ + if (qf->priv->flags & E_MAIL_FORMATTER_QUOTE_FLAG_CITE) { +- string = ""; ++ string = ""; + g_output_stream_write_all ( + stream, string, strlen (string), NULL, cancellable, NULL); + } +diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c +index 795ac9e..fcba621 100644 +--- a/mail/em-composer-utils.c ++++ b/mail/em-composer-utils.c +@@ -2871,8 +2871,7 @@ composer_set_body (EMsgComposer *composer, + original = quoting_text (QUOTING_ORIGINAL); + text = em_utils_message_to_html ( + session, message, original, E_MAIL_FORMATTER_QUOTE_FLAG_HEADERS, +- parts_list, "", +- "", &validity_found); ++ parts_list, NULL, NULL, &validity_found); + e_msg_composer_set_body_text (composer, text, TRUE); + g_free (text); + g_free (original); +@@ -2885,8 +2884,7 @@ composer_set_body (EMsgComposer *composer, + credits = attribution_format (message); + text = em_utils_message_to_html ( + session, message, credits, E_MAIL_FORMATTER_QUOTE_FLAG_CITE, +- parts_list, "", +- "", &validity_found); ++ parts_list, NULL, NULL, &validity_found); + g_free (credits); + e_msg_composer_set_body_text (composer, text, TRUE); + g_free (text); diff --git a/evolution.spec b/evolution.spec index 099aab6..b4fdefc 100644 --- a/evolution.spec +++ b/evolution.spec @@ -30,7 +30,7 @@ Name: evolution Version: 3.13.10 -Release: 1%{?dist} +Release: 2%{?dist} Group: Applications/Productivity Summary: Mail and calendar client for GNOME License: GPLv2+ and GFDL @@ -50,6 +50,9 @@ Patch01: evolution-1.4.4-ldap-x86_64-hack.patch # RH bug #589555 Patch02: evolution-2.30.1-help-contents.patch +# Backport WebKit composer fixes to test them in the wild +Patch03: evolution-3.13.10-composer-backports.patch + ## Dependencies ### Requires: gvfs @@ -216,6 +219,7 @@ the functionality of the installed %{name} package. %setup -q -n evolution-%{version} %patch01 -p1 -b .ldaphack %patch02 -p1 -b .help-contents +%patch03 -p1 -b .composer_backports # Remove the welcome email from Novell for inbox in mail/default/*/Inbox; do @@ -543,6 +547,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/installed-tests %changelog +* Mon Feb 02 2015 Tomas Popela - 3.13.10-2 +- Backport the WebKit composer patches + * Mon Jan 26 2015 Milan Crha - 3.13.10-1 - Update to 3.13.10