[evolution/wip/mcrha/webkit-jsc-api] Implement EvoEditor.InsertContent()



commit bc9d5b8bc16288b1289201c48aecfc6560df3bb4
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jan 28 18:58:15 2020 +0100

    Implement EvoEditor.InsertContent()

 data/webkit/e-editor.js                     | 162 +++++++++++++++++++++++++++-
 src/modules/webkit-editor/e-webkit-editor.c |   6 +-
 2 files changed, 163 insertions(+), 5 deletions(-)
---
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index 0b2a14bbc8..ba818deb57 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -3750,9 +3750,167 @@ EvoEditor.ConvertContent = function(preferredPlainText, startBottom, topSignatur
 {
 }
 
-// replaces current selection with the next plain text or HTML, quoted or normal DIV
-EvoEditor.PasteText = function(text, isHTML, quote)
+// replaces current selection with the plain text or HTML, quoted or normal DIV
+EvoEditor.InsertContent = function(text, isHTML, quote)
 {
+       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_GROUP, "InsertContent");
+       try {
+               if (!document.getSelection().isCollapsed) {
+                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "InsertContent::sel-remove", 
null, null,
+                               EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE | 
EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+                       try {
+                               document.getSelection().deleteFromDocument();
+                       } finally {
+                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
"InsertContent::sel-remove");
+                       }
+               }
+
+               var content = document.createElement(quote ? "BLOCKQUOTE" : "DIV");
+
+               if (quote) {
+                       content.setAttribute("type", "cite");
+               }
+
+               if (isHTML) {
+                       if (EvoEditor.mode == EvoEditor.MODE_HTML) {
+                               content.innerHTML = text;
+
+                               // paste can contain <meta> elements, like the one with Content-Type, which 
can be removed
+                               while (content.firstElementChild && content.firstElementChild.tagName == 
"META") {
+                                       content.removeChild(content.firstElementChild);
+                               }
+                       } else {
+                               content.innerText = text;
+                       }
+               } else {
+                       content.innerText = text;
+               }
+
+               if (quote) {
+                       var baseNode = document.getSelection().baseNode, intoBody = false;
+
+                       if (!content.firstElementChild || (content.firstElementChild.tagName != "DIV" && 
content.firstElementChild.tagName != "P" &&
+                           content.firstElementChild.tagName != "PRE")) {
+                               // enclose quoted text into DIV
+                               var node = document.createElement("DIV");
+
+                               while (content.firstChild) {
+                                       node.appendChild(content.firstChild);
+                               }
+
+                               content.appendChild(node);
+                       }
+
+                       if (baseNode) {
+                               var node, parentBlock = null;
+
+                               if (baseNode.nodeType == baseNode.ELEMENT_NODE) {
+                                       node = baseNode;
+                               } else {
+                                       node = baseNode.parentElement;
+                               }
+
+                               while (node && node.tagName != "BODY" && !EvoEditor.IsBlockNode(node)) {
+                                       parentBlock = node;
+
+                                       node = node.parentElement;
+                               }
+
+                               if (node && node.tagName != "BLOCKQUOTE")
+                                       parentBlock = node;
+                               else if (!parentBlock)
+                                       parentBlock = node;
+
+                               if (!parentBlock) {
+                                       intoBody = true;
+                               } else {
+                                       var willSplit = parentBlock.tagName == "DIV" || parentBlock.tagName 
== "P" || parentBlock.tagName == "PRE";
+
+                                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
"InsertContent::text", parentBlock, parentBlock,
+                                               (willSplit ? 
EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE : 0) | EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+                                       try {
+                                               if (willSplit) {
+                                                       // need to split the content up to the parent block 
node
+                                                       if (baseNode.nodeType == baseNode.TEXT_NODE) {
+                                                               
baseNode.splitText(document.getSelection().baseOffset);
+                                                       }
+
+                                                       var from = baseNode.nextSibling, parent, nextFrom = 
null;
+
+                                                       parent = from ? from.parentElement : 
baseNode.parentElement;
+
+                                                       if (!from && parent) {
+                                                               from = parent.nextElementSibling;
+                                                               nextFrom = from;
+                                                               parent = parent.parentElement;
+                                                       }
+
+                                                       while (parent && parent.tagName != "BODY") {
+                                                               nextFrom = null;
+
+                                                               if (from) {
+                                                                       var clone;
+
+                                                                       clone = 
from.parentElement.cloneNode(false);
+                                                                       
from.parentElement.parentElement.insertBefore(clone, from.parentElement.nextSibling);
+
+                                                                       nextFrom = clone;
+
+                                                                       while (from.nextSibling) {
+                                                                               
clone.appendChild(from.nextSibling);
+                                                                       }
+
+                                                                       clone.insertBefore(from, 
clone.firstChild);
+                                                               }
+
+                                                               if (parent === parentBlock.parentElement || 
parent.parentElement.tagName == "BLOCKQUOTE") {
+                                                                       break;
+                                                               }
+
+                                                               from = nextFrom;
+                                                               parent = parent.parentElement;
+                                                       }
+                                               }
+
+                                               parentBlock.insertAdjacentElement("afterend", content);
+
+                                               if (content.nextSibling)
+                                                       
document.getSelection().setPosition(content.nextSibling, 0);
+                                               else if (content.lastChild)
+                                                       
document.getSelection().setPosition(content.lastChild, 0);
+                                               else
+                                                       document.getSelection().setPosition(content, 0);
+
+                                               if (baseNode.nodeType == baseNode.ELEMENT_NODE && 
baseNode.parentElement &&
+                                                   (baseNode.tagName == "DIV" || baseNode.tagName == "P" || 
baseNode.tagName == "PRE") &&
+                                                   (!baseNode.children.length || (baseNode.children.length 
== 1 && baseNode.children[0].tagName == "BR"))) {
+                                                       baseNode.parentElement.removeChild(baseNode);
+                                               }
+                                       } finally {
+                                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
"InsertContent::text");
+                                       }
+                               }
+                       } else {
+                               intoBody = true;
+                       }
+
+                       if (intoBody) {
+                               EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
"InsertContent::text", document.body, document.body,
+                                       EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE | 
EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+                               try {
+                                       document.body.insertAdjacentElement("afterbegin", content);
+                               } finally {
+                                       EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, 
"InsertContent::text");
+                               }
+                       }
+               } else {
+                       EvoEditor.InsertHTML("InsertContent::text", content.outerHTML);
+               }
+       } finally {
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_GROUP, "InsertContent");
+               EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
+               EvoEditor.EmitContentChanged();
+       }
 }
 
 EvoEditor.wrapParagraph = function(paragraphNode, maxLetters, currentPar, usedLetters, wasNestedElem)
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index 350e6b3950..7505aa0b2d 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -2051,7 +2051,7 @@ webkit_editor_insert_content (EContentEditor *editor,
        if ((flags & E_CONTENT_EDITOR_INSERT_CONVERT) &&
            !(flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL)) {
                e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
-                       "EvoEditor.PasteText(%s, %x, %x);",
+                       "EvoEditor.InsertContent(%s, %x, %x);",
                        content, (flags & E_CONTENT_EDITOR_INSERT_TEXT_HTML) != 0, FALSE);
        } else if ((flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL) &&
                   (flags & E_CONTENT_EDITOR_INSERT_TEXT_HTML)) {
@@ -2088,12 +2088,12 @@ webkit_editor_insert_content (EContentEditor *editor,
                  !(flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL) &&
                  !(flags & E_CONTENT_EDITOR_INSERT_QUOTE_CONTENT)) {
                e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
-                       "EvoEditor.PasteText(%s, %x, %x);",
+                       "EvoEditor.InsertContent(%s, %x, %x);",
                        content, TRUE, FALSE);
        } else if ((flags & E_CONTENT_EDITOR_INSERT_QUOTE_CONTENT) &&
                   !(flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL)) {
                e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
-                       "EvoEditor.PasteText(%s, %x, %x);",
+                       "EvoEditor.InsertContent(%s, %x, %x);",
                        content, (flags & E_CONTENT_EDITOR_INSERT_TEXT_HTML) != 0, TRUE);
        } else if (!(flags & E_CONTENT_EDITOR_INSERT_CONVERT) &&
                   !(flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL)) {


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