[evolution/wip/mcrha/webkit-jsc-api] test-html-editor-units: Adapt the rest (except of one) /bug tests and fix found bugs in the new code



commit f54dceb514efb72b0a6cec6547b1cf82b9bcd80d
Author: Milan Crha <mcrha redhat com>
Date:   Fri Apr 3 11:08:43 2020 +0200

    test-html-editor-units: Adapt the rest (except of one) /bug tests and fix found bugs in the new code

 data/webkit/e-convert.js                    |  40 +++--
 data/webkit/e-editor.js                     | 227 +++++++++++++++-------------
 src/e-util/test-html-editor-units-bugs.c    | 157 ++++++++++++-------
 src/e-util/test-web-view-jsc.c              | 102 ++++++++++++-
 src/modules/webkit-editor/e-webkit-editor.c |  59 +++++++-
 5 files changed, 411 insertions(+), 174 deletions(-)
---
diff --git a/data/webkit/e-convert.js b/data/webkit/e-convert.js
index d7d9cd9f93..24e9d45bcb 100644
--- a/data/webkit/e-convert.js
+++ b/data/webkit/e-convert.js
@@ -389,6 +389,10 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW
                                }
                        },
 
+                       mayConsumeWhitespaceAfterWrap : function(str, ii) {
+                               return ii > 0 && this.line == "" && str[ii - 1] == EvoConvert.NOWRAP_CHAR_END;
+                       },
+
                        isInUnwrapPart : function() {
                                if (worker.inAnchor)
                                        return true;
@@ -399,9 +403,10 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW
                                return false;
                        },
 
-                       shouldWrap : function() {
+                       shouldWrap : function(nextChar) {
                                return worker.canWrap && (!worker.isInUnwrapPart() || worker.lastSpace != -1) 
&& (worker.lineLetters - worker.ignoreLineLetters > worker.useWrapWidth || (
-                                       worker.lineLetters - worker.ignoreLineLetters == worker.useWrapWidth 
&& (
+                                       ((!worker.charWrap && (nextChar == " " || nextChar == "\t") && 
worker.lineLetters - worker.ignoreLineLetters > worker.useWrapWidth) ||
+                                       ((worker.charWrap || (nextChar != " " && nextChar != "\t")) && 
worker.lineLetters - worker.ignoreLineLetters == worker.useWrapWidth)) && (
                                        worker.lastSpace == -1/* || worker.lastSpace == 
worker.line.length*/)));
                        },
 
@@ -504,9 +509,10 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW
                                worker.inAnchor++;
 
                        if (chr == "\n") {
-                               worker.commit(ii);
+                               if (!worker.mayConsumeWhitespaceAfterWrap(str, ii))
+                                       worker.commit(ii);
                        } else if (!worker.charWrap && !worker.collapseWhiteSpace && chr == "\t") {
-                               if (worker.shouldWrap())
+                               if (worker.shouldWrap(str[ii + 1]))
                                        worker.commit(ii);
                                else
                                        worker.commitSpaces(ii);
@@ -515,7 +521,7 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW
 
                                worker.lineLetters = worker.lineLetters - ((worker.lineLetters - 
worker.ignoreLineLetters) % EvoConvert.TAB_WIDTH) + EvoConvert.TAB_WIDTH;
 
-                               if (worker.shouldWrap())
+                               if (worker.shouldWrap(str[ii + 1]))
                                        worker.commit(ii);
 
                                worker.line += add;
@@ -526,7 +532,7 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW
                                if (chr == '\t') {
                                        worker.lineLetters = worker.lineLetters - ((worker.lineLetters - 
worker.ignoreLineLetters) % EvoConvert.TAB_WIDTH) + EvoConvert.TAB_WIDTH;
                                        setSpacesFrom = true;
-                               } else if ((worker.spacesFrom == -1 && worker.line != "") || 
!worker.collapseWhiteSpace) {
+                               } else if ((worker.spacesFrom == -1 && worker.line != "") || 
(!worker.collapseWhiteSpace && !worker.mayConsumeWhitespaceAfterWrap(str, ii))) {
                                        worker.lineLetters++;
                                        setSpacesFrom = true;
                                }
@@ -549,7 +555,7 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW
                                if (chr == EvoConvert.NOWRAP_CHAR_END && worker.inAnchor)
                                        worker.inAnchor--;
 
-                               if (worker.shouldWrap())
+                               if (worker.shouldWrap(str[ii + 1]))
                                        worker.commit(ii);
                        }
                }
@@ -803,7 +809,7 @@ EvoConvert.processNode = function(node, normalDivWidth, quoteLevel)
                whiteSpace = style ? style.whiteSpace.toLowerCase() : "";
 
                if (node.tagName == "DIV" || node.tagName == "P") {
-                       var liText, extraIndent, width;
+                       var liText, extraIndent, width, useDefaultWidth = false;
 
                        liText = node.getAttribute("x-evo-li-text");
                        if (!liText)
@@ -818,17 +824,29 @@ EvoConvert.processNode = function(node, normalDivWidth, quoteLevel)
                        width = node.style.width;
                        if (width && width.endsWith("ch")) {
                                width = parseInt(width.slice(0, -2));
+
                                if (!Number.isInteger(width) || width < 0)
-                                       width = normalDivWidth;
+                                       useDefaultWidth = true;
                        } else {
-                               width = normalDivWidth;
+                               useDefaultWidth = true;
+                       }
+
+                       if (useDefaultWidth && normalDivWidth > 0) {
+                               width = normalDivWidth - (quoteLevel * 2);
+
+                               if (width < EvoConvert.MIN_PARAGRAPH_WIDTH)
+                                       width = EvoConvert.MIN_PARAGRAPH_WIDTH;
                        }
 
                        str = EvoConvert.formatParagraph(EvoConvert.extractElemText(node, normalDivWidth, 
quoteLevel), ltr, align, indent, whiteSpace, width, extraIndent, liText, quoteLevel);
                } else if (node.tagName == "PRE") {
                        str = EvoConvert.formatParagraph(EvoConvert.extractElemText(node, normalDivWidth, 
quoteLevel), ltr, align, indent, "pre", -1, 0, "", quoteLevel);
                } else if (node.tagName == "BR") {
-                       str = "\n";
+                       // ignore new-lines added by wrapping, treat them as spaces
+                       if (node.classList.contains("-x-evo-wrap-br"))
+                               str += " ";
+                       else
+                               str = "\n";
                } else if (node.tagName == "IMG") {
                        str = EvoConvert.ImgToText(node);
                } else if (node.tagName == "A" && !node.innerText.includes(" ") && 
!node.innerText.includes("\n")) {
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index 0fa42643be..c05beb9c82 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -85,6 +85,7 @@ var EvoEditor = {
        MAGIC_LINKS : true,
        MAGIC_SMILEYS : false,
        UNICODE_SMILEYS : false,
+       WRAP_QUOTED_TEXT_IN_REPLIES : true,
 
        FORCE_NO : 0,
        FORCE_YES : 1,
@@ -1986,7 +1987,7 @@ EvoEditor.reBlockquotePlainText = function(plainText, usePreTag)
        return html;
 }
 
-EvoEditor.convertParagraphs = function(parent, blockquoteLevel, wrapWidth)
+EvoEditor.convertParagraphs = function(parent, blockquoteLevel, wrapWidth, canChangeQuoteParagraphs)
 {
        if (!parent)
                return;
@@ -2036,7 +2037,7 @@ EvoEditor.convertParagraphs = function(parent, blockquoteLevel, wrapWidth)
 
                                child.innerHTML = text;
                        } else {
-                               EvoEditor.convertParagraphs(child, blockquoteLevel, wrapWidth);
+                               EvoEditor.convertParagraphs(child, blockquoteLevel, wrapWidth, 
canChangeQuoteParagraphs);
                        }
                } else if (child.tagName == "BLOCKQUOTE") {
                        var innerWrapWidth = wrapWidth;
@@ -2052,10 +2053,11 @@ EvoEditor.convertParagraphs = function(parent, blockquoteLevel, wrapWidth)
                        // and do it only on the top level, not recursively (nested citations)
                        if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT && !blockquoteLevel) {
                                child.innerHTML = 
EvoEditor.reBlockquotePlainText(EvoConvert.ToPlainText(child, -1),
-                                       child.firstElementChild && child.firstElementChild.tagName == "PRE");
+                                       (child.firstElementChild && child.firstElementChild.tagName == "PRE" 
&& (
+                                       !canChangeQuoteParagraphs || 
!EvoEditor.WRAP_QUOTED_TEXT_IN_REPLIES)));
                        }
 
-                       EvoEditor.convertParagraphs(child, blockquoteLevel + 1, innerWrapWidth);
+                       EvoEditor.convertParagraphs(child, blockquoteLevel + 1, innerWrapWidth, 
canChangeQuoteParagraphs);
                } else if (child.tagName == "UL") {
                        if (wrapWidth == -1) {
                                child.style.width = "";
@@ -2101,7 +2103,7 @@ EvoEditor.SetNormalParagraphWidth = function(value)
                EvoEditor.NORMAL_PARAGRAPH_WIDTH = value;
 
                if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT)
-                       EvoEditor.convertParagraphs(document.body, 0, EvoEditor.NORMAL_PARAGRAPH_WIDTH);
+                       EvoEditor.convertParagraphs(document.body, 0, EvoEditor.NORMAL_PARAGRAPH_WIDTH, 
false);
        }
 }
 
@@ -2259,9 +2261,9 @@ EvoEditor.SetMode = function(mode)
 
                        if (mode == EvoEditor.MODE_PLAIN_TEXT) {
                                EvoEditor.convertTags();
-                               EvoEditor.convertParagraphs(document.body, 0, 
EvoEditor.NORMAL_PARAGRAPH_WIDTH);
+                               EvoEditor.convertParagraphs(document.body, 0, 
EvoEditor.NORMAL_PARAGRAPH_WIDTH, false);
                        } else {
-                               EvoEditor.convertParagraphs(document.body, 0, -1);
+                               EvoEditor.convertParagraphs(document.body, 0, -1, false);
                        }
                } finally {
                        EvoUndoRedo.Enable();
@@ -2924,7 +2926,7 @@ EvoEditor.requoteNodeParagraph = function(node)
 EvoEditor.replaceMatchWithNode = function(opType, node, match, newNode, canEmit, withUndo)
 {
        if (withUndo) {
-               EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opType, anchorNode.parentElement, 
anchorNode.parentElement,
+               EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, opType, node.parentElement, 
node.parentElement,
                        EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
        }
 
@@ -2977,74 +2979,89 @@ EvoEditor.linkifyText = function(anchorNode, withUndo)
                }
        }
 
-       var isEmail = text.search("@") >= 0, match, covered = false;
+       var covered = false, done = false;
 
-       // the replace call below replaces &nbsp; (0xA0) with regular space
-       match = EvoEditor.findPattern(text.replace(/ /g, " "), isEmail ? EvoEditor.EMAIL_PATTERN : 
EvoEditor.URL_PATTERN);
-       if (match) {
-               var url = text.substring(match.start, match.end), node;
+       while (!done) {
+               done = true;
 
-               // because 'search' uses Regex and throws exception on brackets and other Regex-sensitive 
characters
-               var isInvalidTrailingChar = function(chr) {
-                       var jj;
+               var isEmail = text.search("@") >= 0 && text.search("://") < 0, match;
 
-                       for (jj = 0; jj < EvoEditor.URL_INVALID_TRAILING_CHARS.length; jj++) {
-                               if (chr == EvoEditor.URL_INVALID_TRAILING_CHARS.charAt(jj))
-                                       return true;
-                       }
+               // the replace call below replaces &nbsp; (0xA0) with regular space
+               match = EvoEditor.findPattern(text.replace(/ /g, " "), isEmail ? EvoEditor.EMAIL_PATTERN : 
EvoEditor.URL_PATTERN);
+               if (match) {
+                       var url = text.substring(match.start, match.end), node;
 
-                       return false;
-               };
+                       // because 'search' uses Regex and throws exception on brackets and other 
Regex-sensitive characters
+                       var isInvalidTrailingChar = function(chr) {
+                               var jj;
 
-               /* URLs are extremely unlikely to end with any punctuation, so
-                * strip any trailing punctuation off from link and put it after
-                * the link. Do the same for any closing double-quotes as well. */
-               while (url.length > 0 && isInvalidTrailingChar(url.charAt(url.length - 1))) {
-                       var open_bracket = 0, close_bracket = url.charAt(url.length - 1);
-
-                       if (close_bracket == ')')
-                               open_bracket = '(';
-                       else if (close_bracket == '}')
-                               open_bracket = '{';
-                       else if (close_bracket == ']')
-                               open_bracket = '[';
-                       else if (close_bracket == '>')
-                               open_bracket = '<';
-
-                       if (open_bracket != 0) {
-                               var n_opened = 0, n_closed = 0, ii, chr;
-
-                               for (ii = 0; ii < url.length; ii++) {
-                                       chr = url.charAt(ii);
-
-                                       if (chr == open_bracket)
-                                               n_opened++;
-                                       else if (chr == close_bracket)
-                                               n_closed++;
+                               for (jj = 0; jj < EvoEditor.URL_INVALID_TRAILING_CHARS.length; jj++) {
+                                       if (chr == EvoEditor.URL_INVALID_TRAILING_CHARS.charAt(jj))
+                                               return true;
                                }
 
-                               /* The closing bracket can match one inside the URL,
-                                  thus keep it there. */
-                               if (n_opened > 0 && n_opened - n_closed >= 0)
-                                       break;
+                               return false;
+                       };
+
+                       /* URLs are extremely unlikely to end with any punctuation, so
+                        * strip any trailing punctuation off from link and put it after
+                        * the link. Do the same for any closing double-quotes as well. */
+                       while (url.length > 0 && isInvalidTrailingChar(url.charAt(url.length - 1))) {
+                               var open_bracket = 0, close_bracket = url.charAt(url.length - 1);
+
+                               if (close_bracket == ')')
+                                       open_bracket = '(';
+                               else if (close_bracket == '}')
+                                       open_bracket = '{';
+                               else if (close_bracket == ']')
+                                       open_bracket = '[';
+                               else if (close_bracket == '>')
+                                       open_bracket = '<';
+
+                               if (open_bracket != 0) {
+                                       var n_opened = 0, n_closed = 0, ii, chr;
+
+                                       for (ii = 0; ii < url.length; ii++) {
+                                               chr = url.charAt(ii);
+
+                                               if (chr == open_bracket)
+                                                       n_opened++;
+                                               else if (chr == close_bracket)
+                                                       n_closed++;
+                                       }
+
+                                       /* The closing bracket can match one inside the URL,
+                                          thus keep it there. */
+                                       if (n_opened > 0 && n_opened - n_closed >= 0)
+                                               break;
+                               }
+
+                               url = url.substr(0, url.length - 1);
+                               match.end--;
                        }
 
-                       url = url.substr(0, url.length - 1);
-                       match.end--;
-               }
+                       if (url.length > 0) {
+                               covered = true;
 
-               if (url.length > 0) {
-                       covered = true;
+                               if (isEmail)
+                                       url = "mailto:"; + url;
+                               else if (url.startsWith("www."))
+                                       url = "https://"; + url;
 
-                       if (isEmail)
-                               url = "mailto:"; + url;
-                       else if (url.startsWith("www."))
-                               url = "https://"; + url;
+                               node = document.createElement("A");
+                               node.href = url;
 
-                       node = document.createElement("A");
-                       node.href = url;
+                               anchorNode = EvoEditor.replaceMatchWithNode("magicLink", anchorNode, match, 
node, true, withUndo);
 
-                       anchorNode = EvoEditor.replaceMatchWithNode("magicLink", anchorNode, match, node, 
true, withUndo);
+                               if (anchorNode) {
+                                       anchorNode = anchorNode.parentElement.nextSibling;
+
+                                       if (anchorNode) {
+                                               text = anchorNode.nodeValue;
+                                               done = !text;
+                                       }
+                               }
+                       }
                }
        }
 
@@ -3125,37 +3142,39 @@ EvoEditor.beforeInputCb = function(inputEvent)
                        return;
                }
 
-               var didRemove = 0;
+               if (!selection.isCollapsed) {
+                       var didRemove = 0;
 
-               if (selection.anchorNode && selection.anchorNode.previousSibling &&
-                   EvoEditor.maybeRemoveQuotationMark(selection.anchorNode.previousSibling))
-                       didRemove++;
+                       if (selection.anchorNode && selection.anchorNode.previousSibling &&
+                           EvoEditor.maybeRemoveQuotationMark(selection.anchorNode.previousSibling))
+                               didRemove++;
 
-               if (selection.focusNode && selection.focusNode.previousSibling &&
-                   EvoEditor.maybeRemoveQuotationMark(selection.focusNode.previousSibling))
-                       didRemove++;
+                       if (selection.focusNode && selection.focusNode.previousSibling &&
+                           EvoEditor.maybeRemoveQuotationMark(selection.focusNode.previousSibling))
+                               didRemove++;
 
-               if (didRemove) {
-                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, inputEvent.inputType + 
"::selDeletion", selection.anchorNode, selection.focusNode,
-                               EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML | 
EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE);
-                       try {
-                               selection.deleteFromDocument();
-                       } finally {
-                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, inputEvent.inputType + 
"::selDeletion");
-                       }
+                       if (didRemove) {
+                               EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, inputEvent.inputType 
+ "::selDeletion", selection.anchorNode, selection.focusNode,
+                                       EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML | 
EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE);
+                               try {
+                                       selection.deleteFromDocument();
+                               } finally {
+                                       EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
inputEvent.inputType + "::selDeletion");
+                               }
 
-                       didRemove += EvoEditor.removeEmptyElements("DIV");
-                       didRemove += EvoEditor.removeEmptyElements("PRE");
+                               didRemove += EvoEditor.removeEmptyElements("DIV");
+                               didRemove += EvoEditor.removeEmptyElements("PRE");
 
-                       EvoUndoRedo.GroupTopRecords(didRemove + 1, inputEvent.inputType + "::grouped");
-                       EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
-                       EvoEditor.EmitContentChanged();
+                               EvoUndoRedo.GroupTopRecords(didRemove + 1, inputEvent.inputType + 
"::grouped");
+                               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+                               EvoEditor.EmitContentChanged();
 
-                       inputEvent.stopImmediatePropagation();
-                       inputEvent.stopPropagation();
-                       inputEvent.preventDefault();
+                               inputEvent.stopImmediatePropagation();
+                               inputEvent.stopPropagation();
+                               inputEvent.preventDefault();
 
-                       return;
+                               return;
+                       }
                }
        }
 
@@ -3334,7 +3353,7 @@ EvoEditor.AfterInputEvent = function(inputEvent, isWordDelim)
 
                                                EvoEditor.removeQuoteMarks(node.nextElementSibling);
                                                EvoEditor.convertParagraphs(node.nextElementSibling, 
blockquoteLevel,
-                                                       EvoEditor.NORMAL_PARAGRAPH_WIDTH - (blockquoteLevel * 
2));
+                                                       EvoEditor.NORMAL_PARAGRAPH_WIDTH - (blockquoteLevel * 
2), false);
                                        }
 
                                        if (node && node.previousElementSibling) {
@@ -3342,7 +3361,7 @@ EvoEditor.AfterInputEvent = function(inputEvent, isWordDelim)
 
                                                EvoEditor.removeQuoteMarks(node.previousElementSibling);
                                                EvoEditor.convertParagraphs(node.previousElementSibling, 
blockquoteLevel,
-                                                       EvoEditor.NORMAL_PARAGRAPH_WIDTH - (blockquoteLevel * 
2));
+                                                       EvoEditor.NORMAL_PARAGRAPH_WIDTH - (blockquoteLevel * 
2), false);
                                        }
                                }
                        } finally {
@@ -4949,10 +4968,10 @@ EvoEditor.InsertContent = function(text, isHTML, quote)
                        }
 
                        if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT) {
-                               EvoEditor.convertParagraphs(content, quote ? 1 : 0, 
EvoEditor.NORMAL_PARAGRAPH_WIDTH);
+                               EvoEditor.convertParagraphs(content, quote ? 1 : 0, 
EvoEditor.NORMAL_PARAGRAPH_WIDTH, quote);
                                content.innerText = EvoConvert.ToPlainText(content, 
EvoEditor.NORMAL_PARAGRAPH_WIDTH);
                        } else {
-                               EvoEditor.convertParagraphs(content, quote ? 1 : 0, -1);
+                               EvoEditor.convertParagraphs(content, quote ? 1 : 0, -1, quote);
                        }
                } else {
                        var lines = text.split("\n");
@@ -4987,14 +5006,14 @@ EvoEditor.InsertContent = function(text, isHTML, quote)
                        }
 
                        if (covered && !isHTML) {
-                               EvoEditor.convertParagraphs(content, quote ? 1 : 0, EvoEditor.mode == 
EvoEditor.MODE_PLAIN_TEXT ? EvoEditor.NORMAL_PARAGRAPH_WIDTH : -1);
+                               EvoEditor.convertParagraphs(content, quote ? 1 : 0, EvoEditor.mode == 
EvoEditor.MODE_PLAIN_TEXT ? EvoEditor.NORMAL_PARAGRAPH_WIDTH : -1, quote);
                                isHTML = true;
                        }
                }
 
                if (quote) {
                        if (!isHTML)
-                               EvoEditor.convertParagraphs(content, quote ? 1 : 0, EvoEditor.mode == 
EvoEditor.MODE_PLAIN_TEXT ? EvoEditor.NORMAL_PARAGRAPH_WIDTH : -1);
+                               EvoEditor.convertParagraphs(content, quote ? 1 : 0, EvoEditor.mode == 
EvoEditor.MODE_PLAIN_TEXT ? EvoEditor.NORMAL_PARAGRAPH_WIDTH : -1, quote);
 
                        var anchorNode = document.getSelection().anchorNode, intoBody = false;
 
@@ -5138,38 +5157,38 @@ EvoEditor.processLoadedContent = function()
        if (!document.body)
                return;
 
-       var node, cite;
+       var node, didCite;
 
        node = document.querySelector("SPAN.-x-evo-cite-body");
 
-       cite = node;
+       didCite = node;
 
        if (node && node.parentElement) {
                node.parentElement.removeChild(node);
        }
 
-       if (cite) {
-               cite = document.createElement("BLOCKQUOTE");
-               cite.setAttribute("type", "cite");
+       if (didCite) {
+               didCite = document.createElement("BLOCKQUOTE");
+               didCite.setAttribute("type", "cite");
 
                while (document.body.firstChild) {
-                       cite.appendChild(document.body.firstChild);
+                       didCite.appendChild(document.body.firstChild);
                }
 
                var next;
 
                // Evolution builds HTML with insignificant "\n", thus remove them first
-               for (node = cite.firstChild; node; node = next) {
-                       next = EvoEditor.getNextNodeInHierarchy(node, cite);
+               for (node = didCite.firstChild; node; node = next) {
+                       next = EvoEditor.getNextNodeInHierarchy(node, didCite);
 
                        if (node.nodeType == node.TEXT_NODE && node.nodeValue && node.nodeValue.charAt(0) == 
'\n' && (
                            (node.previousSibling && EvoEditor.IsBlockNode(node.previousSibling)) ||
-                           (!node.previousSibling && node.parentElement.tagName == "BLOCKQUOTE" && 
!(node.parentElement === cite)))) {
+                           (!node.previousSibling && node.parentElement.tagName == "BLOCKQUOTE" && 
!(node.parentElement === didCite)))) {
                                node.nodeValue = node.nodeValue.substr(1);
                        }
                }
 
-               document.body.appendChild(cite);
+               document.body.appendChild(didCite);
        }
 
        var ii, list;
@@ -5256,7 +5275,7 @@ EvoEditor.processLoadedContent = function()
        }
 
        if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT) {
-               EvoEditor.convertParagraphs(document.body, 0, EvoEditor.NORMAL_PARAGRAPH_WIDTH);
+               EvoEditor.convertParagraphs(document.body, 0, EvoEditor.NORMAL_PARAGRAPH_WIDTH, didCite);
 
                if (EvoEditor.MAGIC_LINKS) {
                        var next;
diff --git a/src/e-util/test-html-editor-units-bugs.c b/src/e-util/test-html-editor-units-bugs.c
index 9572354726..0cc49835f7 100644
--- a/src/e-util/test-html-editor-units-bugs.c
+++ b/src/e-util/test-html-editor-units-bugs.c
@@ -209,7 +209,7 @@ test_bug_769708 (TestFixture *fixture)
                "",
                HTML_PREFIX "<div style=\"width: 71ch;\">aaa</div>"
                "<div class=\"-x-evo-signature-wrapper\" style=\"width: 71ch;\"><span 
class=\"-x-evo-signature\" id=\"autogenerated\"><pre>-- <br></pre>"
-               "<div>user &lt;user@no.where&gt;</div>"
+               "<div>user &lt;<a href=\"mailto:user@no.where\";>user@no.where</a>&gt;</div>"
                "</span></div>" HTML_SUFFIX,
                "aaa\n"
                "-- \n"
@@ -591,6 +591,8 @@ test_bug_771044 (TestFixture *fixture)
 static void
 test_bug_771131 (TestFixture *fixture)
 {
+       test_utils_fixture_change_setting_boolean (fixture, "org.gnome.evolution.mail", 
"composer-wrap-quoted-text-in-replies", TRUE);
+
        if (!test_utils_process_commands (fixture,
                "mode:plain\n")) {
                g_test_fail ();
@@ -610,7 +612,7 @@ test_bug_771131 (TestFixture *fixture)
 
        if (!test_utils_run_simple_test (fixture,
                "",
-               HTML_PREFIX "<div style=\"width: 71ch;\">On Sat, 2016-09-10 at 20:00 +0000, example example 
com wrote:</div>"
+               HTML_PREFIX "<div style=\"width: 71ch;\">On Sat, 2016-09-10 at 20:00 +0000, <a 
href=\"mailto:example example com\">example example com</a> wrote:</div>"
                "<blockquote type=\"cite\">"
                "<div>" QUOTE_SPAN (QUOTE_CHR) "On &lt;date1&gt;, &lt;name1&gt; wrote:</div>"
                "<blockquote type=\"cite\">"
@@ -628,6 +630,40 @@ test_bug_771131 (TestFixture *fixture)
                "> > Goodbye\n"
                "> the 3rd line text\n"))
                g_test_fail ();
+
+       test_utils_fixture_change_setting_boolean (fixture, "org.gnome.evolution.mail", 
"composer-wrap-quoted-text-in-replies", FALSE);
+
+       test_utils_insert_content (fixture,
+               "<body><pre>On &lt;date1&gt;, &lt;name1&gt; wrote:\n"
+               "<blockquote type=\"cite\" " BLOCKQUOTE_STYLE ">\n"
+               "Hello\n"
+               "\n"
+               "Goodbye</blockquote>"
+               "<div><span>the 3rd line text</span></div>"
+               "</pre><span class=\"-x-evo-to-body\" data-credits=\"On Sat, 2016-09-10 at 20:00 +0000, 
example example com wrote:\"></span>"
+               "<span class=\"-x-evo-cite-body\"></span></body>",
+               E_CONTENT_EDITOR_INSERT_REPLACE_ALL | E_CONTENT_EDITOR_INSERT_TEXT_HTML);
+
+       if (!test_utils_run_simple_test (fixture,
+               "",
+               HTML_PREFIX "<div style=\"width: 71ch;\">On Sat, 2016-09-10 at 20:00 +0000, <a 
href=\"mailto:example example com\">example example com</a> wrote:</div>"
+               "<blockquote type=\"cite\">"
+               "<pre>" QUOTE_SPAN (QUOTE_CHR) "On &lt;date1&gt;, &lt;name1&gt; wrote:</pre>"
+               "<blockquote type=\"cite\">"
+               "<pre>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "Hello</pre>"
+               "<pre>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "<br></pre>"
+               "<pre>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "Goodbye</pre>"
+               "</blockquote>"
+               "<pre>" QUOTE_SPAN (QUOTE_CHR) "the 3rd line text</pre>"
+               "</blockquote>"
+               HTML_SUFFIX,
+               "On Sat, 2016-09-10 at 20:00 +0000, example example com wrote:\n"
+               "> On <date1>, <name1> wrote:\n"
+               "> > Hello\n"
+               "> > \n"
+               "> > Goodbye\n"
+               "> the 3rd line text\n"))
+               g_test_fail ();
 }
 
 static void
@@ -779,6 +815,8 @@ test_bug_773164 (TestFixture *fixture)
 static void
 test_bug_775042 (TestFixture *fixture)
 {
+       test_utils_fixture_change_setting_boolean (fixture, "org.gnome.evolution.mail", 
"composer-wrap-quoted-text-in-replies", FALSE);
+
        test_utils_insert_content (fixture,
                "<body><pre>a\n"
                "b\n"
@@ -1136,7 +1174,8 @@ test_bug_781116 (TestFixture *fixture)
                "</blockquote>"
                HTML_SUFFIX,
                "Credits:\n"
-               "> a very long text, which splits into multiple lines when this paragraph\n"
+               "> a very long text, which splits into multiple lines when this\n"
+               "> paragraph\n"
                "> is not marked as preformatted, but as normal, as it should be\n"))
                g_test_fail ();
 }
@@ -1150,7 +1189,9 @@ test_bug_780088 (TestFixture *fixture)
                return;
        }
 
-       test_utils_set_clipboard_text ("Seeing @blah instead of @foo XX'ed on" UNICODE_NBSP 
"https://example.sub"; UNICODE_NBSP "domain.org/page I'd recommend to XX YY 
<https://example.subdomain.org/p/user/> , click fjwvne on the left, click skjd sjewncj on the right, and set 
wqje wjfdn Xs to something like wqjfnm www.example.com/~user wjfdncj or such.", FALSE);
+       test_utils_set_clipboard_text ("Seeing @blah instead of @foo XX'ed on" UNICODE_NBSP 
"https://example.sub"; UNICODE_NBSP "domain.org/page I'd"
+               " recommend to XX YY <https://example.subdomain.org/p/user/> , click fjwvne on the left, 
click skjd sjewncj on the right, and set"
+               " wqje wjfdn Xs to something like wqjfnm www.example.com/~user wjfdncj or such.", FALSE);
 
        if (!test_utils_run_simple_test (fixture,
                "action:paste\n"
@@ -1160,14 +1201,14 @@ test_bug_780088 (TestFixture *fixture)
                "&nbsp;domain.org/page I'd recommend to XX YY "
                "&lt;<a 
href=\"https://example.subdomain.org/p/user/\";>https://example.subdomain.org/p/user/</a>&gt; , "
                "click fjwvne on the left, click skjd sjewncj on the right, and set wqje wjfdn Xs to 
something like "
-               "wqjfnm <a href=\"www.example.com/~user\">www.example.com/~user</a> wjfdncj or such.</div>"
+               "wqjfnm <a href=\"https://www.example.com/~user\";>www.example.com/~user</a> wjfdncj or 
such.</div>"
                "</div><div style=\"width: 71ch;\"><br></div>"
                HTML_SUFFIX,
-               "Seeing @blah instead of @foo XX'ed on" UNICODE_NBSP "https://example.sub"; UNICODE_NBSP 
"domain.org/pa\n"
-               "ge I'd recommend to XX YY <https://example.subdomain.org/p/user/> ,\n"
-               "click fjwvne on the left, click skjd sjewncj on the right, and set wqje\n"
-               "wjfdn Xs to something like wqjfnm www.example.com/~user wjfdncj or\n"
-               "such.\n"))
+               "Seeing @blah instead of @foo XX'ed\n"
+               "on" UNICODE_NBSP "https://example.sub"; UNICODE_NBSP "domain.org/page I'd recommend to XX 
YY\n"
+               "<https://example.subdomain.org/p/user/> , click fjwvne on the left,\n"
+               "click skjd sjewncj on the right, and set wqje wjfdn Xs to something\n"
+               "like wqjfnm www.example.com/~user wjfdncj or such.\n\n"))
                g_test_fail ();
 }
 
@@ -1212,37 +1253,41 @@ test_bug_788829 (TestFixture *fixture)
 
        if (!test_utils_run_simple_test (fixture,
                "",
-               HTML_PREFIX "<div style=\"width: 71ch;\">On Today, User wrote:</div><blockquote type=\"cite\" 
" BLOCKQUOTE_STYLE ">"
-               "<div style=\"width: 71ch;\">&gt; Xxxxx xx xxxxxxxxx xx xxxxxxx xx xxxxx xxxx "
-               "xxxx xx xxx xxx xxxx xxx<br>&gt; xxxçx xôxé \"xxxxx xxxx xxxxxxx xxx\" xx xxxx "
-               "xxxxé xxx xxx xxxéx xxx<br>&gt; x'x xéxxxxé x'xxxxxxxxx xx xxx \"Xxxx XXX Xxxxx"
-               "x Xxx\". Xx xxxx<br>&gt; xxxxxxxx xxx xxxxxxxxxxxxxxxx.xx (xxxxxxx xxxxxxxxxx "
-               "xx .xxx). Xxxx<br>&gt; êxxx xxx xxxxxxxxxxx xxxéxxxxxxxx, xxxx xxxxx xx XXX xx "
-               "xéxxx à xx<br>&gt; xxx \"xxx xxxxxx xxxx xx xxxxxxx\" xx xxxx xx xxxxx xxxxxxxx "
-               "xxxxxxxx<br>&gt; xx $ xx xxxx x'xxxxxx.</div><div style=\"width: 71ch;\">"
-               "&gt; <br></div><div style=\"width: 71ch;\">&gt; Xxxx xx xéxxxxxxx, xxxxxxxx xxxxxxx "
-               "(!), xxxxxxx à xxx, xxxx ooo$ XXX<br>&gt; xxxxé: <br>&gt; <a href=\"https://xxxxx";
-               "xxxxxxxxxxx.xx/xxxxxxx/xxxxx-xxxx-xxxxxxxx-xxxxx-xxxx-xxx-xxxxxxxx-xxx/\">https://";
-               "xxxxxxxxxxxxxxxx.xx/xxxxxxx/xxxxx-xxxx-xxxxxxxx-xxxxx-xxxx-xxx-xxxxxxxx-xxx/</a><br>"
-               "&gt; xx xx xxxx xéxéxxxxxxx x'xxxxxx xxxx xx xxxxxx xx xxxxxxxxxxxx xx xxx<br>&gt; ("
-               "xxxxx Xxxxxx) xxxx xxxx x'xxxxxxx xx xxxxxx: <br>&gt; <a href=\"https://xxxxxxxxxxxxxx";
-               "xx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxxxxxxxxx-Xxxxx-Xxxx-XXX-Xxxxxx-Xxx.xxx\">https://xxxxxx";
+               HTML_PREFIX "<div style=\"width: 71ch;\">On Today, User wrote:</div><blockquote 
type=\"cite\">"
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxxx xx xxxxxxxxx xx xxxxxxx xx xxxxx xxxx xxxx xx xxx xxx 
xxxx xxx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xxxçx xôxé \"xxxxx xxxx xxxxxxx xxx\" xx xxxx xxxxé xxx xxx xxxéx 
xxx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "x'x xéxxxxé x'xxxxxxxxx xx xxx \"Xxxx XXX Xxxxxx Xxx\". Xx xxxx<br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xxxxxxxx xxx xxxxxxxxxxxxxxxx.xx (xxxxxxx xxxxxxxxxx xx .xxx). 
Xxxx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "êxxx xxx xxxxxxxxxxx xxxéxxxxxxxx, xxxx xxxxx xx XXX xx xéxxx à xx<br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xxx \"xxx xxxxxx xxxx xx xxxxxxx\" xx xxxx xx xxxxx xxxxxxxx 
xxxxxxxx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xx $ xx xxxx x'xxxxxx.</div>"
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "<br></div>"
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxx xx xéxxxxxxx, xxxxxxxx xxxxxxx (!), xxxxxxx à xxx, xxxx 
ooo$ XXX<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xxxxé:<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "<a 
href=\"https://xxxxxxxxxxxxxxxx.xx/xxxxxxx/xxxxx-xxxx-xxxxxxxx-xxxxx-xxxx-xxx-xxxxxxxx-xxx/\";>https://";
+               "xxxxxxxxxxxxxxxx.xx/xxxxxxx/xxxxx-xxxx-xxxxxxxx-xxxxx-xxxx-xxx-xxxxxxxx-xxx/</a><br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xx xx xxxx xéxéxxxxxxx x'xxxxxx xxxx xx xxxxxx xx xxxxxxxxxxxx xx 
xxx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "(xxxxx Xxxxxx) xxxx xxxx x'xxxxxxx xx xxxxxx:<br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "<a 
href=\"https://xxxxxxxxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxxxxxxxxx-Xxxxx-Xxxx-XXX-Xxxxxx-Xxx.xxx\";>https://xxxxxx";
                "xxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxxxxxxxxx-Xxxxx-Xxxx-XXX-Xxxxxx-Xxx.xxx</a></div>"
-               "<div style=\"width: 71ch;\">&gt; <br></div><div style=\"width: 71ch;\">&gt; Xxxx xxx x"
-               "xx xxxxxxx xxxxxxxéxx x'xxxêxxxx à xxxxx, xxx xx xxxxé xx<br>&gt; oooxooo xxxxx xxxxx "
-               "xxxx... xxxx x'xxx xxxxxxxxxxxx xxxxx xxx<br>&gt; xxxxxxxx xx \"xx xxxxx xxx xxx xxxxx"
-               "xx xxxxxxx xxxxxxxxxxxxxx xxxx<br>&gt; xxxxx xxxxxx xx xx xxxx xx x'xxxxxx\". Xx xxxx-"
-               "êxxx xxx xx xxxxxxxx xx<br>&gt; xxxx \"x'xxxêxx à xxxxx xx oooxooo xxxx xxx xéxxxxxxxx, "
-               "xxxx\"...</div><div style=\"width: 71ch;\">&gt; <br></div><div style=\"width: 71ch;\">"
-               "&gt; Xxxxx xxxxxx'xx xxx x xxxx xxxxxxx xxxxx xx xxèx xxxxxxxxx<br>&gt; <br>&gt; xxxxxx"
-               "xxxxxxxxxx à xx xxx x'xx xx xêxx (éxxxxxxxxx xxxx-xx-xxxxxxxx): <a href=\"https://xxxxx";
-               "xxxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxx-xxxx-xxx-xxxxxxxxxx-xxxxx.xxx\">https://xxxxxx";
-               "xxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxx-xxxx-xxx-<br>&gt; xxxxxxxxxx-xxxxx.xxx</a> ;&nbsp;"
-               "</div><div style=\"width: 71ch;\">&gt; <br></div><div style=\"width: 71ch;\">&gt; ...x'"
-               "x xxxxx xx xxxxxx x'xxxxxx xéxxxxxxx, xx xxx xxxx xxxxxx<br>&gt; x'xxxxxxxxxxx xxxxxx, "
-               "xxxx <br>&gt; <a href=\"https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/\";>"
-               "https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/</a> xxxxx xxx <br>&gt; <a "
-               "href=\"https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/\";>https://xxxxxxxxx";
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "<br></div>"
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxx xxx xxx xxxxxxx xxxxxxxéxx x'xxxêxxxx à xxxxx, xxx xx 
xxxxé xx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "oooxooo xxxxx xxxxx xxxx... xxxx x'xxx xxxxxxxxxxxx xxxxx xxx<br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xxxxxxxx xx \"xx xxxxx xxx xxx xxxxxxx xxxxxxx xxxxxxxxxxxxxx xxxx<br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xxxxx xxxxxx xx xx xxxx xx x'xxxxxx\". Xx xxxx-êxxx xxx xx xxxxxxxx 
xx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xxxx \"x'xxxêxx à xxxxx xx oooxooo xxxx xxx xéxxxxxxxx, 
xxxx\"...</div>"
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "<br></div>"
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxxx xxxxxx'xx xxx x xxxx xxxxxxx xxxxx xx xxèx xxxxxxxxx<br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "xxxxxxxxxxxxxxxx à xx xxx x'xx xx xêxx (éxxxxxxxxx 
xxxx-xx-xxxxxxxx):<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "<a 
href=\"https://xxxxxxxxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxx-xxxx-xxx-xxxxxxxxxx-xxxxx.xxx\";>https://xxxxxx";
+               "xxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxx-xxxx-xxx-xxxxxxxxxx-xxxxx.xxx</a><br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) ";&nbsp;</div>"
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "<br></div>"
+               "<div>" QUOTE_SPAN (QUOTE_CHR) "...x'x xxxxx xx xxxxxx x'xxxxxx xéxxxxxxx, xx xxx xxxx 
xxxxxx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "x'xxxxxxxxxxx xxxxxx, xxxx<br class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "<a 
href=\"https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/\";>"
+               "https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/</a> xxxxx xxx<br 
class=\"-x-evo-wrap-br\">"
+               QUOTE_SPAN (QUOTE_CHR) "<a 
href=\"https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/\";>https://xxxxxxxxx";
                "xxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/</a> ...</div></blockquote>" HTML_SUFFIX,
                "On Today, User wrote:\n"
                "> Xxxxx xx xxxxxxxxx xx xxxxxxx xx xxxxx xxxx xxxx xx xxx xxx xxxx xxx\n"
@@ -1254,10 +1299,10 @@ test_bug_788829 (TestFixture *fixture)
                "> xx $ xx xxxx x'xxxxxx.\n"
                "> \n"
                "> Xxxx xx xéxxxxxxx, xxxxxxxx xxxxxxx (!), xxxxxxx à xxx, xxxx ooo$ XXX\n"
-               "> xxxxé: \n"
+               "> xxxxé:\n"
                "> https://xxxxxxxxxxxxxxxx.xx/xxxxxxx/xxxxx-xxxx-xxxxxxxx-xxxxx-xxxx-xxx-xxxxxxxx-xxx/\n";
                "> xx xx xxxx xéxéxxxxxxx x'xxxxxx xxxx xx xxxxxx xx xxxxxxxxxxxx xx xxx\n"
-               "> (xxxxx Xxxxxx) xxxx xxxx x'xxxxxxx xx xxxxxx: \n"
+               "> (xxxxx Xxxxxx) xxxx xxxx x'xxxxxxx xx xxxxxx:\n"
                "> 
https://xxxxxxxxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxxxxxxxxx-Xxxxx-Xxxx-XXX-Xxxxxx-Xxx.xxx\n";
                "> \n"
                "> Xxxx xxx xxx xxxxxxx xxxxxxxéxx x'xxxêxxxx à xxxxx, xxx xx xxxxé xx\n"
@@ -1267,14 +1312,14 @@ test_bug_788829 (TestFixture *fixture)
                "> xxxx \"x'xxxêxx à xxxxx xx oooxooo xxxx xxx xéxxxxxxxx, xxxx\"...\n"
                "> \n"
                "> Xxxxx xxxxxx'xx xxx x xxxx xxxxxxx xxxxx xx xxèx xxxxxxxxx\n"
-               "> \n"
-               "> xxxxxxxxxxxxxxxx à xx xxx x'xx xx xêxx (éxxxxxxxxx xxxx-xx-xxxxxxxx): 
https://xxxxxxxxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxx-xxxx-xxx-\n";
-               "> xxxxxxxxxx-xxxxx.xxx ; \n"
+               "> xxxxxxxxxxxxxxxx à xx xxx x'xx xx xêxx (éxxxxxxxxx xxxx-xx-xxxxxxxx):\n"
+               "> https://xxxxxxxxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxx-xxxx-xxx-xxxxxxxxxx-xxxxx.xxx\n";
+               "> ; \n"
                "> \n"
                "> ...x'x xxxxx xx xxxxxx x'xxxxxx xéxxxxxxx, xx xxx xxxx xxxxxx\n"
-               "> x'xxxxxxxxxxx xxxxxx, xxxx \n"
-               "> https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/ xxxxx xxx \n"
-               "> https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/ ..."))
+               "> x'xxxxxxxxxxx xxxxxx, xxxx\n"
+               "> https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/ xxxxx xxx\n"
+               "> https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/ ...\n"))
                g_test_fail ();
 }
 
@@ -1340,26 +1385,26 @@ test_bug_750636 (TestFixture *fixture)
                "B\n\n"
                "12345678901234567890123456789012345678901234567890123456789012345678901\n"
                "C\n\n"
-               "1234567890123456789012345678901234567890123456789012345678901234567890 \n"
+               "1234567890123456789012345678901234567890123456789012345678901234567890\n"
                "D\n\n"
                "12345678901234567890123456789012345678901234567890123456789012345678901\n"
-               "   E\n\n"
-               "1234567890123456789012345678901234567890123456789012345678901234567890 \n"
-               "  F\n\n"
+               UNICODE_NBSP UNICODE_NBSP UNICODE_NBSP "E\n\n"
+               "1234567890123456789012345678901234567890123456789012345678901234567890" UNICODE_NBSP "\n"
+               UNICODE_NBSP UNICODE_NBSP "F\n\n"
                " 1\n"
                "  2\n"
                "   3\n"
                "\n"
-               "prefix text \n"
+               "prefix text\n"
                
"https://www.gnome.org/1234567890123456789012345678901234567890123456789012345678901234567890\n";
                "after text\n"
                "prefix text https://www.gnome.org/123456789012345678901234567890123\n";
                "after text\n"
-               "prefix text https://www.gnome.org/12345678901234567890 \n"
+               "prefix text https://www.gnome.org/12345678901234567890\n";
                "https://www.gnome.org/12345678901234567890 after text\n"
-               "prefix text \n"
+               "prefix text\n"
                
"https://www.gnome.org/1234567890123456789012345678901234567890123456789012345678901234567890\n";
-               " next line text\n"))
+               " next line text\n\n"))
                g_test_fail ();
 }
 
diff --git a/src/e-util/test-web-view-jsc.c b/src/e-util/test-web-view-jsc.c
index 44a56d1c75..29b8051502 100644
--- a/src/e-util/test-web-view-jsc.c
+++ b/src/e-util/test-web-view-jsc.c
@@ -2562,7 +2562,42 @@ test_convert_to_plain (TestFixture *fixture)
        /* 59 */{ HTML ("<div style='width:16ch'>before <a href='https://no.where/'>anchor text</a> 
after</div>"),
                "before anchor\n"
                "text after\n",
-               16 }
+               16 },
+       /* 60 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\"><a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br 
class=\"-x-evo-wrap-br\">text after</div>"),
+               "text\n"
+               "before\n"
+               "https://no.where/1234567890/123457890/1234567890\n";
+               "text\n"
+               "after\n",
+               6 },
+       /* 61 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\"><a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br 
class=\"-x-evo-wrap-br\">text after</div>"),
+               "text\n"
+               "before\n"
+               "https://no.where/1234567890/123457890/1234567890\n";
+               "text\n"
+               "after\n",
+               9 },
+       /* 62 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\"><a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br 
class=\"-x-evo-wrap-br\">text after</div>"),
+               "text\n"
+               "before\n"
+               "https://no.where/1234567890/123457890/1234567890\n";
+               "text after\n",
+               10 },
+       /* 63 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\"><a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br 
class=\"-x-evo-wrap-br\">text after</div>"),
+               "text before\n"
+               "https://no.where/1234567890/123457890/1234567890\n";
+               "text after\n",
+               11 },
+       /* 64 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\"><a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br 
class=\"-x-evo-wrap-br\">text after</div>"),
+               "text before\n"
+               "https://no.where/1234567890/123457890/1234567890\n";
+               "text after\n",
+               12 },
+       /* 65 */{ HTML ("<div>text before<br><a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br>text after</div>"),
+               "text before\n"
+               "https://no.where/1234567890/123457890/1234567890\n";
+               "text after\n",
+               12 }
        };
 
        #undef HTML
@@ -2591,6 +2626,8 @@ static void
 test_convert_to_plain_quoted (TestFixture *fixture)
 {
        #define HTML(_body) ("<html><head><style><!-- span.Apple-tab-span { white-space:pre; } 
--></style></head><body style='font-family:monospace;'>" _body "</body></html>")
+       #define QUOTE_SPAN(x) "<span class='-x-evo-quoted'>" x "</span>"
+       #define QUOTE_CHR "<span class='-x-evo-quote-character'>&gt; </span>"
 
        struct _tests {
                const gchar *html;
@@ -2778,9 +2815,70 @@ test_convert_to_plain_quoted (TestFixture *fixture)
                "</blockquote>"),
                "> > before anchor\n"
                "> > text after\n",
-               16 }
+               16 },
+       /* 15 */{ HTML ("<blockquote type='cite'>"
+                       "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "<a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "text after</div>"
+               "</blockquote>"),
+               "> text\n"
+               "> before\n"
+               "> https://no.where/1234567890/123457890/1234567890\n";
+               "> text\n"
+               "> after\n",
+               8 },
+       /* 16 */{ HTML ("<blockquote type='cite'>"
+                       "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "<a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "text after</div>"
+               "</blockquote>"),
+               "> text\n"
+               "> before\n"
+               "> https://no.where/1234567890/123457890/1234567890\n";
+               "> text\n"
+               "> after\n",
+               11 },
+       /* 17 */{ HTML ("<blockquote type='cite'>"
+                       "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "<a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "text after</div>"
+               "</blockquote>"),
+               "> text\n"
+               "> before\n"
+               "> https://no.where/1234567890/123457890/1234567890\n";
+               "> text after\n",
+               12 },
+       /* 18 */{ HTML ("<blockquote type='cite'>"
+                       "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "<a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "text after</div>"
+               "</blockquote>"),
+               "> text before\n"
+               "> https://no.where/1234567890/123457890/1234567890\n";
+               "> text after\n",
+               13 },
+       /* 19 */{ HTML ("<blockquote type='cite'>"
+                       "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "<a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\">"
+                       QUOTE_SPAN (QUOTE_CHR) "text after</div>"
+               "</blockquote>"),
+               "> text before\n"
+               "> https://no.where/1234567890/123457890/1234567890\n";
+               "> text after\n",
+               14 },
+       /* 20 */{ HTML ("<blockquote type='cite'>"
+                       "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br>"
+                       QUOTE_SPAN (QUOTE_CHR) "<a 
href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br>"
+                       QUOTE_SPAN (QUOTE_CHR) "text after</div>"
+               "</blockquote>"),
+               "> text before\n"
+               "> https://no.where/1234567890/123457890/1234567890\n";
+               "> text after\n",
+               14 }
        };
 
+       #undef QUOTE_SPAN
+       #undef QUOTE_CHR
        #undef HTML
 
        gchar *script;
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index 897905c66b..713bf1b0d6 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -69,7 +69,8 @@ enum {
        PROP_NORMAL_PARAGRAPH_WIDTH,
        PROP_MAGIC_LINKS,
        PROP_MAGIC_SMILEYS,
-       PROP_UNICODE_SMILEYS
+       PROP_UNICODE_SMILEYS,
+       PROP_WRAP_QUOTED_TEXT_IN_REPLIES
 };
 
 struct _EWebKitEditorPrivate {
@@ -110,6 +111,7 @@ struct _EWebKitEditorPrivate {
        gboolean magic_links;
        gboolean magic_smileys;
        gboolean unicode_smileys;
+       gboolean wrap_quoted_text_in_replies;
 
        EContentEditorBlockFormat block_format;
        EContentEditorAlignment alignment;
@@ -3975,6 +3977,31 @@ webkit_editor_get_unicode_smileys (EWebKitEditor *wk_editor)
        return wk_editor->priv->unicode_smileys;
 }
 
+static void
+webkit_editor_set_wrap_quoted_text_in_replies (EWebKitEditor *wk_editor,
+                                              gboolean value)
+{
+       g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
+
+       if ((wk_editor->priv->wrap_quoted_text_in_replies ? 1 : 0) != (value ? 1 : 0)) {
+               wk_editor->priv->wrap_quoted_text_in_replies = value;
+
+               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+                       "EvoEditor.WRAP_QUOTED_TEXT_IN_REPLIES = %x;",
+                       value);
+
+               g_object_notify (G_OBJECT (wk_editor), "wrap-quoted-text-in-replies");
+       }
+}
+
+static gboolean
+webkit_editor_get_wrap_quoted_text_in_replies (EWebKitEditor *wk_editor)
+{
+       g_return_val_if_fail (E_IS_WEBKIT_EDITOR (wk_editor), FALSE);
+
+       return wk_editor->priv->wrap_quoted_text_in_replies;
+}
+
 static void
 e_webkit_editor_initialize_web_extensions_cb (WebKitWebContext *web_context,
                                              gpointer user_data)
@@ -4082,6 +4109,11 @@ webkit_editor_constructed (GObject *object)
                wk_editor, "unicode-smileys",
                G_SETTINGS_BIND_GET);
 
+       g_settings_bind (
+               settings, "composer-wrap-quoted-text-in-replies",
+               wk_editor, "wrap-quoted-text-in-replies",
+               G_SETTINGS_BIND_GET);
+
        g_object_unref (settings);
 
        webkit_web_view_load_html (WEBKIT_WEB_VIEW (wk_editor), "", "evo-file:///");
@@ -4289,6 +4321,12 @@ webkit_editor_set_property (GObject *object,
                                g_value_get_boolean (value));
                        return;
 
+               case PROP_WRAP_QUOTED_TEXT_IN_REPLIES:
+                       webkit_editor_set_wrap_quoted_text_in_replies (
+                               E_WEBKIT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
                case PROP_ALIGNMENT:
                        webkit_editor_set_alignment (
                                E_WEBKIT_EDITOR (object),
@@ -4482,6 +4520,11 @@ webkit_editor_get_property (GObject *object,
                                webkit_editor_get_unicode_smileys (E_WEBKIT_EDITOR (object)));
                        return;
 
+               case PROP_WRAP_QUOTED_TEXT_IN_REPLIES:
+                       g_value_set_boolean (value,
+                               webkit_editor_get_wrap_quoted_text_in_replies (E_WEBKIT_EDITOR (object)));
+                       return;
+
                case PROP_ALIGNMENT:
                        g_value_set_enum (
                                value,
@@ -5379,6 +5422,19 @@ e_webkit_editor_class_init (EWebKitEditorClass *class)
                        G_PARAM_READWRITE |
                        G_PARAM_CONSTRUCT |
                        G_PARAM_STATIC_STRINGS));
+
+
+       g_object_class_install_property (
+               object_class,
+               PROP_WRAP_QUOTED_TEXT_IN_REPLIES,
+               g_param_spec_boolean (
+                       "wrap-quoted-text-in-replies",
+                       NULL,
+                       NULL,
+                       TRUE, /* Should be the same as e-editor.js:EvoEditor.WRAP_QUOTED_TEXT_IN_REPLIES and 
in the init() */
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -5401,6 +5457,7 @@ e_webkit_editor_init (EWebKitEditor *wk_editor)
        wk_editor->priv->magic_links = TRUE;
        wk_editor->priv->magic_smileys = FALSE;
        wk_editor->priv->unicode_smileys = FALSE;
+       wk_editor->priv->wrap_quoted_text_in_replies = TRUE;
 
        g_signal_connect (
                wk_editor, "load-changed",



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