[evolution/wip/mcrha/webkit-jsc-api] e-editor.js: Initial implementation of EvoEditor.quoteParagraph()
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/mcrha/webkit-jsc-api] e-editor.js: Initial implementation of EvoEditor.quoteParagraph()
- Date: Thu, 12 Mar 2020 17:27:36 +0000 (UTC)
commit 36e7e8db778cdddea9a2cac85ba87cdb8d9445c3
Author: Milan Crha <mcrha redhat com>
Date: Thu Mar 12 18:29:50 2020 +0100
e-editor.js: Initial implementation of EvoEditor.quoteParagraph()
data/webkit/e-editor.js | 241 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 209 insertions(+), 32 deletions(-)
---
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index aca321980d..9ddfea1d37 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -1689,7 +1689,143 @@ EvoEditor.initializeContent = function()
}
}
-EvoEditor.convertParagraphs = function(parent, wrapWidth)
+EvoEditor.getNextNodeInHierarchy = function(node, upToNode)
+{
+ if (!node)
+ return null;
+
+ var next;
+
+ next = node.firstChild;
+
+ if (!next)
+ next = node.nextSibling;
+
+ if (!next) {
+ next = node.parentElement;
+
+ if (next === document.body || next === upToNode)
+ next = null;
+
+ while (next) {
+ if (next.nextSibling) {
+ next = next.nextSibling;
+ break;
+ } else {
+ next = next.parentElement;
+
+ if (next === document.body || next === upToNode)
+ next = null;
+ }
+ }
+ }
+
+ return next;
+}
+
+// it already knows the line is too long; the node is where the text length exceeded
+EvoEditor.quoteParagraphWrap = function(node, lineLength, wrapWidth, prefixHtml)
+{
+ if (node.nodeType == node.ELEMENT_NODE) {
+ var br = document.createElement("BR");
+ br.className = "-x-evo-wrap-br";
+
+ node.insertAdjacentElement("beforebegin", br);
+ node.insertAdjacentHTML("beforebegin", prefixHtml);
+
+ return node.innerText.length;
+ }
+
+ var words = node.nodeValue.split(" "), ii, offset = 0, inc;
+
+ for (ii = 0; ii < words.length; ii++) {
+ var word = words[ii], wordLen = word.length;
+
+ if (lineLength + wordLen > wrapWidth) {
+ node.splitText(offset - 1);
+ node = node.nextSibling;
+
+ // erase the space at the end of the line
+ node.splitText(1);
+ var next = node.nextSibling;
+ node.parentElement.removeChild(node);
+ node = next;
+
+ var br = document.createElement("BR");
+ br.className = "-x-evo-wrap-br";
+
+ node.parentElement.insertBefore(br, node);
+ br.insertAdjacentHTML("afterend", prefixHtml);
+
+ offset = 0;
+ lineLength = 0;
+ }
+
+ inc = wordLen + (ii + 1 < words.length ? 1 : 0);
+
+ lineLength += inc;
+ offset += inc;
+ }
+
+ return lineLength;
+}
+
+EvoEditor.getBlockquotePrefixHtml = function(blockquoteLevel)
+{
+ var prefixHtml;
+
+ prefixHtml = "<span class='-x-evo-quote-character'>> </span>".repeat(blockquoteLevel);
+ prefixHtml = "<span class='-x-evo-quoted'>" + prefixHtml + "</span>";
+
+ return prefixHtml;
+}
+
+EvoEditor.quoteParagraph = function(paragraph, blockquoteLevel, wrapWidth)
+{
+ if (!paragraph || !(blockquoteLevel > 0))
+ return;
+
+ var node = paragraph.firstChild, next, lineLength = 0;
+ var prefixHtml = EvoEditor.getBlockquotePrefixHtml(blockquoteLevel);
+
+ while (node) {
+ next = EvoEditor.getNextNodeInHierarchy(node, paragraph);
+
+ if (node.nodeType == node.TEXT_NODE) {
+ if (wrapWidth > 0 && lineLength + node.nodeValue.length > wrapWidth) {
+ lineLength = EvoEditor.quoteParagraphWrap(node, lineLength, wrapWidth,
prefixHtml);
+ } else {
+ lineLength += node.nodeValue.length;
+ }
+ } else if (node.nodeType == node.ELEMENT_NODE) {
+ if (node.tagName == "BR") {
+ if (node.classList.contains("-x-evo-wrap-br")) {
+ node.parentElement.removeChild(node);
+ } else {
+ node.insertAdjacentHTML("afterend", prefixHtml);
+ lineLength = 0;
+ }
+ } else if (node.tagName == "A") {
+ var len = node.innerText.length;
+
+ if (wrapWidth > 0 && lineLength + len > wrapWidth && (!next || next.tagName
!= "BR")) {
+ lineLength = EvoEditor.quoteParagraphWrap(node, lineLength,
wrapWidth, prefixHtml);
+ } else {
+ lineLength += len;
+ }
+
+ // do not traverse into the anchor element
+ next = node.nextSibling;
+ }
+ }
+
+ node = next;
+ }
+
+ paragraph.insertAdjacentHTML("afterbegin", prefixHtml);
+}
+
+EvoEditor.convertParagraphs = function(parent, wrapWidth, blockquoteLevel)
{
if (!parent)
return;
@@ -1700,21 +1836,48 @@ EvoEditor.convertParagraphs = function(parent, wrapWidth)
var child = parent.children.item(ii);
if (child.tagName == "DIV") {
- if (wrapWidth == -1) {
+ if (wrapWidth == -1 || (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT &&
blockquoteLevel > 0)) {
child.style.width = "";
EvoEditor.removeEmptyStyleAttribute(child);
+
+ if (wrapWidth == -1)
+ child.removeAttribute("x-evo-width");
+ else
+ child.setAttribute("x-evo-width", wrapWidth);
} else {
child.style.width = wrapWidth + "ch";
+ child.removeAttribute("x-evo-width");
+ }
+
+ if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT && blockquoteLevel > 0)
+ EvoEditor.quoteParagraph(child, blockquoteLevel, wrapWidth);
+ } else if (child.tagName == "PRE") {
+ if (EvoEditor.mode == EvoEditor.MODE_PLAIN_TEXT && blockquoteLevel > 0) {
+ var prefixHtml = EvoEditor.getBlockquotePrefixHtml(blockquoteLevel);
+ var lines = child.innerText.split("\n"), ii, text = "";
+
+ for (ii = 0; ii < lines.length; ii++) {
+ text += prefixHtml + lines[ii].replace(/\&/g, "&").replace(/</g,
"<").replace(/>/g, ">");
+ if (ii + 1 < lines.length)
+ text += "\n";
+ }
+
+ if (!lines.length)
+ text += prefixHtml;
+
+ child.innerHTML = text;
}
} else if (child.tagName == "BLOCKQUOTE") {
var innerWrapWidth = wrapWidth;
- innerWrapWidth -= 2; // length of "> "
+ if (innerWrapWidth > 0) {
+ innerWrapWidth -= 2; // length of "> "
- if (innerWrapWidth < EvoConvert.MIN_PARAGRAPH_WIDTH)
- innerWrapWidth = EvoConvert.MIN_PARAGRAPH_WIDTH;
+ if (innerWrapWidth < EvoConvert.MIN_PARAGRAPH_WIDTH)
+ innerWrapWidth = EvoConvert.MIN_PARAGRAPH_WIDTH;
+ }
- EvoEditor.convertParagraphs(child, innerWrapWidth);
+ EvoEditor.convertParagraphs(child, innerWrapWidth, blockquoteLevel + 1);
} else if (child.tagName == "UL") {
if (wrapWidth == -1) {
child.style.width = "";
@@ -1760,7 +1923,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);
+ EvoEditor.convertParagraphs(document.body, EvoEditor.NORMAL_PARAGRAPH_WIDTH, 0);
}
}
@@ -1790,8 +1953,10 @@ EvoEditor.convertTags = function()
img.outerText = EvoConvert.ImgToText(img);
}
- for (ii = document.anchors.length - 1; ii >= 0; ii--) {
- var anchor = document.anchors[ii];
+ list = document.getElementsByTagName("A");
+
+ for (ii = list.length - 1; ii >= 0; ii--) {
+ var anchor = list[ii];
EvoEditor.moveNodeContent(anchor);
@@ -1834,34 +1999,44 @@ EvoEditor.convertTags = function()
}
}
- next = node.firstChild;
+ next = EvoEditor.getNextNodeInHierarchy(node, document.body);
- if (!next)
- next = node.nextSibling;
+ if (removeNode)
+ node.parentElement.removeChild(node);
+
+ node = next;
+ }
- if (!next) {
- next = node.parentElement;
+ document.body.normalize();
+}
- if (next === document.body)
- next = null;
+EvoEditor.removeQuoteMarks = function()
+{
+ var ii, list;
- while (next) {
- if (next.nextSibling) {
- next = next.nextSibling;
- break;
- } else {
- next = next.parentElement;
+ list = document.querySelectorAll("span.-x-evo-quoted");
- if (next === document.body)
- next = null;
- }
- }
- }
+ for (ii = list.length - 1; ii >= 0; ii--) {
+ var node = list[ii];
- if (removeNode)
- node.parentElement.removeChild(node);
+ node.parentElement.removeChild(node);
+ }
- node = next;
+ list = document.querySelectorAll("br.-x-evo-wrap-br");
+
+ for (ii = list.length - 1; ii >= 0; ii--) {
+ var node = list[ii];
+
+ node.insertAdjacentText("beforebegin", " ");
+ node.parentElement.removeChild(node);
+ }
+
+ list = document.querySelectorAll("div[x-evo-width]");
+
+ for (ii = list.length - 1; ii >= 0; ii--) {
+ var node = list[ii];
+
+ node.removeAttribute("x-evo-width");
}
document.body.normalize();
@@ -1890,11 +2065,13 @@ EvoEditor.SetMode = function(mode)
try {
EvoEditor.mode = mode;
+ EvoEditor.removeQuoteMarks();
+
if (mode == EvoEditor.MODE_PLAIN_TEXT) {
EvoEditor.convertTags();
- EvoEditor.convertParagraphs(document.body, EvoEditor.NORMAL_PARAGRAPH_WIDTH);
+ EvoEditor.convertParagraphs(document.body, EvoEditor.NORMAL_PARAGRAPH_WIDTH,
0);
} else {
- EvoEditor.convertParagraphs(document.body, -1);
+ EvoEditor.convertParagraphs(document.body, -1, 0);
}
} finally {
EvoUndoRedo.Enable();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]