[evolution/wip/webkit-composer] When generating the HTML code of the message write the additional data after the message



commit 1fccc43f55f8c43929a852e7e6546e8e0ec405fc
Author: Tomas Popela <tpopela redhat com>
Date:   Fri Feb 21 22:23:01 2014 +0100

    When generating the HTML code of the message write the additional data after the message
    
    Before this change we were putting BR elements and also the credits
    before the actual HTML code of the message. But this was wrong as when
    WebKit was loading the given HTML code that looked like
    <br>CREDITS<html>MESSAGE_CODE</html> WebKit parsed it like
    <html><br>CREDITS</html><html>MESSAGE_CODE</html>. As no elements are
    allowed outside of HTML root element WebKit wrapped them into another
    HTML root element. Afterwards the first root element was treated as the
    primary one and all the elements from the second's root HEAD and BODY
    elements were moved from to the first one. Thus the HTML that was loaded
    into composer contained the i.e. META or STYLE definitions in the body.
    With this change we are putting and wrapping the elements behind the
    message and afterwards moving them into the body. Also when we need to
    cite the whole body of the message we're appending the span with
    -x-evo-cite-body class to the message.

 composer/e-composer-private.c                |   29 ++++++++++---
 e-util/e-editor-widget.c                     |   57 ++++++++++++++++++++++++++
 em-format/e-mail-formatter-quote-text-html.c |    2 +-
 em-format/e-mail-formatter-quote.c           |   48 +++++++++++----------
 4 files changed, 106 insertions(+), 30 deletions(-)
---
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index a9246b3..ca3d642 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -886,6 +886,8 @@ composer_move_caret (EMsgComposer *composer)
                        WEBKIT_DOM_ELEMENT (element), "-x-evo-input-start");
                webkit_dom_html_element_set_inner_html (
                        WEBKIT_DOM_HTML_ELEMENT (element), UNICODE_ZERO_WIDTH_SPACE, NULL);
+               if (top_signature)
+                       element_add_class (element, "-x-evo-top-signature");
        }
 
        if (start_bottom) {
@@ -959,7 +961,8 @@ composer_move_caret (EMsgComposer *composer)
                        }
                }
 
-               webkit_dom_range_select_node_contents (new_range,
+               webkit_dom_range_select_node_contents (
+                       new_range,
                        WEBKIT_DOM_NODE (
                                webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body))),
                        NULL);
@@ -1140,11 +1143,15 @@ insert:
                                WEBKIT_DOM_HTML_ELEMENT (element), html_buffer->str, NULL);
 
                        if (top_signature) {
+                               WebKitDOMNode *signature_inserted;
                                WebKitDOMNode *child =
                                        webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+                               WebKitDOMElement *br =
+                                       webkit_dom_document_create_element (
+                                               document, "br", NULL);
 
                                if (start_bottom) {
-                                       webkit_dom_node_insert_before (
+                                       signature_inserted = webkit_dom_node_insert_before (
                                                WEBKIT_DOM_NODE (body),
                                                WEBKIT_DOM_NODE (element),
                                                child,
@@ -1155,7 +1162,7 @@ insert:
                                                        document, "-x-evo-input-start");
                                        /* When we are using signature on top the caret
                                         * should be before the signature */
-                                       webkit_dom_node_insert_before (
+                                       signature_inserted = webkit_dom_node_insert_before (
                                                WEBKIT_DOM_NODE (body),
                                                WEBKIT_DOM_NODE (element),
                                                input_start ?
@@ -1164,6 +1171,12 @@ insert:
                                                        child,
                                                NULL);
                                }
+
+                               webkit_dom_node_insert_before (
+                                       WEBKIT_DOM_NODE (body),
+                                       WEBKIT_DOM_NODE (br),
+                                       webkit_dom_node_get_next_sibling (signature_inserted),
+                                       NULL);
                        } else {
                                webkit_dom_node_append_child (
                                        WEBKIT_DOM_NODE (body),
@@ -1196,7 +1209,9 @@ composer_web_view_load_status_changed_cb (WebKitWebView *webkit_web_view,
                return;
 
        g_signal_handlers_disconnect_by_func (
-               webkit_web_view, G_CALLBACK (composer_web_view_load_status_changed_cb), NULL);
+               webkit_web_view,
+               G_CALLBACK (composer_web_view_load_status_changed_cb),
+               NULL);
 
        e_composer_update_signature (composer);
 }
@@ -1227,10 +1242,12 @@ e_composer_update_signature (EMsgComposer *composer)
                /* Disconnect previous handlers */
                g_signal_handlers_disconnect_by_func (
                        WEBKIT_WEB_VIEW (editor_widget),
-                       G_CALLBACK (composer_web_view_load_status_changed_cb), composer);
+                       G_CALLBACK (composer_web_view_load_status_changed_cb),
+                       composer);
                g_signal_connect (
                        WEBKIT_WEB_VIEW(editor_widget), "notify::load-status",
-                       G_CALLBACK (composer_web_view_load_status_changed_cb), composer);
+                       G_CALLBACK (composer_web_view_load_status_changed_cb),
+                       composer);
                return;
        }
 
diff --git a/e-util/e-editor-widget.c b/e-util/e-editor-widget.c
index 6d94928..cd12056 100644
--- a/e-util/e-editor-widget.c
+++ b/e-util/e-editor-widget.c
@@ -473,6 +473,60 @@ change_cid_images_src_to_base64 (EEditorWidget *widget)
        g_hash_table_remove_all (widget->priv->inline_images);
 }
 
+/* For purpose of this function see e-mail-formatter-quote.c */
+static void
+put_body_in_citation (WebKitDOMDocument *document)
+{
+       WebKitDOMElement *cite_body = webkit_dom_document_query_selector (
+               document, "span.-x-evo-cite-body", NULL);
+
+       if (cite_body) {
+               WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
+               gchar *inner_html, *with_citation;
+
+               webkit_dom_node_remove_child (
+                       WEBKIT_DOM_NODE (body),
+                       WEBKIT_DOM_NODE (cite_body),
+                       NULL);
+
+               inner_html = webkit_dom_html_element_get_inner_html (body);
+               with_citation = g_strconcat (
+                       "<blockquote type=\"cite\">", inner_html, "</span>", NULL);
+               webkit_dom_html_element_set_inner_html (body, with_citation, NULL);
+               g_free (inner_html);
+               g_free (with_citation);
+       }
+}
+
+/* For purpose of this function see e-mail-formatter-quote.c */
+static void
+move_elements_to_body (WebKitDOMDocument *document)
+{
+       WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
+       WebKitDOMNodeList *list;
+       gint ii;
+
+       list = webkit_dom_document_query_selector_all (
+               document, "span.-x-evo-to-body", NULL);
+       for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
+               WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
+
+               while (webkit_dom_node_has_child_nodes (node)) {
+                       webkit_dom_node_insert_before (
+                               WEBKIT_DOM_NODE (body),
+                               webkit_dom_node_get_first_child (node),
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (body)),
+                               NULL);
+               }
+
+               webkit_dom_node_remove_child (
+                       webkit_dom_node_get_parent_node (node),
+                       WEBKIT_DOM_NODE (node),
+                       NULL);
+       }
+}
+
 static void
 editor_widget_load_status_changed (EEditorWidget *widget)
 {
@@ -484,7 +538,10 @@ editor_widget_load_status_changed (EEditorWidget *widget)
                return;
 
        widget->priv->reload_in_progress = FALSE;
+
        document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
+       put_body_in_citation (document);
+       move_elements_to_body (document);
 
        /* Register on input event that is called when the content (body) is modified */
        webkit_dom_event_target_add_event_listener (
diff --git a/em-format/e-mail-formatter-quote-text-html.c b/em-format/e-mail-formatter-quote-text-html.c
index 7183fac..9adaf8b 100644
--- a/em-format/e-mail-formatter-quote-text-html.c
+++ b/em-format/e-mail-formatter-quote-text-html.c
@@ -58,7 +58,7 @@ emqfe_text_html_format (EMailFormatterExtension *extension,
        qf_context = (EMailFormatterQuoteContext *) context;
 
        camel_stream_write_string (
-               stream, "\n<!-- text/html -->\n", cancellable, NULL);
+               stream, "<!-- text/html -->", cancellable, NULL);
 
        if ((qf_context->qf_flags & E_MAIL_FORMATTER_QUOTE_FLAG_KEEP_SIG) == 0) {
                CamelMimeFilter *sig_strip;
diff --git a/em-format/e-mail-formatter-quote.c b/em-format/e-mail-formatter-quote.c
index 3868f66..bc46a55 100644
--- a/em-format/e-mail-formatter-quote.c
+++ b/em-format/e-mail-formatter-quote.c
@@ -57,7 +57,6 @@ mail_formatter_quote_run (EMailFormatter *formatter,
 {
        EMailFormatterQuote *qf;
        EMailFormatterQuoteContext *qf_context;
-       GSettings *settings;
        GQueue queue = G_QUEUE_INIT;
        GList *head, *link;
 
@@ -73,27 +72,6 @@ mail_formatter_quote_run (EMailFormatter *formatter,
                G_SEEKABLE (stream),
                0, G_SEEK_SET, NULL, NULL);
 
-       settings = g_settings_new ("org.gnome.evolution.mail");
-       if (g_settings_get_boolean (
-               settings, "composer-top-signature"))
-               camel_stream_write_string (
-                       stream, "<br>\n", cancellable, NULL);
-       g_object_unref (settings);
-
-       if (qf->priv->credits && *qf->priv->credits) {
-               gchar *credits = g_strdup_printf ("%s<br>", qf->priv->credits);
-               camel_stream_write_string (stream, credits, cancellable, NULL);
-               g_free (credits);
-       } else {
-               camel_stream_write_string (stream, "<br>", cancellable, NULL);
-       }
-
-       if (qf->priv->flags & E_MAIL_FORMATTER_QUOTE_FLAG_CITE) {
-               camel_stream_write_string (
-                       stream,
-                       "<blockquote type=cite>\n", cancellable, NULL);
-       }
-
        e_mail_part_list_queue_parts (context->part_list, NULL, &queue);
 
        head = g_queue_peek_head_link (&queue);
@@ -128,9 +106,33 @@ mail_formatter_quote_run (EMailFormatter *formatter,
        while (!g_queue_is_empty (&queue))
                g_object_unref (g_queue_pop_head (&queue));
 
+       /* Before we were inserting the BR elements and the credits in front of
+        * the actual HTML code of the message. But this was wrong as when WebKit
+        * was loading the given HTML code that looked like
+        * <br>CREDITS<html>MESSAGE_CODE</html> WebKit parsed it like
+        * <html><br>CREDITS</html><html>MESSAGE_CODE</html>. As no elements are
+        * allowed outside of the HTML root element WebKit wrapped them into
+        * another HTML root element. Afterwards the first root element was
+        * treated as the primary one and all the elements from the second's root
+        * HEAD and BODY elements were moved to the first one.
+        * Thus the HTML that was loaded into composer contained the i.e. META
+        * or STYLE definitions in the body.
+        * So if we want to put something into the message we have to put it into
+        * the special span element and it will be moved to body in EEditorWidget */
+       if (qf->priv->credits && *qf->priv->credits) {
+               gchar *credits = g_strdup_printf (
+                       "<span class=\"-x-evo-to-body\">%s</span>", qf->priv->credits);
+               camel_stream_write_string (stream, credits, cancellable, NULL);
+               g_free (credits);
+       }
+
+       /* If we want to cite the message we have to append the special span element
+        * after the message and cite it in EEditorWidget because of reasons
+        * mentioned above */
        if (qf->priv->flags & E_MAIL_FORMATTER_QUOTE_FLAG_CITE) {
                camel_stream_write_string (
-                       stream, "</blockquote>", cancellable, NULL);
+                       stream, "<span class=\"-x-evo-cite-body\"><span>",
+                       cancellable, NULL);
        }
 }
 


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