diff options
author | Milan Crha <mcrha@redhat.com> | 2021-05-12 17:55:16 +0200 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2021-05-12 17:57:16 +0200 |
commit | e16cc24ee25f7174b7c9ff086f6667d1d7c09b23 (patch) | |
tree | 594e2779b653d5a79f64e675a6695c63fdd386a5 | |
parent | eb439f826db516023fd97257e4631fb03af18b8e (diff) | |
download | evolution-e16cc24ee25f7174b7c9ff086f6667d1d7c09b23.tar.gz |
I#1392 - Pressing backspace in front of quoted line with link does not delete anything
Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1392
-rw-r--r-- | data/webkit/e-convert.js | 11 | ||||
-rw-r--r-- | data/webkit/e-editor.js | 9 | ||||
-rw-r--r-- | data/webkit/e-selection.js | 98 | ||||
-rw-r--r-- | src/e-util/test-html-editor-units-bugs.c | 148 | ||||
-rw-r--r-- | src/e-util/test-html-editor-units-bugs.h | 1 | ||||
-rw-r--r-- | src/e-util/test-html-editor-units.c | 4 | ||||
-rw-r--r-- | src/e-util/test-web-view-jsc.c | 30 |
7 files changed, 240 insertions, 61 deletions
diff --git a/data/webkit/e-convert.js b/data/webkit/e-convert.js index 7037ae9724..a2cb7e10ac 100644 --- a/data/webkit/e-convert.js +++ b/data/webkit/e-convert.js @@ -584,6 +584,9 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW if (chr == "-" && worker.line.length && !worker.inAnchor) worker.lastWrapableChar = worker.line.length; + else if (chr == EvoConvert.NOWRAP_CHAR_START && quoteLevel > 0 && worker.lastWrapableChar < 0 && worker.inAnchor <= 1 && worker.line.length > 1) { + worker.lastWrapableChar = worker.line.length; + } } } @@ -928,10 +931,12 @@ EvoConvert.processNode = function(node, normalDivWidth, quoteLevel) str = EvoConvert.formatParagraph(EvoConvert.extractElemText(node, normalDivWidth, quoteLevel), ltr, align, indent, "pre", -1, 0, "", quoteLevel); } else if (node.tagName == "BR") { // ignore new-lines added by wrapping, treat them as spaces - if (node.classList.contains("-x-evo-wrap-br")) - str += " "; - else + if (node.classList.contains("-x-evo-wrap-br")) { + if (node.hasAttribute("x-evo-is-space")) + 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 67245f71a5..706da2739c 100644 --- a/data/webkit/e-editor.js +++ b/data/webkit/e-editor.js @@ -1846,9 +1846,10 @@ EvoEditor.quoteParagraphWrap = function(node, lineLength, wrapWidth, prefixHtml) node = next; // add the prefix and <br> only if there's still anything to be quoted - if (node.nodeValue.length) { + if (node.nodeValue.length > 0 || ii + 1 < words.length) { var br = document.createElement("BR"); br.className = "-x-evo-wrap-br"; + br.setAttribute("x-evo-is-space", "1"); node.parentElement.insertBefore(br, node); @@ -1904,6 +1905,8 @@ EvoEditor.quoteParagraph = function(paragraph, blockquoteLevel, wrapWidth) } else if (node.nodeType == node.ELEMENT_NODE) { if (node.tagName == "BR") { if (node.classList.contains("-x-evo-wrap-br")) { + if (node.hasAttribute("x-evo-is-space")) + node.insertAdjacentText("beforebegin", " "); node.remove(); } else { if (node.parentElement.childNodes.length != 1) @@ -2231,7 +2234,9 @@ EvoEditor.removeQuoteMarks = function(element) for (ii = list.length - 1; ii >= 0; ii--) { var node = list[ii]; - node.insertAdjacentText("beforebegin", " "); + if (node.hasAttribute("x-evo-is-space")) + node.insertAdjacentText("beforebegin", " "); + node.remove(); } diff --git a/data/webkit/e-selection.js b/data/webkit/e-selection.js index 1036c67874..f8fad24f22 100644 --- a/data/webkit/e-selection.js +++ b/data/webkit/e-selection.js @@ -23,6 +23,12 @@ var EvoSelection = { }; +EvoSelection.isQuotationElement = function(node) +{ + return (node.tagName == "SPAN" && node.classList.contains("-x-evo-quoted")) || + (node.tagName == "BR" && node.classList.contains("-x-evo-wrap-br")); +} + /* The node path is described as an array of child indexes between parent and the childNode (in this order). */ EvoSelection.GetChildPath = function(parent, childNode) @@ -41,7 +47,9 @@ EvoSelection.GetChildPath = function(parent, childNode) var child, index = 0; for (child = node.previousElementSibling; child; child = child.previousElementSibling) { - index++; + // Skip quotation elements, because they can be added/removed after quotation edit + if (!EvoSelection.isQuotationElement(child)) + index++; } array[array.length] = index; @@ -59,16 +67,35 @@ EvoSelection.FindElementByPath = function(parent, path) return null; } - var ii, child = parent; + var ii, child = parent, node; for (ii = 0; ii < path.length; ii++) { - var idx = path[ii]; + var idx = path[ii], adept = child; + + for (node = child.firstElementChild; node && idx >= 0; node = node.nextElementSibling) { + if (!EvoSelection.isQuotationElement(node)) { + idx--; + adept = node; + } + } - if (idx < 0 || idx >= child.children.length) { - throw "EvoSelection.FindElementByPath:: Index '" + idx + "' out of range '" + child.children.length + "'"; + if (idx > 0) { + throw "EvoSelection.FindElementByPath:: Index '" + path[ii] + "' out of range '" + child.children.length + "'"; } - child = child.children.item(idx); + child = adept; + } + + if (child && child.tagName == "SPAN" && child.classList.contains("-x-evo-quote-character")) { + child = child.parentElement; + } + + if (child && child.tagName == "SPAN" && child.classList.contains("-x-evo-quoted")) { + if (child.nextSibling) { + child = child.nextSibling; + } else if (child.previousSibling) { + child = child.previousSibling; + } } return child; @@ -87,6 +114,8 @@ EvoSelection.GetOverallTextOffset = function(node) for (sibling = node.previousSibling; sibling; sibling = sibling.previousSibling) { if (sibling.nodeType == sibling.TEXT_NODE) { text_offset += sibling.textContent.length; + } else if (sibling.tagName == "BR" && sibling.classList.contains("-x-evo-wrap-br") && sibling.hasAttribute("x-evo-is-space")) { + text_offset++; } } @@ -113,12 +142,46 @@ EvoSelection.GetTextOffsetNode = function(element, textOffset) } else { break; } + } else if (node.tagName == "BR" && node.classList.contains("-x-evo-wrap-br") && node.hasAttribute("x-evo-is-space")) { + textOffset--; } } return node ? node : (adept ? adept : element); } +EvoSelection.correctSelectedNode = function(fromNode, fromOffset) +{ + var node, nodeData = {}; + + nodeData.node = fromNode; + nodeData.offset = fromOffset; + + if (!fromNode) + return nodeData; + + node = fromNode; + + if (node.nodeType == node.TEXT_NODE) + node = node.parentElement; + + while (node && node.tagName == "SPAN" && node.classList.contains("-x-evo-quote-character")) { + node = node.parentElement; + } + + if (node && node.tagName == "SPAN" && node.classList.contains("-x-evo-quoted")) { + if (node.nextSibling) { + nodeData.node = node.nextSibling; + nodeData.offset = 0; + } else if (node.previousSibling) { + nodeData.node = node.previousSibling; + nodeData.offset = nodeData.node.nodeValue.length; + } + } + + return nodeData; +} + /* Returns an object, where the current selection in the doc is stored */ EvoSelection.Store = function(doc) { @@ -127,19 +190,30 @@ EvoSelection.Store = function(doc) } var selection = {}, sel = doc.getSelection(); + var anchorNode, anchorOffset, nodeData; - selection.anchorElem = sel.anchorNode ? EvoSelection.GetChildPath(doc.body, sel.anchorNode) : []; - selection.anchorOffset = sel.anchorOffset + EvoSelection.GetOverallTextOffset(sel.anchorNode); + nodeData = EvoSelection.correctSelectedNode(sel.anchorNode, sel.anchorOffset); + anchorNode = nodeData.node; + anchorOffset = nodeData.offset; - if (sel.anchorNode && sel.anchorNode.nodeType == sel.anchorNode.ELEMENT_NODE) { + selection.anchorElem = anchorNode ? EvoSelection.GetChildPath(doc.body, anchorNode) : []; + selection.anchorOffset = anchorOffset + EvoSelection.GetOverallTextOffset(anchorNode); + + if (anchorNode && anchorNode.nodeType == anchorNode.ELEMENT_NODE) { selection.anchorIsElement = true; } if (!sel.isCollapsed) { - selection.focusElem = EvoSelection.GetChildPath(doc.body, sel.focusNode); - selection.focusOffset = sel.focusOffset + EvoSelection.GetOverallTextOffset(sel.focusNode); + var focusNode, focusOffset; + + nodeData = EvoSelection.correctSelectedNode(sel.focusNode, sel.focusOffset); + focusNode = nodeData.node; + focusOffset = nodeData.offset; + + selection.focusElem = EvoSelection.GetChildPath(doc.body, focusNode); + selection.focusOffset = focusOffset + EvoSelection.GetOverallTextOffset(focusNode); - if (sel.focusNode && sel.focusNode.nodeType == sel.focusNode.ELEMENT_NODE) { + if (focusNode && focusNode.nodeType == focusNode.ELEMENT_NODE) { selection.focusIsElement = true; } } diff --git a/src/e-util/test-html-editor-units-bugs.c b/src/e-util/test-html-editor-units-bugs.c index 377405094a..c75b1fb6cb 100644 --- a/src/e-util/test-html-editor-units-bugs.c +++ b/src/e-util/test-html-editor-units-bugs.c @@ -1225,39 +1225,39 @@ 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\">" - "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxxx xx xxxxxxxxx xx xxxxxxx xx xxxxx xxxx xxxx xx xxx xxx xxxx xxx" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "xxxçx xôxé \"xxxxx xxxx xxxxxxx xxx\" xx xxxx xxxxé xxx xxx xxxéx xxx" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "x'x xéxxxxé x'xxxxxxxxx xx xxx \"Xxxx XXX Xxxxxx Xxx\". Xx xxxx" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "xxxxxxxx xxx xxxxxxxxxxxxxxxx.xx (xxxxxxx xxxxxxxxxx xx .xxx). Xxxx" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "êxxx xxx xxxxxxxxxxx xxxéxxxxxxxx, xxxx xxxxx xx XXX xx xéxxx à xx" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "xxx \"xxx xxxxxx xxxx xx xxxxxxx\" xx xxxx xx xxxxx xxxxxxxx xxxxxxxx" WRAP_BR + "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxxx xx xxxxxxxxx xx xxxxxxx xx xxxxx xxxx xxxx xx xxx xxx xxxx xxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "xxxçx xôxé \"xxxxx xxxx xxxxxxx xxx\" xx xxxx xxxxé xxx xxx xxxéx xxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "x'x xéxxxxé x'xxxxxxxxx xx xxx \"Xxxx XXX Xxxxxx Xxx\". Xx xxxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "xxxxxxxx xxx xxxxxxxxxxxxxxxx.xx (xxxxxxx xxxxxxxxxx xx .xxx). Xxxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "êxxx xxx xxxxxxxxxxx xxxéxxxxxxxx, xxxx xxxxx xx XXX xx xéxxx à xx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "xxx \"xxx xxxxxx xxxx xx xxxxxxx\" xx xxxx xx xxxxx xxxxxxxx xxxxxxxx" WRAP_BR_SPC 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" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "xxxxé:" WRAP_BR + "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxx xx xéxxxxxxx, xxxxxxxx xxxxxxx (!), xxxxxxx à xxx, xxxx ooo$ XXX" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "xxxxé:" WRAP_BR_SPC 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>" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "xx xx xxxx xéxéxxxxxxx x'xxxxxx xxxx xx xxxxxx xx xxxxxxxxxxxx xx xxx" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "(xxxxx Xxxxxx) xxxx xxxx x'xxxxxxx xx xxxxxx:" WRAP_BR + "xxxxxxxxxxxxxxxx.xx/xxxxxxx/xxxxx-xxxx-xxxxxxxx-xxxxx-xxxx-xxx-xxxxxxxx-xxx/</a>" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "xx xx xxxx xéxéxxxxxxx x'xxxxxx xxxx xx xxxxxx xx xxxxxxxxxxxx xx xxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "(xxxxx Xxxxxx) xxxx xxxx x'xxxxxxx xx xxxxxx:" WRAP_BR_SPC 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>" 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" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "oooxooo xxxxx xxxxx xxxx... xxxx x'xxx xxxxxxxxxxxx xxxxx xxx" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "xxxxxxxx xx \"xx xxxxx xxx xxx xxxxxxx xxxxxxx xxxxxxxxxxxxxx xxxx" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "xxxxx xxxxxx xx xx xxxx xx x'xxxxxx\". Xx xxxx-êxxx xxx xx xxxxxxxx xx" WRAP_BR + "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxx xxx xxx xxxxxxx xxxxxxxéxx x'xxxêxxxx à xxxxx, xxx xx xxxxé xx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "oooxooo xxxxx xxxxx xxxx... xxxx x'xxx xxxxxxxxxxxx xxxxx xxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "xxxxxxxx xx \"xx xxxxx xxx xxx xxxxxxx xxxxxxx xxxxxxxxxxxxxx xxxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "xxxxx xxxxxx xx xx xxxx xx x'xxxxxx\". Xx xxxx-êxxx xxx xx xxxxxxxx xx" WRAP_BR_SPC 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" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "xxxxxxxxxxxxxxxx à xx xxx x'xx xx xêxx (éxxxxxxxxx xxxx-xx-xxxxxxxx):" WRAP_BR + "<div>" QUOTE_SPAN (QUOTE_CHR) "Xxxxx xxxxxx'xx xxx x xxxx xxxxxxx xxxxx xx xxèx xxxxxxxxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "xxxxxxxxxxxxxxxx à xx xxx x'xx xx xêxx (éxxxxxxxxx xxxx-xx-xxxxxxxx):" WRAP_BR_SPC 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>" WRAP_BR + "xxxxxxxxxx.xxx/xx-xxxxxxx/xxxxxxx/Xxxxx-xxxx-xxx-xxxxxxxxxx-xxxxx.xxx</a>" WRAP_BR_SPC QUOTE_SPAN (QUOTE_CHR) "; </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" WRAP_BR - QUOTE_SPAN (QUOTE_CHR) "x'xxxxxxxxxxx xxxxxx, xxxx" WRAP_BR + "<div>" QUOTE_SPAN (QUOTE_CHR) "...x'x xxxxx xx xxxxxx x'xxxxxx xéxxxxxxx, xx xxx xxxx xxxxxx" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "x'xxxxxxxxxxx xxxxxx, xxxx" WRAP_BR_SPC 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" WRAP_BR + "https://xxxxxxxxxxxxxxxx.xxx/xxxxxxxx-xxxxxxx-xxxx-xxx-o/</a> xxxxx xxx" WRAP_BR_SPC 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" @@ -2140,7 +2140,7 @@ test_issue_1330 (TestFixture *fixture) "<div>" QUOTE_SPAN (QUOTE_CHR) "123 567 90</div>" "<div>" QUOTE_SPAN (QUOTE_CHR) "2345678901</div>" "<div>" QUOTE_SPAN (QUOTE_CHR) "34 67 9012</div>" - "<div>" QUOTE_SPAN (QUOTE_CHR) "45678 0 2" WRAP_BR + "<div>" QUOTE_SPAN (QUOTE_CHR) "45678 0 2" WRAP_BR_SPC QUOTE_SPAN (QUOTE_CHR) "4 6 8 0</div>" "</blockquote>" HTML_SUFFIX, @@ -2243,7 +2243,7 @@ test_issue_1365 (TestFixture *fixture) "<div>" QUOTE_SPAN (QUOTE_CHR) "cc dd. ee ff.</div>" "<div>" QUOTE_SPAN (QUOTE_CHR) "<br></div>" "<div>" QUOTE_SPAN (QUOTE_CHR) "xxxx:</div>" - "<div>" QUOTE_SPAN (QUOTE_CHR) "123456789 1234 6789 123<br class=\"-x-evo-wrap-br\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "123456789 1234 6789 123" WRAP_BR_SPC QUOTE_SPAN (QUOTE_CHR) "56 89.</div>" "<div>" QUOTE_SPAN (QUOTE_CHR) "<br></div>" "<div>" QUOTE_SPAN (QUOTE_CHR) "yyy:</div>" @@ -2251,8 +2251,8 @@ test_issue_1365 (TestFixture *fixture) "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "zz yy,</div>" "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "<br></div>" "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "xxx,</div>" - "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "www 123456789 12 456<br class=\"-x-evo-wrap-br\">" - QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "89 123 567 9 12 456<br class=\"-x-evo-wrap-br\">" + "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "www 123456789 12 456" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "89 123 567 9 12 456" WRAP_BR_SPC QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "89.</div>" "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "<br></div>" "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR) "vv,</div>" @@ -2261,8 +2261,8 @@ test_issue_1365 (TestFixture *fixture) "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "ZZ YY,</div>" "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "<br></div>" "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "XXX,</div>" - "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "WWW 987654321 98<br class=\"-x-evo-wrap-br\">" - QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "654 21 987 543 1 98<br class=\"-x-evo-wrap-br\">" + "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "WWW 987654321 98" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "654 21 987 543 1 98" WRAP_BR_SPC QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "654 21.</div>" "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "<br></div>" "<div>" QUOTE_SPAN (QUOTE_CHR QUOTE_CHR QUOTE_CHR) "VV,</div>" @@ -2690,6 +2690,99 @@ test_issue_1439 (TestFixture *fixture) g_test_fail (); } +static void +test_issue_1392 (TestFixture *fixture) +{ + test_utils_fixture_change_setting_int32 (fixture, "org.gnome.evolution.mail", "composer-word-wrap-length", 28); + + if (!test_utils_process_commands (fixture, + "mode:plain\n")) { + g_test_fail (); + return; + } + + test_utils_insert_content (fixture, + "<body><div>aaaa <a href=\"https://www.example.com/\">www.example.com/aaabbbccc</a> bbbb</div>" + "<div>ccc</div>" + "<body><div>dddd <a href=\"https://www.example.com/\">www.example.com/eeefffggg</a> hhh</div>" + "<div>iii</div>" + "<span class=\"-x-evo-to-body\" data-credits=\"Credits:\"></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, + "seq:ddelbbbblbb\n" + "type:1\n", + HTML_PREFIX "<div style=\"width: 28ch;\">Credits:</div>" + "<blockquote type=\"cite\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "aaaa <a href=\"https://www.example.com/aaabbbccc\">www.example.com/a1bc</a>" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "bbbb</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "ccc</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "dddd" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "<a href=\"https://www.example.com/eeefffggg\">www.example.com/eeefffggg</a>" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "hhh</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "iii</div>" + "</blockquote>" + HTML_SUFFIX, + "Credits:\n" + "> aaaa www.example.com/a1bc\n" + "> bbbb\n" + "> ccc\n" + "> dddd\n" + "> www.example.com/eeefffggg\n" + "> hhh\n" + "> iii\n")) { + g_test_fail (); + return; + } + + if (!test_utils_run_simple_test (fixture, + "seq:hddddbdelbbbblbb\n" + "type:2\n", + HTML_PREFIX "<div style=\"width: 28ch;\">Credits:</div>" + "<blockquote type=\"cite\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "aaaa <a href=\"https://www.example.com/aaabbbccc\">www.example.com/a1bc</a>" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "bbbb</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "ccc</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "dddd<a href=\"https://www.example.com/eeefffggg\">www.example.com/e2fg</a>" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "hhh</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "iii</div>" + "</blockquote>" + HTML_SUFFIX, + "Credits:\n" + "> aaaa www.example.com/a1bc\n" + "> bbbb\n" + "> ccc\n" + "> ddddwww.example.com/e2fg\n" + "> hhh\n" + "> iii\n")) { + g_test_fail (); + return; + } + + if (!test_utils_run_simple_test (fixture, + "seq:hr\n" + "type:333\n", + HTML_PREFIX "<div style=\"width: 28ch;\">Credits:</div>" + "<blockquote type=\"cite\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "aaaa <a href=\"https://www.example.com/aaabbbccc\">www.example.com/a1bc</a>" WRAP_BR_SPC + QUOTE_SPAN (QUOTE_CHR) "bbbb</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "ccc</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "d333ddd" WRAP_BR + QUOTE_SPAN (QUOTE_CHR) "<a href=\"https://www.example.com/eeefffggg\">www.example.com/e2fg</a> hhh</div>" + "<div>" QUOTE_SPAN (QUOTE_CHR) "iii</div>" + "</blockquote>" + HTML_SUFFIX, + "Credits:\n" + "> aaaa www.example.com/a1bc\n" + "> bbbb\n" + "> ccc\n" + "> d333ddd\n" + "> www.example.com/e2fg hhh\n" + "> iii\n")) + g_test_fail (); +} + void test_add_html_editor_bug_tests (void) { @@ -2737,4 +2830,5 @@ test_add_html_editor_bug_tests (void) test_utils_add_test ("/issue/1424-level1", test_issue_1424_level1); test_utils_add_test ("/issue/1424-level2", test_issue_1424_level2); test_utils_add_test ("/issue/1439", test_issue_1439); + test_utils_add_test ("/issue/1392", test_issue_1392); } diff --git a/src/e-util/test-html-editor-units-bugs.h b/src/e-util/test-html-editor-units-bugs.h index 9eda23a1d6..2857aae9c2 100644 --- a/src/e-util/test-html-editor-units-bugs.h +++ b/src/e-util/test-html-editor-units-bugs.h @@ -23,6 +23,7 @@ #define QUOTE_SPAN(x) "<span class='-x-evo-quoted'>" x "</span>" #define QUOTE_CHR "<span class='-x-evo-quote-character'>> </span>" #define WRAP_BR "<br class=\"-x-evo-wrap-br\">" +#define WRAP_BR_SPC "<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" G_BEGIN_DECLS diff --git a/src/e-util/test-html-editor-units.c b/src/e-util/test-html-editor-units.c index 551d7878e7..f8d553e9a8 100644 --- a/src/e-util/test-html-editor-units.c +++ b/src/e-util/test-html-editor-units.c @@ -5093,9 +5093,9 @@ test_cite_reply_link (TestFixture *fixture) "", HTML_PREFIX "<div style=\"width: 71ch;\">On Today, User wrote:</div>" "<blockquote type=\"cite\">" - "<div>" QUOTE_SPAN (QUOTE_CHR) "123 (here<br class=\"-x-evo-wrap-br\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "123 (here" WRAP_BR_SPC QUOTE_SPAN (QUOTE_CHR) "<a href=\"https://www.example.com/1234567890/1234567890/1234567890/1234567890/1234567890/\">" - "https://www.example.com/1234567890/1234567890/1234567890/1234567890/1234567890/</a>)<br class=\"-x-evo-wrap-br\">" + "https://www.example.com/1234567890/1234567890/1234567890/1234567890/1234567890/</a>)" WRAP_BR_SPC QUOTE_SPAN (QUOTE_CHR) "and here ěščřžýáíé <a href=\"https://www.example.com\">www.example.com</a> with closing text after.</div>" "<div>" QUOTE_SPAN (QUOTE_CHR) "<a href=\"https://www.example1.com\">www.example1.com</a></div>" "<div>" QUOTE_SPAN (QUOTE_CHR) "before <a href=\"https://www.example2.com\">www.example2.com</a></div>" diff --git a/src/e-util/test-web-view-jsc.c b/src/e-util/test-web-view-jsc.c index ba41c7c9d1..629d25dfb0 100644 --- a/src/e-util/test-web-view-jsc.c +++ b/src/e-util/test-web-view-jsc.c @@ -2563,32 +2563,32 @@ test_convert_to_plain (TestFixture *fixture) "before anchor\n" "text after\n", 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>"), + /* 60 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\"><a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">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>"), + /* 61 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\"><a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">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>"), + /* 62 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\"><a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">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>"), + /* 63 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\"><a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">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>"), + /* 64 */{ HTML ("<div>text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\"><a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">text after</div>"), "text before\n" "https://no.where/1234567890/123457890/1234567890\n" "text after\n", @@ -2900,8 +2900,8 @@ test_convert_to_plain_quoted (TestFixture *fixture) "> > text after\n", 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\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" + QUOTE_SPAN (QUOTE_CHR) "<a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" QUOTE_SPAN (QUOTE_CHR) "text after</div>" "</blockquote>"), "> text\n" @@ -2911,8 +2911,8 @@ test_convert_to_plain_quoted (TestFixture *fixture) "> 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\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" + QUOTE_SPAN (QUOTE_CHR) "<a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" QUOTE_SPAN (QUOTE_CHR) "text after</div>" "</blockquote>"), "> text\n" @@ -2922,8 +2922,8 @@ test_convert_to_plain_quoted (TestFixture *fixture) "> 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\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" + QUOTE_SPAN (QUOTE_CHR) "<a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" QUOTE_SPAN (QUOTE_CHR) "text after</div>" "</blockquote>"), "> text\n" @@ -2932,8 +2932,8 @@ test_convert_to_plain_quoted (TestFixture *fixture) "> 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\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" + QUOTE_SPAN (QUOTE_CHR) "<a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" QUOTE_SPAN (QUOTE_CHR) "text after</div>" "</blockquote>"), "> text before\n" @@ -2941,8 +2941,8 @@ test_convert_to_plain_quoted (TestFixture *fixture) "> 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\">" + "<div>" QUOTE_SPAN (QUOTE_CHR) "text before<br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" + QUOTE_SPAN (QUOTE_CHR) "<a href='https://no.where/'>https://no.where/1234567890/123457890/1234567890</a><br class=\"-x-evo-wrap-br\" x-evo-is-space=\"1\">" QUOTE_SPAN (QUOTE_CHR) "text after</div>" "</blockquote>"), "> text before\n" |