[evolution/wip/mcrha/webkit-jsc-api] Split of blockquote on Enter/Shift+Enter



commit f1590f6f9a89d8b9b96fc9705d1cca14df4c52d9
Author: Milan Crha <mcrha redhat com>
Date:   Tue Mar 17 19:15:44 2020 +0100

    Split of blockquote on Enter/Shift+Enter

 data/webkit/e-editor.js                     | 194 ++++++++++-
 src/e-util/test-html-editor-units.c         | 480 ++++++++++++++++++++++++++++
 src/e-util/test-html-editor.c               |  11 +
 src/modules/webkit-editor/e-webkit-editor.c | 104 +++---
 4 files changed, 728 insertions(+), 61 deletions(-)
---
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index 25f34646f5..c3de6f2b8d 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -1789,6 +1789,8 @@ EvoEditor.quoteParagraph = function(paragraph, blockquoteLevel, wrapWidth)
        if (!paragraph || !(blockquoteLevel > 0))
                return;
 
+       EvoEditor.removeQuoteMarks(paragraph);
+
        var node = paragraph.firstChild, next, lineLength = 0;
        var prefixHtml = EvoEditor.getBlockquotePrefixHtml(blockquoteLevel);
 
@@ -1880,7 +1882,7 @@ EvoEditor.reBlockquotePlainText = function(plainText)
        return html;
 }
 
-EvoEditor.convertParagraphs = function(parent, wrapWidth, blockquoteLevel)
+EvoEditor.convertParagraphs = function(parent, blockquoteLevel, wrapWidth)
 {
        if (!parent)
                return;
@@ -1937,7 +1939,7 @@ EvoEditor.convertParagraphs = function(parent, wrapWidth, blockquoteLevel)
                        if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT && !blockquoteLevel)
                                child.innerHTML = 
EvoEditor.reBlockquotePlainText(EvoConvert.ToPlainText(child, -1));
 
-                       EvoEditor.convertParagraphs(child, innerWrapWidth, blockquoteLevel + 1);
+                       EvoEditor.convertParagraphs(child, blockquoteLevel + 1, innerWrapWidth);
                } else if (child.tagName == "UL") {
                        if (wrapWidth == -1) {
                                child.style.width = "";
@@ -1983,7 +1985,7 @@ EvoEditor.SetNormalParagraphWidth = function(value)
                EvoEditor.NORMAL_PARAGRAPH_WIDTH = value;
 
                if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT)
-                       EvoEditor.convertParagraphs(document.body, EvoEditor.NORMAL_PARAGRAPH_WIDTH, 0);
+                       EvoEditor.convertParagraphs(document.body, 0, EvoEditor.NORMAL_PARAGRAPH_WIDTH);
        }
 }
 
@@ -2070,11 +2072,14 @@ EvoEditor.convertTags = function()
        document.body.normalize();
 }
 
-EvoEditor.removeQuoteMarks = function()
+EvoEditor.removeQuoteMarks = function(element)
 {
        var ii, list;
 
-       list = document.querySelectorAll("span.-x-evo-quoted");
+       if (!element)
+               element = document;
+
+       list = element.querySelectorAll("span.-x-evo-quoted");
 
        for (ii = list.length - 1; ii >= 0; ii--) {
                var node = list[ii];
@@ -2082,7 +2087,7 @@ EvoEditor.removeQuoteMarks = function()
                node.parentElement.removeChild(node);
        }
 
-       list = document.querySelectorAll("br.-x-evo-wrap-br");
+       list = element.querySelectorAll("br.-x-evo-wrap-br");
 
        for (ii = list.length - 1; ii >= 0; ii--) {
                var node = list[ii];
@@ -2091,7 +2096,7 @@ EvoEditor.removeQuoteMarks = function()
                node.parentElement.removeChild(node);
        }
 
-       list = document.querySelectorAll("div[x-evo-width]");
+       list = element.querySelectorAll("div[x-evo-width]");
 
        for (ii = list.length - 1; ii >= 0; ii--) {
                var node = list[ii];
@@ -2099,7 +2104,10 @@ EvoEditor.removeQuoteMarks = function()
                node.removeAttribute("x-evo-width");
        }
 
-       document.body.normalize();
+       if (element === document)
+               document.body.normalize();
+       else
+               element.normalize();
 }
 
 EvoEditor.SetMode = function(mode)
@@ -2125,13 +2133,13 @@ EvoEditor.SetMode = function(mode)
                try {
                        EvoEditor.mode = mode;
 
-                       EvoEditor.removeQuoteMarks();
+                       EvoEditor.removeQuoteMarks(null);
 
                        if (mode == EvoEditor.MODE_PLAIN_TEXT) {
                                EvoEditor.convertTags();
-                               EvoEditor.convertParagraphs(document.body, EvoEditor.NORMAL_PARAGRAPH_WIDTH, 
0);
+                               EvoEditor.convertParagraphs(document.body, 0, 
EvoEditor.NORMAL_PARAGRAPH_WIDTH);
                        } else {
-                               EvoEditor.convertParagraphs(document.body, -1, 0);
+                               EvoEditor.convertParagraphs(document.body, 0, -1);
                        }
                } finally {
                        EvoUndoRedo.Enable();
@@ -2728,6 +2736,41 @@ EvoEditor.maybeUpdateParagraphWidth = function(topNode)
        }
 }
 
+EvoEditor.splitAtChild = function(parent, childNode)
+{
+       var newNode, node, next, ii;
+
+       newNode = parent.ownerDocument.createElement(parent.tagName);
+
+       for (ii = 0; ii < parent.attributes.length; ii++) {
+               newNode.setAttribute(parent.attributes[ii].nodeName, parent.attributes[ii].nodeValue);
+       }
+
+       node = childNode;
+       while (node) {
+               next = node.nextSibling;
+               newNode.appendChild(node);
+               node = next;
+       }
+
+       parent.parentElement.insertBefore(newNode, parent.nextSibling);
+
+       return newNode;
+}
+
+EvoEditor.hasElementWithTagNameAsParent = function(node, tagName)
+{
+       if (!node)
+               return false;
+
+       for (node = node.parentElement; node; node = node.parentElement) {
+               if (node.tagName == tagName)
+                       return true;
+       }
+
+       return false;
+}
+
 EvoEditor.AfterInputEvent = function(inputEvent, isWordDelim)
 {
        var isInsertParagraph = inputEvent.inputType == "insertParagraph";
@@ -2785,6 +2828,135 @@ EvoEditor.AfterInputEvent = function(inputEvent, isWordDelim)
                }
        }
 
+       // special editing of blockquotes
+       if ((isInsertParagraph || inputEvent.inputType == "insertLineBreak") &&
+           selection.isCollapsed && EvoEditor.hasElementWithTagNameAsParent(selection.anchorNode, 
"BLOCKQUOTE")) {
+               // insertParagraph should split the blockquote into two
+               if (isInsertParagraph) {
+                       var node = selection.anchorNode, childNode = node, parent, removeNode = null;
+
+                       for (parent = node.parentElement; parent && parent.tagName != "BODY"; parent = 
parent.parentElement) {
+                               if (parent.tagName == "BLOCKQUOTE") {
+                                       childNode = parent;
+                               }
+                       }
+
+                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "blockquoteSplit", childNode, 
childNode,
+                               EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+
+                       try {
+                               if (node.nodeType == node.ELEMENT_NODE && node.childNodes.length == 1 && 
node.firstChild.tagName == "BR")
+                                       removeNode = node;
+                               else if (node.nodeType == node.ELEMENT_NODE && node.childNodes.length > 1 && 
node.firstChild.tagName == "BR")
+                                       removeNode = node.firstChild;
+
+                               childNode = node;
+
+                               for (parent = node.parentElement; parent && parent.tagName != "BODY"; parent 
= parent.parentElement) {
+                                       if (parent.tagName == "BLOCKQUOTE") {
+                                               childNode = EvoEditor.splitAtChild(parent, childNode);
+                                               parent = childNode;
+                                       } else {
+                                               childNode = parent;
+                                       }
+                               }
+
+                               if (parent) {
+                                       var divNode = document.createElement("DIV");
+                                       divNode.appendChild(document.createElement("BR"));
+                                       parent.insertBefore(divNode, childNode);
+                                       document.getSelection().setPosition(divNode, 0);
+                                       EvoEditor.maybeUpdateParagraphWidth(divNode);
+                               }
+
+                               while (removeNode && removeNode.tagName != "BODY") {
+                                       node = removeNode.parentElement;
+                                       node.removeChild(removeNode);
+
+                                       if (node.childNodes.length)
+                                               break;
+
+                                       removeNode = node;
+                               }
+
+                               if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT) {
+                                       node = document.getSelection().anchorNode;
+
+                                       if (node && node.nextElementSibling) {
+                                               var blockquoteLevel = (node.nextElementSibling.tagName == 
"BLOCKQUOTE" ? 1 : 0);
+
+                                               EvoEditor.convertParagraphs(node.nextElementSibling, 
blockquoteLevel,
+                                                       EvoEditor.NORMAL_PARAGRAPH_WIDTH - (blockquoteLevel * 
2));
+                                       }
+
+                                       if (node && node.previousElementSibling) {
+                                               var blockquoteLevel = (node.previousElementSibling.tagName == 
"BLOCKQUOTE" ? 1 : 0);
+
+                                               EvoEditor.convertParagraphs(node.previousElementSibling, 
blockquoteLevel,
+                                                       EvoEditor.NORMAL_PARAGRAPH_WIDTH - (blockquoteLevel * 
2));
+                                       }
+                               }
+                       } finally {
+                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "blockquoteSplit");
+                               EvoUndoRedo.GroupTopRecords(2, "insertParagraph::blockquoteSplit");
+                               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+                               EvoEditor.EmitContentChanged();
+                       }
+               // insertLineBreak should re-quote text in the Plain Text mode
+               } else if (inputEvent.inputType == "insertLineBreak") {
+                       if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT) {
+                               var selNode = document.getSelection().anchorNode, node = selNode, parent;
+
+                               while (node && node.tagName != "BODY" && !EvoEditor.IsBlockNode(node)) {
+                                       node = node.parentElement;
+                               }
+
+                               if (node && node.tagName != "BODY" && selNode.previousSibling && 
selNode.previousSibling.nodeValue == "\n") {
+                                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "requote", 
node, node,
+                                               EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+
+                                       try {
+                                               var blockquoteLevel;
+
+                                               // the "\n" is replaced with full paragraph
+                                               selNode.parentElement.removeChild(selNode.previousSibling);
+
+                                               parent = selNode.parentElement;
+
+                                               var childNode = selNode;
+
+                                               while (parent && parent.tagName != "BODY") {
+                                                       childNode = EvoEditor.splitAtChild(parent, childNode);
+
+                                                       if (childNode === node || 
EvoEditor.IsBlockNode(parent))
+                                                               break;
+
+                                                       parent = childNode.parentElement;
+                                               }
+
+                                               blockquoteLevel = 0;
+
+                                               while (parent && parent.tagName != "BODY") {
+                                                       if (parent.tagName == "BLOCKQUOTE")
+                                                               blockquoteLevel++;
+
+                                                       parent = parent.parentElement;
+                                               }
+
+                                               EvoEditor.quoteParagraph(childNode, blockquoteLevel, 
EvoEditor.NORMAL_PARAGRAPH_WIDTH - (2 * blockquoteLevel));
+
+                                               document.getSelection().setPosition(childNode, 0);
+                                       } finally {
+                                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
"requote");
+                                               EvoUndoRedo.GroupTopRecords(2, "insertLineBreak::requote");
+                                               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+                                               EvoEditor.EmitContentChanged();
+                                       }
+                               }
+                       }
+               }
+       }
+
        if ((!isInsertParagraph && inputEvent.inputType != "insertText") ||
            (!(EvoEditor.MAGIC_LINKS && (isWordDelim || isInsertParagraph)) &&
            !EvoEditor.MAGIC_SMILEYS)) {
diff --git a/src/e-util/test-html-editor-units.c b/src/e-util/test-html-editor-units.c
index dc10c00411..d0ab4ccc02 100644
--- a/src/e-util/test-html-editor-units.c
+++ b/src/e-util/test-html-editor-units.c
@@ -4878,6 +4878,484 @@ test_cite_reply_plain (TestFixture *fixture)
                g_test_fail ();
 }
 
+static void
+test_cite_editing_html (TestFixture *fixture)
+{
+       const gchar *plain0, *html0, *plain1, *html1, *plain2, *html2, *plain3, *html3, *plain4, *html4;
+
+       if (!test_utils_process_commands (fixture,
+               "mode:html\n")) {
+               g_test_fail ();
+               return;
+       }
+
+       test_utils_insert_content (fixture,
+               "<div>before citation</div>"
+               "<blockquote type='cite'>"
+                       "<div>cite level 1a</div>"
+                       "<blockquote type='cite'>"
+                               "<div>cite level 2</div>"
+                       "</blockquote>"
+                       "<div>cite level 1b</div>"
+               "</blockquote>"
+               "<div>after citation</div>",
+               E_CONTENT_EDITOR_INSERT_REPLACE_ALL | E_CONTENT_EDITOR_INSERT_TEXT_HTML);
+
+       html0 = HTML_PREFIX "<div>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div>cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div>cite level 2</div>"
+                       "</blockquote>"
+                       "<div>cite level 1b</div>"
+               "</blockquote>"
+               "<div>after citation</div>" HTML_SUFFIX;
+
+       plain0 = "before citation\n"
+               "> cite level 1a\n"
+               "> > cite level 2\n"
+               "> cite level 1b\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture, "", html0, plain0)) {
+               g_test_fail ();
+               return;
+       }
+
+       html1 = HTML_PREFIX "<div>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div>cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div>ciXte level 2</div>"
+                       "</blockquote>"
+                       "<div>cite level 1b</div>"
+               "</blockquote>"
+               "<div>after citation</div>" HTML_SUFFIX;
+
+       plain1 = "before citation\n"
+               "> cite level 1a\n"
+               "> > ciXte level 2\n"
+               "> cite level 1b\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture,
+               "seq:Chc\n" /* Ctrl+Home to get to the beginning of the document */
+               "seq:ddrr\n" /* on the third line, after the second character */
+               "type:X\n",
+               html1, plain1)) {
+               g_test_fail ();
+               return;
+       }
+
+       html2 = HTML_PREFIX "<div>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div>cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div>ciX</div>"
+                       "</blockquote>"
+               "</blockquote>"
+               "<div>Y</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div>te level 2</div>"
+                       "</blockquote>"
+                       "<div>cite level 1b</div>"
+               "</blockquote>"
+               "<div>after citation</div>" HTML_SUFFIX;
+
+       plain2 = "before citation\n"
+               "> cite level 1a\n"
+               "> > ciX\n"
+               "Y\n"
+               "> > te level 2\n"
+               "> cite level 1b\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture,
+               "type:\\nY\n",
+               html2, plain2)) {
+               g_test_fail ();
+               return;
+       }
+
+       html3 = HTML_PREFIX "<div>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div>cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div>ciX</div>"
+                       "</blockquote>"
+               "</blockquote>"
+               "<div>Y</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div>tZ<br>e level 2</div>"
+                       "</blockquote>"
+                       "<div>cite level 1b</div>"
+               "</blockquote>"
+               "<div>after citation</div>" HTML_SUFFIX;
+
+       plain3 = "before citation\n"
+               "> cite level 1a\n"
+               "> > ciX\n"
+               "Y\n"
+               "> > tZ\n"
+               "> > e level 2\n"
+               "> cite level 1b\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture,
+               "seq:dr\n"
+               "type:Z\n"
+               "seq:Sns\n", /* soft Enter */
+               html3, plain3)) {
+               g_test_fail ();
+               return;
+       }
+
+       html4 = HTML_PREFIX "<div>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div>cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div>ciX</div>"
+                       "</blockquote>"
+               "</blockquote>"
+               "<div>Y</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div>tZ<br>e level 2</div>"
+                       "</blockquote>"
+               "</blockquote>"
+               "<div><br></div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div><br></div>"
+               "</blockquote>"
+               "<div><br></div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div>cite level 1b</div>"
+               "</blockquote>"
+               "<div><br></div>"
+               "<div>after citation</div>" HTML_SUFFIX;
+
+       plain4 = "before citation\n"
+               "> cite level 1a\n"
+               "> > ciX\n"
+               "Y\n"
+               "> > tZ\n"
+               "> > e level 2\n"
+               "\n"
+               "> \n"
+               "\n"
+               "> cite level 1b\n"
+               "\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture,
+               "seq:endhnden\n",
+               html4, plain4)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:undo:3\n",
+               html3, plain3)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:undo:2\n",
+               html2, plain2)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:undo:2\n",
+               html1, plain1)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:undo:1\n",
+               html0, plain0)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:redo:1\n",
+               html1, plain1)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:redo:2\n",
+               html2, plain2)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:redo:2\n",
+               html3, plain3)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:redo:3\n",
+               html4, plain4)) {
+               g_test_fail ();
+               return;
+       }
+}
+
+static void
+test_cite_editing_plain (TestFixture *fixture)
+{
+       const gchar *plain0, *html0, *plain1, *html1, *plain2, *html2, *plain3, *html3, *plain4, *html4;
+
+       if (!test_utils_process_commands (fixture,
+               "mode:html\n")) {
+               g_test_fail ();
+               return;
+       }
+
+       test_utils_insert_content (fixture,
+               "<div>before citation</div>"
+               "<blockquote type='cite'>"
+                       "<div>cite level 1a</div>"
+                       "<blockquote type='cite'>"
+                               "<div>cite level 2</div>"
+                       "</blockquote>"
+                       "<div>cite level 1b</div>"
+               "</blockquote>"
+               "<div>after citation</div>",
+               E_CONTENT_EDITOR_INSERT_REPLACE_ALL | E_CONTENT_EDITOR_INSERT_TEXT_HTML);
+
+       #define QUOTE_SPAN(x) "<span class='-x-evo-quoted'>" x "</span>"
+       #define QUOTE_CHR "<span class='-x-evo-quote-character'>&gt; </span>"
+
+       html0 = HTML_PREFIX "<div style='width: 71ch;'>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "cite level 2</div>"
+                       "</blockquote>"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1b</div>"
+               "</blockquote>"
+               "<div style='width: 71ch;'>after citation</div>" HTML_SUFFIX;
+
+       plain0 = "before citation\n"
+               "> cite level 1a\n"
+               "> > cite level 2\n"
+               "> cite level 1b\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture, "mode:plain\n", html0, plain0)) {
+               g_test_fail ();
+               return;
+       }
+
+       html1 = HTML_PREFIX "<div style='width: 71ch;'>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "ciXte level 
2</div>"
+                       "</blockquote>"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1b</div>"
+               "</blockquote>"
+               "<div style='width: 71ch;'>after citation</div>" HTML_SUFFIX;
+
+       plain1 = "before citation\n"
+               "> cite level 1a\n"
+               "> > ciXte level 2\n"
+               "> cite level 1b\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture,
+               "seq:Chc\n" /* Ctrl+Home to get to the beginning of the document */
+               "seq:ddrr\n" /* on the third line, after the second character */
+               "type:X\n",
+               html1, plain1)) {
+               g_test_fail ();
+               return;
+       }
+
+       html2 = HTML_PREFIX "<div style='width: 71ch;'>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "ciX</div>"
+                       "</blockquote>"
+               "</blockquote>"
+               "<div style='width: 71ch;'>Y</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "te level 2</div>"
+                       "</blockquote>"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1b</div>"
+               "</blockquote>"
+               "<div style='width: 71ch;'>after citation</div>" HTML_SUFFIX;
+
+       plain2 = "before citation\n"
+               "> cite level 1a\n"
+               "> > ciX\n"
+               "Y\n"
+               "> > te level 2\n"
+               "> cite level 1b\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture,
+               "type:\\nY\n",
+               html2, plain2)) {
+               g_test_fail ();
+               return;
+       }
+
+       html3 = HTML_PREFIX "<div style='width: 71ch;'>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "ciX</div>"
+                       "</blockquote>"
+               "</blockquote>"
+               "<div style='width: 71ch;'>Y</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "tZ</div>"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "e level 2</div>"
+                       "</blockquote>"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1b</div>"
+               "</blockquote>"
+               "<div style='width: 71ch;'>after citation</div>" HTML_SUFFIX;
+
+       plain3 = "before citation\n"
+               "> cite level 1a\n"
+               "> > ciX\n"
+               "Y\n"
+               "> > tZ\n"
+               "> > e level 2\n"
+               "> cite level 1b\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture,
+               "seq:dr\n"
+               "type:Z\n"
+               "seq:Sns\n", /* soft Enter */
+               html3, plain3)) {
+               g_test_fail ();
+               return;
+       }
+
+       html4 = HTML_PREFIX "<div style='width: 71ch;'>before citation</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1a</div>"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "ciX</div>"
+                       "</blockquote>"
+               "</blockquote>"
+               "<div style='width: 71ch;'>Y</div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "tZ</div>"
+                               "<div x-evo-width='67'>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "e level 2</div>"
+                       "</blockquote>"
+               "</blockquote>"
+               "<div style='width: 71ch;'><br></div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "<br></div>"
+               "</blockquote>"
+               "<div style='width: 71ch;'><br></div>"
+               "<blockquote type='cite' " /*BLOCKQUOTE_STYLE*/ ">"
+                       "<div x-evo-width='69'>" QUOTE_SPAN (QUOTE_CHR) "cite level 1b</div>"
+               "</blockquote>"
+               "<div style='width: 71ch;'><br></div>"
+               "<div style='width: 71ch;'>after citation</div>" HTML_SUFFIX;
+
+       plain4 = "before citation\n"
+               "> cite level 1a\n"
+               "> > ciX\n"
+               "Y\n"
+               "> > tZ\n"
+               "> > e level 2\n"
+               "\n"
+               "> \n"
+               "\n"
+               "> cite level 1b\n"
+               "\n"
+               "after citation\n";
+
+       if (!test_utils_run_simple_test (fixture,
+               "seq:endhnden\n",
+               html4, plain4)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:undo:3\n",
+               html3, plain3)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:undo:2\n",
+               html2, plain2)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:undo:2\n",
+               html1, plain1)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:undo:1\n",
+               html0, plain0)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:redo:1\n",
+               html1, plain1)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:redo:2\n",
+               html2, plain2)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:redo:2\n",
+               html3, plain3)) {
+               g_test_fail ();
+               return;
+       }
+
+       if (!test_utils_run_simple_test (fixture,
+               "undo:redo:3\n",
+               html4, plain4)) {
+               g_test_fail ();
+               return;
+       }
+
+       #undef QUOTE_CHR
+       #undef QUOTE_SPAN
+}
+
 static void
 test_undo_text_typed (TestFixture *fixture)
 {
@@ -5718,6 +6196,8 @@ main (gint argc,
        test_utils_add_test ("/cite/longline", test_cite_longline);
        test_utils_add_test ("/cite/reply-html", test_cite_reply_html);
        test_utils_add_test ("/cite/reply-plain", test_cite_reply_plain);
+       test_utils_add_test ("/cite/editing-html", test_cite_editing_html);
+       test_utils_add_test ("/cite/editing-plain", test_cite_editing_plain);
        test_utils_add_test ("/undo/text-typed", test_undo_text_typed);
        test_utils_add_test ("/undo/text-forward-delete", test_undo_text_forward_delete);
        test_utils_add_test ("/undo/text-backward-delete", test_undo_text_backward_delete);
diff --git a/src/e-util/test-html-editor.c b/src/e-util/test-html-editor.c
index 7403523ecc..7078d9e371 100644
--- a/src/e-util/test-html-editor.c
+++ b/src/e-util/test-html-editor.c
@@ -504,6 +504,7 @@ static GtkActionEntry view_entries[] = {
 };
 
 static guint glob_editors = 0;
+static const gchar *glob_prefill_body = NULL;
 
 static void
 editor_destroyed_cb (GtkWidget *editor)
@@ -649,6 +650,13 @@ create_new_editor_cb (GObject *source_object,
        }
 
        gtk_ui_manager_ensure_update (manager);
+
+       if (glob_prefill_body) {
+               e_content_editor_insert_content (cnt_editor, glob_prefill_body, 
E_CONTENT_EDITOR_INSERT_REPLACE_ALL |
+                       (*glob_prefill_body == '<' ? E_CONTENT_EDITOR_INSERT_TEXT_HTML : 
E_CONTENT_EDITOR_INSERT_TEXT_PLAIN));
+
+               glob_prefill_body = NULL;
+       }
 }
 
 static void
@@ -681,6 +689,9 @@ main (gint argc,
        modules = e_module_load_all_in_directory (EVOLUTION_MODULEDIR);
        g_list_free_full (modules, (GDestroyNotify) g_type_module_unuse);
 
+       if (argc == 2)
+               glob_prefill_body = argv[1];
+
        create_new_editor ();
 
        gtk_main ();
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index d78bc933b3..932768636f 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -1461,6 +1461,60 @@ webkit_editor_update_styles (EContentEditor *editor)
                        "  word-break: break-word; \n"
                        "  white-space: pre-wrap; \n"
                        "}\n");
+
+               g_string_append (
+                       stylesheet,
+                       ".-x-evo-quoted { -webkit-user-select: none; }\n");
+
+               g_string_append_printf (
+                       stylesheet,
+                       ".-x-evo-quote-character "
+                       "{\n"
+                       "  color: %s;\n"
+                       "}\n",
+                       e_web_view_get_citation_color_for_level (1));
+
+               g_string_append_printf (
+                       stylesheet,
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character"
+                       "{\n"
+                       "  color: %s;\n"
+                       "}\n",
+                       e_web_view_get_citation_color_for_level (2));
+
+               g_string_append_printf (
+                       stylesheet,
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character"
+                       "{\n"
+                       "  color: %s;\n"
+                       "}\n",
+                       e_web_view_get_citation_color_for_level (3));
+
+               g_string_append_printf (
+                       stylesheet,
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character"
+                       "{\n"
+                       "  color: %s;\n"
+                       "}\n",
+                       e_web_view_get_citation_color_for_level (4));
+
+               g_string_append_printf (
+                       stylesheet,
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character+"
+                       ".-x-evo-quote-character"
+                       "{\n"
+                       "  color: %s;\n"
+                       "}\n",
+                       e_web_view_get_citation_color_for_level (5));
        }
 
        g_string_append_printf (
@@ -1531,56 +1585,6 @@ webkit_editor_update_styles (EContentEditor *editor)
 
        g_string_append (stylesheet, "}\n");
 
-       g_string_append_printf (
-               stylesheet,
-               ".-x-evo-quote-character "
-               "{\n"
-               "  color: %s;\n"
-               "}\n",
-               e_web_view_get_citation_color_for_level (1));
-
-       g_string_append_printf (
-               stylesheet,
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character"
-               "{\n"
-               "  color: %s;\n"
-               "}\n",
-               e_web_view_get_citation_color_for_level (2));
-
-       g_string_append_printf (
-               stylesheet,
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character"
-               "{\n"
-               "  color: %s;\n"
-               "}\n",
-               e_web_view_get_citation_color_for_level (3));
-
-       g_string_append_printf (
-               stylesheet,
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character"
-               "{\n"
-               "  color: %s;\n"
-               "}\n",
-               e_web_view_get_citation_color_for_level (4));
-
-       g_string_append_printf (
-               stylesheet,
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character+"
-               ".-x-evo-quote-character"
-               "{\n"
-               "  color: %s;\n"
-               "}\n",
-               e_web_view_get_citation_color_for_level (5));
-
        if (wk_editor->priv->visually_wrap_long_lines) {
                g_string_append (
                        stylesheet,


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