[evolution/wip/webkit-composer] Fix various bugs in plain text citation quoting



commit bb917654fb6496e5396079e5ae7bc1c1800f7553
Author: Tomas Popela <tpopela redhat com>
Date:   Thu Jan 23 14:38:49 2014 +0100

    Fix various bugs in plain text citation quoting

 e-util/e-editor-selection.c |   97 +++++++++++++++++++++++++++++++++----------
 e-util/e-editor-widget.c    |   87 +++++++++++++++++++++++++++++---------
 2 files changed, 141 insertions(+), 43 deletions(-)
---
diff --git a/e-util/e-editor-selection.c b/e-util/e-editor-selection.c
index 4454fba..727665f 100644
--- a/e-util/e-editor-selection.c
+++ b/e-util/e-editor-selection.c
@@ -3404,6 +3404,44 @@ e_editor_selection_save_caret_position (EEditorSelection *selection)
                NULL);
 }
 
+static void
+fix_quoting_nodes_after_caret_restoration (WebKitDOMDOMSelection *window_selection,
+                                           WebKitDOMNode *prev_sibling,
+                                           WebKitDOMNode *next_sibling)
+{
+       WebKitDOMNode *tmp_node;
+
+       if (!element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper"))
+               return;
+
+       webkit_dom_dom_selection_modify (
+               window_selection, "move", "right", "character");
+       tmp_node = webkit_dom_node_get_next_sibling (
+               webkit_dom_node_get_first_child (prev_sibling));
+
+       webkit_dom_node_insert_before (
+               webkit_dom_node_get_parent_node (prev_sibling),
+               tmp_node,
+               next_sibling,
+               NULL);
+
+       tmp_node = webkit_dom_node_get_first_child (prev_sibling);
+
+       webkit_dom_node_insert_before (
+               webkit_dom_node_get_parent_node (prev_sibling),
+               tmp_node,
+               webkit_dom_node_get_previous_sibling (next_sibling),
+               NULL);
+
+       webkit_dom_node_remove_child (
+               webkit_dom_node_get_parent_node (prev_sibling),
+               prev_sibling,
+               NULL);
+
+       webkit_dom_dom_selection_modify (
+               window_selection, "move", "left", "character");
+}
+
 /**
  * e_editor_selection_restore_caret_position:
  * @selection: an #EEditorSelection
@@ -3416,6 +3454,7 @@ e_editor_selection_restore_caret_position (EEditorSelection *selection)
        EEditorWidget *widget;
        WebKitDOMDocument *document;
        WebKitDOMElement *element;
+       gboolean fix_after_quoting;
 
        g_return_if_fail (E_IS_EDITOR_SELECTION (selection));
 
@@ -3425,12 +3464,16 @@ e_editor_selection_restore_caret_position (EEditorSelection *selection)
        document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
        g_object_unref (widget);
 
-       element = webkit_dom_document_get_element_by_id (document, "-x-evo-caret-position");
+       element = webkit_dom_document_get_element_by_id (
+               document, "-x-evo-caret-position");
+       fix_after_quoting = element_has_class (element, "-x-evo-caret-quoting");
 
        if (element) {
                WebKitDOMDOMWindow *window;
                WebKitDOMNode *parent_node;
                WebKitDOMDOMSelection *window_selection;
+               WebKitDOMNode *prev_sibling;
+               WebKitDOMNode *next_sibling;
 
                window = webkit_dom_document_get_default_view (document);
                window_selection = webkit_dom_dom_window_get_selection (window);
@@ -3438,42 +3481,52 @@ e_editor_selection_restore_caret_position (EEditorSelection *selection)
                /* If parent is BODY element, we try to restore the position on the 
                 * element that is next to us */
                if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent_node)) {
-
-                       WebKitDOMNode *next_sibling;
-
                        /* Look if we have DIV on right */
-                       next_sibling = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (element));
-
+                       next_sibling = webkit_dom_node_get_next_sibling (
+                               WEBKIT_DOM_NODE (element));
                        if (element_has_class (WEBKIT_DOM_ELEMENT (next_sibling), "-x-evo-paragraph")) {
                                webkit_dom_node_remove_child (
-                                       webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+                                       webkit_dom_node_get_parent_node (
+                                               WEBKIT_DOM_NODE (element)),
                                        WEBKIT_DOM_NODE (element),
                                        NULL);
 
-                               move_caret_into_element (document, WEBKIT_DOM_ELEMENT (next_sibling));
-
-                               /* FIXME If caret position is restored and afterwards the position is saved
-                                * it is not on the place where it supposed to be (it is in the beginning of
-                                * parent's element. It can be avoided by moving with the caret. */
-                               webkit_dom_dom_selection_modify (window_selection, "move", "left", 
"character");
-                               webkit_dom_dom_selection_modify (window_selection, "move", "right", 
"character");
+                               move_caret_into_element (
+                                       document, WEBKIT_DOM_ELEMENT (next_sibling));
 
-                               webkit_dom_node_normalize (parent_node);
-                               return;
+                               goto out;
                        }
                }
 
                move_caret_into_element (document, element);
+
+               if (fix_after_quoting) {
+                       prev_sibling = webkit_dom_node_get_previous_sibling (
+                               WEBKIT_DOM_NODE (element));
+                       next_sibling = webkit_dom_node_get_next_sibling (
+                               WEBKIT_DOM_NODE (element));
+                       if (!next_sibling)
+                               fix_after_quoting = FALSE;
+               }
+
                webkit_dom_node_remove_child (
-                       webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+                       webkit_dom_node_get_parent_node (
+                               WEBKIT_DOM_NODE (element)),
                        WEBKIT_DOM_NODE (element),
                        NULL);
 
-               /* FIXME If caret position is restored and afterwards the position is saved
-                * it is not on the place where it supposed to be (it is in the beginning of
-                * parent's element. It can be avoided by moving with the caret. */
-               webkit_dom_dom_selection_modify (window_selection, "move", "left", "character");
-               webkit_dom_dom_selection_modify (window_selection, "move", "right", "character");
+               if (fix_after_quoting)
+                       fix_quoting_nodes_after_caret_restoration (
+                               window_selection, prev_sibling, next_sibling);
+ out:
+               /* FIXME If caret position is restored and afterwards the
+                * position is saved it is not on the place where it supposed
+                * to be (it is in the beginning of parent's element. It can
+                * be avoided by moving with the caret. */
+               webkit_dom_dom_selection_modify (
+                       window_selection, "move", "left", "character");
+               webkit_dom_dom_selection_modify (
+                       window_selection, "move", "right", "character");
 
                webkit_dom_node_normalize (parent_node);
        }
diff --git a/e-util/e-editor-widget.c b/e-util/e-editor-widget.c
index b2ad57d..acbf46e 100644
--- a/e-util/e-editor-widget.c
+++ b/e-util/e-editor-widget.c
@@ -1725,11 +1725,18 @@ quote_node (WebKitDOMDocument *document,
                WebKitDOMNode *next_sibling;
                gboolean skip_first = FALSE;
                gboolean insert_newline = FALSE;
+               gboolean is_html_node = FALSE;
 
                prev_sibling = webkit_dom_node_get_previous_sibling (node);
                next_sibling = webkit_dom_node_get_next_sibling (node);
 
-               if (prev_sibling && WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling))
+               is_html_node =
+                       WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling) ||
+                       element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "b") ||
+                       element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "i") ||
+                       element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "u");
+
+               if (prev_sibling && is_html_node)
                        skip_first = TRUE;
 
                /* Skip the BR between first blockquote and pre */
@@ -1772,7 +1779,8 @@ quote_node (WebKitDOMDocument *document,
 static void
 insert_quote_symbols_before_node (WebKitDOMDocument *document,
                                   WebKitDOMNode *node,
-                                 gint quote_level)
+                                  gint quote_level,
+                                  gboolean is_html_node)
 {
        gchar *indent;
        gchar *content;
@@ -1783,15 +1791,35 @@ insert_quote_symbols_before_node (WebKitDOMDocument *document,
        element_add_class (element, "-x-evo-quoted");
        content = g_strconcat (indent, " ", NULL);
        webkit_dom_html_element_set_inner_text (
-                       WEBKIT_DOM_HTML_ELEMENT (element),
-                       content,
+               WEBKIT_DOM_HTML_ELEMENT (element),
+               content,
+               NULL);
+
+       if (is_html_node) {
+               WebKitDOMElement *new_br;
+
+               new_br = webkit_dom_document_create_element (document, "br", NULL);
+               element_add_class (new_br, "-x-evo-temp-br");
+
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_parent_node (node),
+                       WEBKIT_DOM_NODE (new_br),
+                       node,
                        NULL);
+       }
 
        webkit_dom_node_insert_before (
+               webkit_dom_node_get_parent_node (node),
+               WEBKIT_DOM_NODE (element),
+               node,
+               NULL);
+
+       if (is_html_node) {
+               webkit_dom_node_remove_child (
                        webkit_dom_node_get_parent_node (node),
-                       WEBKIT_DOM_NODE (element),
                        node,
                        NULL);
+       }
 
        g_free (indent);
        g_free (content);
@@ -1805,6 +1833,7 @@ quote_plain_text_recursive (WebKitDOMDocument *document,
 {
        gboolean skip_node = FALSE;
        gboolean move_next = FALSE;
+       gboolean suppress_next = FALSE;
 
        node = webkit_dom_node_get_first_child (node);
 
@@ -1814,7 +1843,7 @@ quote_plain_text_recursive (WebKitDOMDocument *document,
 
                if (WEBKIT_DOM_IS_TEXT (node)) {
                        /* Start quoting after we are in blockquote */
-                       if (quote_level > 0) {
+                       if (quote_level > 0 && !suppress_next) {
                                WebKitDOMNode *next_sibling;
 
                                /* When quoting text node, we are wrappering it and
@@ -1825,29 +1854,48 @@ quote_plain_text_recursive (WebKitDOMDocument *document,
                                quote_node (document, node, quote_level);
                                node = next_sibling;
                                skip_node = TRUE;
-                       }
+                       } else
+                               suppress_next = FALSE;
+
+                       goto next_node;
+               }
+
+               if (element_has_id (WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-position")) {
+                       if (quote_level > 0)
+                               element_add_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-quoting");
+
+                       move_next = TRUE;
+                       suppress_next = TRUE;
 
                        goto next_node;
                }
 
                if (WEBKIT_DOM_IS_ELEMENT (node) || WEBKIT_DOM_IS_HTML_ELEMENT (node)) {
                        if (webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (node)) == 0) {
-                               /* We have to treat anchors separately to avoid
-                                * modifications of it's inner text */
-                               if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) {
+                               /* Even in plain text mode we can have some basic html element
+                                * like anchor and others. When Forwaring e-mail as Quoted EMFormat
+                                * generates header that contatains <b> tags (bold font).
+                                * We have to treat these elements separately to avoid
+                                * modifications of theirs inner texts */
+                               gboolean is_html_node =
+                                       WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) ||
+                                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "b") ||
+                                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "i") ||
+                                       element_has_tag (WEBKIT_DOM_ELEMENT (node), "u");
+
+                               if (is_html_node) {
                                        WebKitDOMNode *prev_sibling;
 
                                        prev_sibling = webkit_dom_node_get_previous_sibling (node);
                                        if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling)) {
                                                insert_quote_symbols_before_node (
-                                                       document,
-                                                       prev_sibling,
-                                                       quote_level);
+                                                       document, prev_sibling, quote_level, TRUE);
                                        }
                                        move_next = TRUE;
 
                                        goto next_node;
                                }
+
                                /* If element doesn't have children, we can quote it */
                                if (is_citation_node (node)) {
                                        /* Citation with just text inside */
@@ -1865,7 +1913,8 @@ quote_plain_text_recursive (WebKitDOMDocument *document,
                                                next_sibling = webkit_dom_node_get_next_sibling (node);
 
                                                /* Situation when anchors are alone on line */
-                                               if (element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), 
"-x-evo-temp-text-wrapper") &&
+                                               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+                                                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), 
"-x-evo-temp-text-wrapper") &&
                                                    WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (next_sibling)) {
                                                        gchar *text_content;
 
@@ -1873,9 +1922,7 @@ quote_plain_text_recursive (WebKitDOMDocument *document,
 
                                                        if (g_str_has_suffix (text_content, "\n")) {
                                                                insert_quote_symbols_before_node (
-                                                                       document,
-                                                                       node,
-                                                                       quote_level);
+                                                                       document, node, quote_level, FALSE);
                                                                webkit_dom_node_remove_child (
                                                                        webkit_dom_node_get_parent_node 
(node),
                                                                        node,
@@ -1897,7 +1944,7 @@ quote_plain_text_recursive (WebKitDOMDocument *document,
                                                        content = g_strconcat (
                                                                "<span class=\"-x-evo-quoted\">",
                                                                indent,
-                                                               "</span><br class=\"-x-evo-temp-br\">",
+                                                               " </span><br class=\"-x-evo-temp-br\">",
                                                                NULL);
 
                                                        webkit_dom_html_element_set_outer_html (
@@ -1914,9 +1961,7 @@ quote_plain_text_recursive (WebKitDOMDocument *document,
                                                }
                                                if (is_citation_node (prev_sibling)) {
                                                        insert_quote_symbols_before_node (
-                                                               document,
-                                                               node,
-                                                               quote_level);
+                                                               document, node, quote_level, FALSE);
                                                }
                                        }
                                        quote_node (document, node, quote_level);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]