[evolution] EHTMLEditorView - Fix clipboard paste into quoted content



commit d4b8a56865843be13e7fa6b8990f8915024994e0
Author: Tomas Popela <tpopela redhat com>
Date:   Wed Jun 25 15:54:38 2014 +0200

    EHTMLEditorView - Fix clipboard paste into quoted content
    
    When pasting the text from clipboard into the quoted content in the composer
    paste it into it and not into the body.

 e-util/e-html-editor-view.c | 1293 ++++++++++++++++++++++---------------------
 1 files changed, 665 insertions(+), 628 deletions(-)
---
diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c
index 0afd7a3..80c952e 100644
--- a/e-util/e-html-editor-view.c
+++ b/e-util/e-html-editor-view.c
@@ -2653,6 +2653,626 @@ e_html_editor_view_class_init (EHTMLEditorViewClass *class)
 }
 
 static gboolean
+is_citation_node (WebKitDOMNode *node)
+{
+       char *value;
+
+       if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))
+               return FALSE;
+
+       value = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "type");
+
+       /* citation == <blockquote type='cite'> */
+       if (g_strcmp0 (value, "cite") == 0) {
+               g_free (value);
+               return TRUE;
+       } else {
+               g_free (value);
+               return FALSE;
+       }
+}
+
+static gchar *
+get_quotation_for_level (gint quote_level)
+{
+       gint ii;
+       GString *output = g_string_new ("");
+
+       for (ii = 0; ii < quote_level; ii++) {
+               g_string_append (output, "<span class=\"-x-evo-quote-character\">");
+               g_string_append (output, QUOTE_SYMBOL);
+               g_string_append (output, " ");
+               g_string_append (output, "</span>");
+       }
+
+       return g_string_free (output, FALSE);
+}
+
+static void
+insert_quote_symbols (WebKitDOMHTMLElement *element,
+                      gint quote_level,
+                      gboolean skip_first,
+                      gboolean insert_newline)
+{
+       gchar *text;
+       gint ii;
+       GString *output;
+       gchar *quotation;
+
+       if (!WEBKIT_DOM_IS_HTML_ELEMENT (element))
+               return;
+
+       text = webkit_dom_html_element_get_inner_html (element);
+       output = g_string_new ("");
+       quotation = get_quotation_for_level (quote_level);
+
+       if (g_strcmp0 (text, "\n") == 0) {
+               g_string_append (output, "<span class=\"-x-evo-quoted\">");
+               g_string_append (output, quotation);
+               g_string_append (output, "</span>");
+               g_string_append (output, "\n");
+       } else {
+               gchar **lines;
+
+               lines = g_strsplit (text, "\n", 0);
+
+               for (ii = 0; lines[ii]; ii++) {
+                       if (ii == 0 && skip_first) {
+                               if (g_strv_length (lines) == 1) {
+                                       g_strfreev (lines);
+                                       goto exit;
+                               }
+                               g_string_append (output, lines[ii]);
+                               g_string_append (output, "\n");
+                       }
+
+                       g_string_append (output, "<span class=\"-x-evo-quoted\">");
+                       g_string_append (output, quotation);
+                       g_string_append (output, "</span>");
+
+                       /* Insert line of text */
+                       g_string_append (output, lines[ii]);
+                       if ((ii == g_strv_length (lines) - 1) &&
+                           !g_str_has_suffix (text, "\n") && !insert_newline) {
+                               /* If we are on last line and node's text doesn't
+                                * end with \n, don't insert it */
+                               break;
+                       }
+                       g_string_append (output, "\n");
+               }
+
+               g_strfreev (lines);
+       }
+
+       webkit_dom_html_element_set_inner_html (element, output->str, NULL);
+ exit:
+       g_free (quotation);
+       g_free (text);
+       g_string_free (output, TRUE);
+}
+
+static void
+quote_node (WebKitDOMDocument *document,
+           WebKitDOMNode *node,
+           gint quote_level)
+{
+       gboolean skip_first = FALSE;
+       gboolean insert_newline = FALSE;
+       gboolean is_html_node = FALSE;
+       WebKitDOMElement *wrapper;
+       WebKitDOMNode *node_clone, *prev_sibling, *next_sibling;
+
+       /* Don't quote when we are not in citation */
+       if (quote_level == 0)
+               return;
+
+       if (WEBKIT_DOM_IS_COMMENT (node))
+               return;
+
+       if (WEBKIT_DOM_IS_HTML_ELEMENT (node)) {
+               insert_quote_symbols (
+                       WEBKIT_DOM_HTML_ELEMENT (node), quote_level, FALSE, FALSE);
+               return;
+       }
+
+       prev_sibling = webkit_dom_node_get_previous_sibling (node);
+       next_sibling = webkit_dom_node_get_next_sibling (node);
+
+       is_html_node =
+               !WEBKIT_DOM_IS_TEXT (prev_sibling) &&
+               !WEBKIT_DOM_IS_COMMENT (prev_sibling) && (
+               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 */
+       if (quote_level == 1 && next_sibling && WEBKIT_DOM_IS_HTML_PRE_ELEMENT (next_sibling))
+               return;
+
+       if (next_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (next_sibling) &&
+           WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (webkit_dom_node_get_next_sibling (next_sibling))) {
+               insert_newline = TRUE;
+       }
+
+       /* Do temporary wrapper */
+       wrapper = webkit_dom_document_create_element (document, "SPAN", NULL);
+       webkit_dom_element_set_class_name (wrapper, "-x-evo-temp-text-wrapper");
+
+       node_clone = webkit_dom_node_clone_node (node, TRUE);
+
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (wrapper),
+               node_clone,
+               NULL);
+
+       insert_quote_symbols (
+               WEBKIT_DOM_HTML_ELEMENT (wrapper),
+               quote_level,
+               skip_first,
+               insert_newline);
+
+       webkit_dom_node_replace_child (
+               webkit_dom_node_get_parent_node (node),
+               WEBKIT_DOM_NODE (wrapper),
+               node,
+               NULL);
+}
+
+static void
+insert_quote_symbols_before_node (WebKitDOMDocument *document,
+                                  WebKitDOMNode *node,
+                                  gint quote_level,
+                                  gboolean is_html_node)
+{
+       gchar *quotation;
+       WebKitDOMElement *element;
+
+       quotation = get_quotation_for_level (quote_level);
+       element = webkit_dom_document_create_element (document, "SPAN", NULL);
+       element_add_class (element, "-x-evo-quoted");
+       webkit_dom_html_element_set_inner_html (
+               WEBKIT_DOM_HTML_ELEMENT (element), quotation, 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)
+               remove_node (node);
+
+       g_free (quotation);
+}
+
+static gboolean
+element_is_selection_marker (WebKitDOMElement *element)
+{
+       gboolean is_marker = FALSE;
+
+       is_marker =
+               element_has_id (element, "-x-evo-selection-start-marker") ||
+               element_has_id (element, "-x-evo-selection-end-marker");
+
+       return is_marker;
+}
+
+static gboolean
+check_if_suppress_next_node (WebKitDOMNode *node)
+{
+       if (node && WEBKIT_DOM_IS_ELEMENT (node))
+               if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node)))
+                       if (!webkit_dom_node_get_previous_sibling (node))
+                               return FALSE;
+
+       return TRUE;
+}
+
+static void
+quote_plain_text_recursive (WebKitDOMDocument *document,
+                           WebKitDOMNode *node,
+                           WebKitDOMNode *start_node,
+                           gint quote_level)
+{
+       gboolean skip_node = FALSE;
+       gboolean move_next = FALSE;
+       gboolean suppress_next = FALSE;
+       gboolean is_html_node = FALSE;
+       WebKitDOMNode *next_sibling, *prev_sibling;
+
+       node = webkit_dom_node_get_first_child (node);
+
+       while (node) {
+               skip_node = FALSE;
+               move_next = FALSE;
+               is_html_node = FALSE;
+
+               if (WEBKIT_DOM_IS_COMMENT (node))
+                       goto next_node;
+
+               prev_sibling = webkit_dom_node_get_previous_sibling (node);
+               next_sibling = webkit_dom_node_get_next_sibling (node);
+
+               if (WEBKIT_DOM_IS_TEXT (node)) {
+                       /* Start quoting after we are in blockquote */
+                       if (quote_level > 0 && !suppress_next) {
+                               /* When quoting text node, we are wrappering it and
+                                * afterwards replacing it with that wrapper, thus asking
+                                * for next_sibling after quoting will return NULL bacause
+                                * that node don't exist anymore */
+                               quote_node (document, node, quote_level);
+                               node = next_sibling;
+                               skip_node = TRUE;
+                       } else
+                               suppress_next = FALSE;
+
+                       goto next_node;
+               }
+
+               if (!(WEBKIT_DOM_IS_ELEMENT (node) || WEBKIT_DOM_IS_HTML_ELEMENT (node)))
+                       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 (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node))) {
+                       move_next = TRUE;
+                       /* If there is collapsed selection in the beginning of line
+                        * we cannot suppress first text that is after the end of
+                        * selection */
+                       suppress_next = check_if_suppress_next_node (prev_sibling);
+                       goto next_node;
+               }
+
+               if (WEBKIT_DOM_IS_HTML_META_ELEMENT (node)) {
+                       goto next_node;
+               }
+               if (WEBKIT_DOM_IS_HTML_STYLE_ELEMENT (node)) {
+                       move_next = TRUE;
+                       goto next_node;
+               }
+               if (WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (node)) {
+                       move_next = TRUE;
+                       goto next_node;
+               }
+
+               if (webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (node)) != 0)
+                       goto with_children;
+
+               /* 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 */
+               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) {
+                       if (!prev_sibling)
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+
+                       if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling))
+                               insert_quote_symbols_before_node (
+                                       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 */
+                       quote_node (document, node, quote_level + 1);
+                       /* Set citation as quoted */
+                       element_add_class (
+                               WEBKIT_DOM_ELEMENT (node),
+                               "-x-evo-plaintext-quoted");
+
+                       move_next = TRUE;
+                       goto next_node;
+               }
+
+               if (!WEBKIT_DOM_IS_HTMLBR_ELEMENT (node))
+                       goto not_br;
+
+               if (!prev_sibling) {
+                       WebKitDOMNode *parent;
+
+                       parent = webkit_dom_node_get_parent_node (node);
+
+                       /* BR in the beginning of the citation */
+                       if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent))
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+               }
+
+               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+                   WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (next_sibling) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
+                       /* Situation when anchors are alone on line */
+                       gchar *text_content;
+
+                       text_content = webkit_dom_node_get_text_content (prev_sibling);
+
+                       if (g_str_has_suffix (text_content, "\n")) {
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+                               remove_node (node);
+                               g_free (text_content);
+                               node = next_sibling;
+                               skip_node = TRUE;
+                               goto next_node;
+                       }
+                       g_free (text_content);
+               }
+
+               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling)) {
+                       gchar *quotation, *content;
+
+                       quotation = get_quotation_for_level (quote_level);
+
+                       content = g_strconcat (
+                               "<span class=\"-x-evo-quoted\">",
+                               quotation,
+                               "</span><br class=\"-x-evo-temp-br\">",
+                               NULL);
+
+                       webkit_dom_html_element_set_outer_html (
+                               WEBKIT_DOM_HTML_ELEMENT (node),
+                               content,
+                               NULL);
+
+                       g_free (content);
+                       g_free (quotation);
+
+                       node = next_sibling;
+                       skip_node = TRUE;
+                       goto next_node;
+               }
+
+               if (!prev_sibling && !next_sibling) {
+                       WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
+
+                       if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent)) {
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+                       }
+               }
+
+               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
+                       gchar *text_content;
+
+                       text_content = webkit_dom_node_get_text_content (prev_sibling);
+                       if (g_strcmp0 (text_content, "") == 0)
+                               insert_quote_symbols_before_node (
+                                       document, node, quote_level, FALSE);
+
+                       g_free (text_content);
+               }
+
+               if (is_citation_node (prev_sibling)) {
+                       insert_quote_symbols_before_node (
+                               document, node, quote_level, FALSE);
+               }
+ not_br:
+               if (g_strcmp0 (webkit_dom_node_get_text_content (node), "") == 0) {
+                       move_next = TRUE;
+                       goto next_node;
+               }
+
+               quote_node (document, node, quote_level);
+
+               move_next = TRUE;
+               goto next_node;
+
+ with_children:
+               if (is_citation_node (node)) {
+                       /* Go deeper and increase level */
+                       quote_plain_text_recursive (
+                               document, node, start_node, quote_level + 1);
+                       /* set citation as quoted */
+                       element_add_class (
+                               WEBKIT_DOM_ELEMENT (node),
+                               "-x-evo-plaintext-quoted");
+                       move_next = TRUE;
+               } else {
+                       quote_plain_text_recursive (
+                               document, node, start_node, quote_level);
+                       move_next = TRUE;
+               }
+ next_node:
+               if (!skip_node) {
+                       /* Move to next node */
+                       if (!move_next && webkit_dom_node_has_child_nodes (node)) {
+                               node = webkit_dom_node_get_first_child (node);
+                       } else if (webkit_dom_node_get_next_sibling (node)) {
+                               node = webkit_dom_node_get_next_sibling (node);
+                       } else {
+                               return;
+                       }
+               }
+       }
+}
+
+WebKitDOMElement *
+e_html_editor_view_quote_plain_text_element (EHTMLEditorView *view,
+                                             WebKitDOMElement *element)
+{
+       WebKitDOMDocument *document;
+       WebKitDOMNode *element_clone;
+       WebKitDOMNodeList *list;
+       gint ii, length, level;
+
+       document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
+
+       element_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (element), TRUE);
+       level = get_citation_level (WEBKIT_DOM_NODE (element), TRUE);
+
+       /* Remove old quote characters if the exists */
+       list = webkit_dom_element_query_selector_all (
+               WEBKIT_DOM_ELEMENT (element_clone), "span.-x-evo-quoted", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for  (ii = 0; ii < length; ii++)
+               remove_node (webkit_dom_node_list_item (list, ii));
+
+       quote_plain_text_recursive (
+               document, element_clone, element_clone, level);
+
+       /* Replace old element with one, that is quoted */
+       webkit_dom_node_replace_child (
+               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+               element_clone,
+               WEBKIT_DOM_NODE (element),
+               NULL);
+
+       return WEBKIT_DOM_ELEMENT (element_clone);
+}
+
+/**
+ * e_html_editor_view_quote_plain_text:
+ * @view: an #EHTMLEditorView
+ *
+ * Quote text inside citation blockquotes in plain text mode.
+ *
+ * As this function is cloning and replacing all citation blockquotes keep on
+ * mind that any pointers to nodes inside these blockquotes will be invalidated.
+ */
+WebKitDOMElement *
+e_html_editor_view_quote_plain_text (EHTMLEditorView *view)
+{
+       WebKitDOMDocument *document;
+       WebKitDOMHTMLElement *body;
+       WebKitDOMNode *body_clone;
+       WebKitDOMNamedNodeMap *attributes;
+       WebKitDOMNodeList *list;
+       WebKitDOMElement *element;
+       gint ii, length;
+       gulong attributes_length;
+
+       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
+
+       /* Check if the document is already quoted */
+       element = webkit_dom_document_query_selector (
+               document, ".-x-evo-plaintext-quoted", NULL);
+       if (element)
+               return NULL;
+
+       body = webkit_dom_document_get_body (document);
+       body_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
+
+       /* Clean unwanted spaces before and after blockquotes */
+       list = webkit_dom_element_query_selector_all (
+               WEBKIT_DOM_ELEMENT (body_clone), "blockquote[type|=cite]", NULL);
+       length = webkit_dom_node_list_get_length (list);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *blockquote = webkit_dom_node_list_item (list, ii);
+               WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (blockquote);
+               WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (blockquote);
+
+               if (prev_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling))
+                       remove_node (prev_sibling);
+
+               if (next_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (next_sibling))
+                       remove_node (next_sibling);
+
+               if (webkit_dom_node_has_child_nodes (blockquote)) {
+                       WebKitDOMNode *child = webkit_dom_node_get_first_child (blockquote);
+                       if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child))
+                               remove_node (child);
+               }
+       }
+
+       quote_plain_text_recursive (document, body_clone, body_clone, 0);
+
+       /* Copy attributes */
+       attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
+       attributes_length = webkit_dom_named_node_map_get_length (attributes);
+       for (ii = 0; ii < attributes_length; ii++) {
+               gchar *name, *value;
+               WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
+
+               name = webkit_dom_node_get_local_name (node);
+               value = webkit_dom_node_get_node_value (node);
+
+               webkit_dom_element_set_attribute (
+                       WEBKIT_DOM_ELEMENT (body_clone), name, value, NULL);
+
+               g_free (name);
+               g_free (value);
+       }
+
+       /* Replace old BODY with one, that is quoted */
+       webkit_dom_node_replace_child (
+               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
+               body_clone,
+               WEBKIT_DOM_NODE (body),
+               NULL);
+
+       return WEBKIT_DOM_ELEMENT (body_clone);
+}
+
+/**
+ * e_html_editor_view_dequote_plain_text:
+ * @view: an #EHTMLEditorView
+ *
+ * Dequote already quoted plain text in editor.
+ * Editor have to be quoted with e_html_editor_view_quote_plain_text otherwise
+ * it's not working.
+ */
+void
+e_html_editor_view_dequote_plain_text (EHTMLEditorView *view)
+{
+       WebKitDOMDocument *document;
+       WebKitDOMNodeList *paragraphs;
+       gint length, ii;
+
+       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
+
+       paragraphs = webkit_dom_document_query_selector_all (
+               document, "blockquote.-x-evo-plaintext-quoted", NULL);
+       length = webkit_dom_node_list_get_length (paragraphs);
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMElement *element;
+
+               element = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (paragraphs, ii));
+
+               if (is_citation_node (WEBKIT_DOM_NODE (element))) {
+                       element_remove_class (element, "-x-evo-plaintext-quoted");
+                       remove_quoting_from_element (element);
+               }
+       }
+}
+
+static gboolean
 create_anchor_for_link (const GMatchInfo *info,
                         GString *res,
                         gpointer data)
@@ -2695,7 +3315,6 @@ create_anchor_for_link (const GMatchInfo *info,
        if (address_surrounded)
                g_string_append (res, "&gt;");
 
-       g_warning ("%s", res->str);
        g_free (match);
 
        return FALSE;
@@ -3255,9 +3874,11 @@ static void
 html_editor_view_insert_converted_html_into_selection (EHTMLEditorView *view,
                                                        WebKitDOMDocument *document_convertor)
 {
+       EHTMLEditorSelection *selection = e_html_editor_view_get_selection (view);
        gchar *inner_text, *inner_html;
+       gint citation_level;
        WebKitDOMDocument *document;
-       WebKitDOMElement *element;
+       WebKitDOMElement *caret, *element;
        WebKitDOMHTMLElement *convertor_body;
 
        document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
@@ -3271,20 +3892,56 @@ html_editor_view_insert_converted_html_into_selection (EHTMLEditorView *view,
        inner_html = webkit_dom_html_element_get_inner_html (
                WEBKIT_DOM_HTML_ELEMENT (element));
 
-       parse_html_into_paragraphs (
-               view, document, element, inner_html, FALSE);
-
+       parse_html_into_paragraphs (view, document, element, inner_html, FALSE);
        g_free (inner_html);
 
+       caret = e_html_editor_selection_save_caret_position (selection);
+       citation_level = get_citation_level (WEBKIT_DOM_NODE (caret), FALSE);
+       /* Pasting into citation */
+       if (citation_level > 0) {
+               WebKitDOMNode *parent;
+
+               parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (caret));
+               /* Pasting into empty line in citation */
+               if (is_citation_node (parent)) {
+                       quote_plain_text_recursive (
+                               document,
+                               WEBKIT_DOM_NODE (element),
+                               WEBKIT_DOM_NODE (element),
+                               citation_level);
+
+                       webkit_dom_node_insert_before (
+                               parent,
+                               WEBKIT_DOM_NODE (element),
+                               webkit_dom_node_get_next_sibling (
+                                       WEBKIT_DOM_NODE (caret)),
+                               NULL);
+
+                       webkit_dom_node_append_child (
+                               WEBKIT_DOM_NODE (element),
+                               WEBKIT_DOM_NODE (caret),
+                               NULL);
+
+                       remove_node (
+                               webkit_dom_node_get_next_sibling (
+                                       WEBKIT_DOM_NODE (element)));
+
+                       e_html_editor_selection_restore_caret_position (selection);
+
+                       goto out;
+               }
+       }
+
+       e_html_editor_selection_clear_caret_position_marker (selection);
+
        inner_html = webkit_dom_html_element_get_inner_html (
                WEBKIT_DOM_HTML_ELEMENT (element));
-
        e_html_editor_view_exec_command (
                view, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, inner_html);
-
+       g_free (inner_html);
+ out:
        e_html_editor_view_force_spell_check (view);
 
-       g_free (inner_html);
        g_free (inner_text);
 }
 
@@ -3627,626 +4284,6 @@ e_html_editor_view_set_changed (EHTMLEditorView *view,
        g_object_notify (G_OBJECT (view), "changed");
 }
 
-static gboolean
-is_citation_node (WebKitDOMNode *node)
-{
-       char *value;
-
-       if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))
-               return FALSE;
-
-       value = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "type");
-
-       /* citation == <blockquote type='cite'> */
-       if (g_strcmp0 (value, "cite") == 0) {
-               g_free (value);
-               return TRUE;
-       } else {
-               g_free (value);
-               return FALSE;
-       }
-}
-
-static gchar *
-get_quotation_for_level (gint quote_level)
-{
-       gint ii;
-       GString *output = g_string_new ("");
-
-       for (ii = 0; ii < quote_level; ii++) {
-               g_string_append (output, "<span class=\"-x-evo-quote-character\">");
-               g_string_append (output, QUOTE_SYMBOL);
-               g_string_append (output, " ");
-               g_string_append (output, "</span>");
-       }
-
-       return g_string_free (output, FALSE);
-}
-
-static void
-insert_quote_symbols (WebKitDOMHTMLElement *element,
-                      gint quote_level,
-                      gboolean skip_first,
-                      gboolean insert_newline)
-{
-       gchar *text;
-       gint ii;
-       GString *output;
-       gchar *quotation;
-
-       if (!WEBKIT_DOM_IS_HTML_ELEMENT (element))
-               return;
-
-       text = webkit_dom_html_element_get_inner_html (element);
-       output = g_string_new ("");
-       quotation = get_quotation_for_level (quote_level);
-
-       if (g_strcmp0 (text, "\n") == 0) {
-               g_string_append (output, "<span class=\"-x-evo-quoted\">");
-               g_string_append (output, quotation);
-               g_string_append (output, "</span>");
-               g_string_append (output, "\n");
-       } else {
-               gchar **lines;
-
-               lines = g_strsplit (text, "\n", 0);
-
-               for (ii = 0; lines[ii]; ii++) {
-                       if (ii == 0 && skip_first) {
-                               if (g_strv_length (lines) == 1) {
-                                       g_strfreev (lines);
-                                       goto exit;
-                               }
-                               g_string_append (output, lines[ii]);
-                               g_string_append (output, "\n");
-                       }
-
-                       g_string_append (output, "<span class=\"-x-evo-quoted\">");
-                       g_string_append (output, quotation);
-                       g_string_append (output, "</span>");
-
-                       /* Insert line of text */
-                       g_string_append (output, lines[ii]);
-                       if ((ii == g_strv_length (lines) - 1) &&
-                           !g_str_has_suffix (text, "\n") && !insert_newline) {
-                               /* If we are on last line and node's text doesn't
-                                * end with \n, don't insert it */
-                               break;
-                       }
-                       g_string_append (output, "\n");
-               }
-
-               g_strfreev (lines);
-       }
-
-       webkit_dom_html_element_set_inner_html (element, output->str, NULL);
- exit:
-       g_free (quotation);
-       g_free (text);
-       g_string_free (output, TRUE);
-}
-
-static void
-quote_node (WebKitDOMDocument *document,
-           WebKitDOMNode *node,
-           gint quote_level)
-{
-       gboolean skip_first = FALSE;
-       gboolean insert_newline = FALSE;
-       gboolean is_html_node = FALSE;
-       WebKitDOMElement *wrapper;
-       WebKitDOMNode *node_clone, *prev_sibling, *next_sibling;
-
-       /* Don't quote when we are not in citation */
-       if (quote_level == 0)
-               return;
-
-       if (WEBKIT_DOM_IS_COMMENT (node))
-               return;
-
-       if (WEBKIT_DOM_IS_HTML_ELEMENT (node)) {
-               insert_quote_symbols (
-                       WEBKIT_DOM_HTML_ELEMENT (node), quote_level, FALSE, FALSE);
-               return;
-       }
-
-       prev_sibling = webkit_dom_node_get_previous_sibling (node);
-       next_sibling = webkit_dom_node_get_next_sibling (node);
-
-       is_html_node =
-               !WEBKIT_DOM_IS_TEXT (prev_sibling) &&
-               !WEBKIT_DOM_IS_COMMENT (prev_sibling) && (
-               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 */
-       if (quote_level == 1 && next_sibling && WEBKIT_DOM_IS_HTML_PRE_ELEMENT (next_sibling))
-               return;
-
-       if (next_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (next_sibling) &&
-           WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (webkit_dom_node_get_next_sibling (next_sibling))) {
-               insert_newline = TRUE;
-       }
-
-       /* Do temporary wrapper */
-       wrapper = webkit_dom_document_create_element (document, "SPAN", NULL);
-       webkit_dom_element_set_class_name (wrapper, "-x-evo-temp-text-wrapper");
-
-       node_clone = webkit_dom_node_clone_node (node, TRUE);
-
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (wrapper),
-               node_clone,
-               NULL);
-
-       insert_quote_symbols (
-               WEBKIT_DOM_HTML_ELEMENT (wrapper),
-               quote_level,
-               skip_first,
-               insert_newline);
-
-       webkit_dom_node_replace_child (
-               webkit_dom_node_get_parent_node (node),
-               WEBKIT_DOM_NODE (wrapper),
-               node,
-               NULL);
-}
-
-static void
-insert_quote_symbols_before_node (WebKitDOMDocument *document,
-                                  WebKitDOMNode *node,
-                                  gint quote_level,
-                                  gboolean is_html_node)
-{
-       gchar *quotation;
-       WebKitDOMElement *element;
-
-       quotation = get_quotation_for_level (quote_level);
-       element = webkit_dom_document_create_element (document, "SPAN", NULL);
-       element_add_class (element, "-x-evo-quoted");
-       webkit_dom_html_element_set_inner_html (
-               WEBKIT_DOM_HTML_ELEMENT (element), quotation, 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)
-               remove_node (node);
-
-       g_free (quotation);
-}
-
-static gboolean
-element_is_selection_marker (WebKitDOMElement *element)
-{
-       gboolean is_marker = FALSE;
-
-       is_marker =
-               element_has_id (element, "-x-evo-selection-start-marker") ||
-               element_has_id (element, "-x-evo-selection-end-marker");
-
-       return is_marker;
-}
-
-static gboolean
-check_if_suppress_next_node (WebKitDOMNode *node)
-{
-       if (node && WEBKIT_DOM_IS_ELEMENT (node))
-               if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node)))
-                       if (!webkit_dom_node_get_previous_sibling (node))
-                               return FALSE;
-
-       return TRUE;
-}
-
-static void
-quote_plain_text_recursive (WebKitDOMDocument *document,
-                           WebKitDOMNode *node,
-                           WebKitDOMNode *start_node,
-                           gint quote_level)
-{
-       gboolean skip_node = FALSE;
-       gboolean move_next = FALSE;
-       gboolean suppress_next = FALSE;
-       gboolean is_html_node = FALSE;
-       WebKitDOMNode *next_sibling, *prev_sibling;
-
-       node = webkit_dom_node_get_first_child (node);
-
-       while (node) {
-               skip_node = FALSE;
-               move_next = FALSE;
-               is_html_node = FALSE;
-
-               if (WEBKIT_DOM_IS_COMMENT (node))
-                       goto next_node;
-
-               prev_sibling = webkit_dom_node_get_previous_sibling (node);
-               next_sibling = webkit_dom_node_get_next_sibling (node);
-
-               if (WEBKIT_DOM_IS_TEXT (node)) {
-                       /* Start quoting after we are in blockquote */
-                       if (quote_level > 0 && !suppress_next) {
-                               /* When quoting text node, we are wrappering it and
-                                * afterwards replacing it with that wrapper, thus asking
-                                * for next_sibling after quoting will return NULL bacause
-                                * that node don't exist anymore */
-                               quote_node (document, node, quote_level);
-                               node = next_sibling;
-                               skip_node = TRUE;
-                       } else
-                               suppress_next = FALSE;
-
-                       goto next_node;
-               }
-
-               if (!(WEBKIT_DOM_IS_ELEMENT (node) || WEBKIT_DOM_IS_HTML_ELEMENT (node)))
-                       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 (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node))) {
-                       move_next = TRUE;
-                       /* If there is collapsed selection in the beginning of line
-                        * we cannot suppress first text that is after the end of
-                        * selection */
-                       suppress_next = check_if_suppress_next_node (prev_sibling);
-                       goto next_node;
-               }
-
-               if (WEBKIT_DOM_IS_HTML_META_ELEMENT (node)) {
-                       goto next_node;
-               }
-               if (WEBKIT_DOM_IS_HTML_STYLE_ELEMENT (node)) {
-                       move_next = TRUE;
-                       goto next_node;
-               }
-               if (WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (node)) {
-                       move_next = TRUE;
-                       goto next_node;
-               }
-
-               if (webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (node)) != 0)
-                       goto with_children;
-
-               /* 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 */
-               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) {
-                       if (!prev_sibling)
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-
-                       if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling))
-                               insert_quote_symbols_before_node (
-                                       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 */
-                       quote_node (document, node, quote_level + 1);
-                       /* Set citation as quoted */
-                       element_add_class (
-                               WEBKIT_DOM_ELEMENT (node),
-                               "-x-evo-plaintext-quoted");
-
-                       move_next = TRUE;
-                       goto next_node;
-               }
-
-               if (!WEBKIT_DOM_IS_HTMLBR_ELEMENT (node))
-                       goto not_br;
-
-               if (!prev_sibling) {
-                       WebKitDOMNode *parent;
-
-                       parent = webkit_dom_node_get_parent_node (node);
-
-                       /* BR in the beginning of the citation */
-                       if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent))
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-               }
-
-               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
-                   WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (next_sibling) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
-                       /* Situation when anchors are alone on line */
-                       gchar *text_content;
-
-                       text_content = webkit_dom_node_get_text_content (prev_sibling);
-
-                       if (g_str_has_suffix (text_content, "\n")) {
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-                               remove_node (node);
-                               g_free (text_content);
-                               node = next_sibling;
-                               skip_node = TRUE;
-                               goto next_node;
-                       }
-                       g_free (text_content);
-               }
-
-               if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling)) {
-                       gchar *quotation, *content;
-
-                       quotation = get_quotation_for_level (quote_level);
-
-                       content = g_strconcat (
-                               "<span class=\"-x-evo-quoted\">",
-                               quotation,
-                               "</span><br class=\"-x-evo-temp-br\">",
-                               NULL);
-
-                       webkit_dom_html_element_set_outer_html (
-                               WEBKIT_DOM_HTML_ELEMENT (node),
-                               content,
-                               NULL);
-
-                       g_free (content);
-                       g_free (quotation);
-
-                       node = next_sibling;
-                       skip_node = TRUE;
-                       goto next_node;
-               }
-
-               if (!prev_sibling && !next_sibling) {
-                       WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
-
-                       if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent)) {
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-                       }
-               }
-
-               if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
-                   element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
-                       gchar *text_content;
-
-                       text_content = webkit_dom_node_get_text_content (prev_sibling);
-                       if (g_strcmp0 (text_content, "") == 0)
-                               insert_quote_symbols_before_node (
-                                       document, node, quote_level, FALSE);
-
-                       g_free (text_content);
-               }
-
-               if (is_citation_node (prev_sibling)) {
-                       insert_quote_symbols_before_node (
-                               document, node, quote_level, FALSE);
-               }
- not_br:
-               if (g_strcmp0 (webkit_dom_node_get_text_content (node), "") == 0) {
-                       move_next = TRUE;
-                       goto next_node;
-               }
-
-               quote_node (document, node, quote_level);
-
-               move_next = TRUE;
-               goto next_node;
-
- with_children:
-               if (is_citation_node (node)) {
-                       /* Go deeper and increase level */
-                       quote_plain_text_recursive (
-                               document, node, start_node, quote_level + 1);
-                       /* set citation as quoted */
-                       element_add_class (
-                               WEBKIT_DOM_ELEMENT (node),
-                               "-x-evo-plaintext-quoted");
-                       move_next = TRUE;
-               } else {
-                       quote_plain_text_recursive (
-                               document, node, start_node, quote_level);
-                       move_next = TRUE;
-               }
- next_node:
-               if (!skip_node) {
-                       /* Move to next node */
-                       if (!move_next && webkit_dom_node_has_child_nodes (node)) {
-                               node = webkit_dom_node_get_first_child (node);
-                       } else if (webkit_dom_node_get_next_sibling (node)) {
-                               node = webkit_dom_node_get_next_sibling (node);
-                       } else {
-                               return;
-                       }
-               }
-       }
-}
-
-WebKitDOMElement *
-e_html_editor_view_quote_plain_text_element (EHTMLEditorView *view,
-                                             WebKitDOMElement *element)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMNode *element_clone;
-       WebKitDOMNodeList *list;
-       gint ii, length, level;
-
-       document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
-
-       element_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (element), TRUE);
-       level = get_citation_level (WEBKIT_DOM_NODE (element), TRUE);
-
-       /* Remove old quote characters if the exists */
-       list = webkit_dom_element_query_selector_all (
-               WEBKIT_DOM_ELEMENT (element_clone), "span.-x-evo-quoted", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for  (ii = 0; ii < length; ii++)
-               remove_node (webkit_dom_node_list_item (list, ii));
-
-       quote_plain_text_recursive (
-               document, element_clone, element_clone, level);
-
-       /* Replace old element with one, that is quoted */
-       webkit_dom_node_replace_child (
-               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
-               element_clone,
-               WEBKIT_DOM_NODE (element),
-               NULL);
-
-       return WEBKIT_DOM_ELEMENT (element_clone);
-}
-
-/**
- * e_html_editor_view_quote_plain_text:
- * @view: an #EHTMLEditorView
- *
- * Quote text inside citation blockquotes in plain text mode.
- *
- * As this function is cloning and replacing all citation blockquotes keep on
- * mind that any pointers to nodes inside these blockquotes will be invalidated.
- */
-WebKitDOMElement *
-e_html_editor_view_quote_plain_text (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMHTMLElement *body;
-       WebKitDOMNode *body_clone;
-       WebKitDOMNamedNodeMap *attributes;
-       WebKitDOMNodeList *list;
-       WebKitDOMElement *element;
-       gint ii, length;
-       gulong attributes_length;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       /* Check if the document is already quoted */
-       element = webkit_dom_document_query_selector (
-               document, ".-x-evo-plaintext-quoted", NULL);
-       if (element)
-               return NULL;
-
-       body = webkit_dom_document_get_body (document);
-       body_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
-
-       /* Clean unwanted spaces before and after blockquotes */
-       list = webkit_dom_element_query_selector_all (
-               WEBKIT_DOM_ELEMENT (body_clone), "blockquote[type|=cite]", NULL);
-       length = webkit_dom_node_list_get_length (list);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *blockquote = webkit_dom_node_list_item (list, ii);
-               WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (blockquote);
-               WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (blockquote);
-
-               if (prev_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling))
-                       remove_node (prev_sibling);
-
-               if (next_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (next_sibling))
-                       remove_node (next_sibling);
-
-               if (webkit_dom_node_has_child_nodes (blockquote)) {
-                       WebKitDOMNode *child = webkit_dom_node_get_first_child (blockquote);
-                       if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child))
-                               remove_node (child);
-               }
-       }
-
-       quote_plain_text_recursive (document, body_clone, body_clone, 0);
-
-       /* Copy attributes */
-       attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
-       attributes_length = webkit_dom_named_node_map_get_length (attributes);
-       for (ii = 0; ii < attributes_length; ii++) {
-               gchar *name, *value;
-               WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
-
-               name = webkit_dom_node_get_local_name (node);
-               value = webkit_dom_node_get_node_value (node);
-
-               webkit_dom_element_set_attribute (
-                       WEBKIT_DOM_ELEMENT (body_clone), name, value, NULL);
-
-               g_free (name);
-               g_free (value);
-       }
-
-       /* Replace old BODY with one, that is quoted */
-       webkit_dom_node_replace_child (
-               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
-               body_clone,
-               WEBKIT_DOM_NODE (body),
-               NULL);
-
-       return WEBKIT_DOM_ELEMENT (body_clone);
-}
-
-/**
- * e_html_editor_view_dequote_plain_text:
- * @view: an #EHTMLEditorView
- *
- * Dequote already quoted plain text in editor.
- * Editor have to be quoted with e_html_editor_view_quote_plain_text otherwise
- * it's not working.
- */
-void
-e_html_editor_view_dequote_plain_text (EHTMLEditorView *view)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMNodeList *paragraphs;
-       gint length, ii;
-
-       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
-       paragraphs = webkit_dom_document_query_selector_all (
-               document, "blockquote.-x-evo-plaintext-quoted", NULL);
-       length = webkit_dom_node_list_get_length (paragraphs);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMElement *element;
-
-               element = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (paragraphs, ii));
-
-               if (is_citation_node (WEBKIT_DOM_NODE (element))) {
-                       element_remove_class (element, "-x-evo-plaintext-quoted");
-                       remove_quoting_from_element (element);
-               }
-       }
-}
-
 /**
  * e_html_editor_view_get_html_mode:
  * @view: an #EHTMLEditorView



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