[evolution/wip/mcrha/webkit-jsc-api] Pre-code EvoEditor.InsertSignature() and (finish) EvoEditor.ReplaceSelection()
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/mcrha/webkit-jsc-api] Pre-code EvoEditor.InsertSignature() and (finish) EvoEditor.ReplaceSelection()
- Date: Mon, 20 Jan 2020 14:52:40 +0000 (UTC)
commit 564ad2c1e6454e39ef18433ce6323d9415f2219e
Author: Milan Crha <mcrha redhat com>
Date: Mon Jan 20 15:54:16 2020 +0100
Pre-code EvoEditor.InsertSignature() and (finish) EvoEditor.ReplaceSelection()
data/webkit/e-editor.js | 227 +++++++++++++++++++++++++++-
src/modules/webkit-editor/e-webkit-editor.c | 55 ++-----
2 files changed, 235 insertions(+), 47 deletions(-)
---
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index 225d8d8b07..79fc9819dd 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -3351,19 +3351,23 @@ EvoEditor.GetCaretWord = function()
return range.toString();
}
-EvoEditor.ReplaceCaretWord = function(replacement)
+EvoEditor.replaceSelectionWord = function(opType, expandWord, replacement)
{
+ if (!expandWord && document.getSelection().isCollapsed)
+ return;
+
if (document.getSelection().rangeCount < 1)
- return null;
+ return;
var range = document.getSelection().getRangeAt(0);
if (!range)
- return null;
+ return;
- range.expand("word");
+ if (expandWord)
+ range.expand("word");
- EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_EVENT, "ReplaceCaretWord", null, null,
EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE | EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+ EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_EVENT, opType, null, null,
EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE | EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
try {
var fragment = range.extractContents(), node;
@@ -3375,7 +3379,7 @@ EvoEditor.ReplaceCaretWord = function(replacement)
;
}
- if (node && node.nodeType == node.TEXT_NODE) {
+ if (node && node.nodeType == node.TEXT_NODE && replacement) {
var text;
/* Replace the word */
@@ -3387,12 +3391,22 @@ EvoEditor.ReplaceCaretWord = function(replacement)
document.getSelection().modify("move", "forward", "word");
}
} finally {
- EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_EVENT, "ReplaceCaretWord");
+ EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_EVENT, opType);
EvoEditor.maybeUpdateFormattingState(EvoEditor.FORCE_MAYBE);
EvoEditor.EmitContentChanged();
}
}
+EvoEditor.ReplaceCaretWord = function(replacement)
+{
+ EvoEditor.replaceSelectionWord("ReplaceCaretWord", true, replacement);
+}
+
+EvoEditor.ReplaceSelection = function(replacement)
+{
+ EvoEditor.replaceSelectionWord("ReplaceSelection", false, replacement);
+}
+
EvoEditor.SpellCheckContinue = function(fromCaret, directionNext)
{
var selection, storedSelection = null;
@@ -3505,8 +3519,205 @@ EvoEditor.GetCurrentSignatureUid = function()
return "";
}
-EvoEditor.InsertSignature = function(content, is_html, uid, fromMessage, checkChanged, ignoreNextChange,
startBottom, topSignature, addDelimiter)
+EvoEditor.InsertSignature = function(content, isHTML, uid, fromMessage, checkChanged, ignoreNextChange,
startBottom, topSignature, addDelimiter)
{
+ var sigSpan, node;
+
+ sigSpan = document.createElement("SPAN");
+ sigSpan.className = "-x-evo-signature";
+ sigSpan.id = uid;
+
+ if (content) {
+ if (isHTML && EvoEditor.mode != EvoEditor.MODE_HTML) {
+ node = document.createElement("SPAN");
+ node.innerHTML = content;
+
+ content = EvoConvert.ToPlainText(node, EvoEditor.NORMAL_PARAGRAPH_WIDTH);
+ if (content != "") {
+ content = "<PRE>" + content.replace(/\&/g, "&").replace(/</g,
"<").replace(/>/g, ">") + "</PRE>";
+ }
+
+ isHTML = false;
+ }
+
+ /* The signature dash convention ("-- \n") is specified
+ * in the "Son of RFC 1036", section 4.3.2.
+ * http://www.chemie.fu-berlin.de/outerspace/netnews/son-of-1036.html
+ */
+ if (addDelimiter) {
+ var found;
+
+ if (isHTML) {
+ found = content.substr(0, 8).toUpperCase().startsWith("-- <BR>") ||
content.match(/\n-- <BR>/i) != null;
+ } else {
+ found = content.startsWith("-- \n") || content.match(/\n-- \n/i) != null;
+ }
+
+ /* Skip the delimiter if the signature already has one. */
+ if (!found) {
+ /* Always use the HTML delimiter as we are never in anything
+ * like a strict plain text mode. */
+ node = document.createElement("PRE");
+ node.innerHTML = "-- <BR>";
+ sigSpan.appendChild(node);
+ }
+ }
+
+ sigSpan.insertAdjacentHTML("beforeend", content);
+
+ node = sigSpan.querySelector("[data-evo-signature-plain-text-mode]");
+ if (node)
+ node.removeAttribute("[data-evo-signature-plain-text-mode]");
+
+ node = sigSpan.querySelector("#-x-evo-selection-start-marker");
+ if (node && node.parentElement)
+ node.parentElement.removeChild(node);
+
+ node = sigSpan.querySelector("#-x-evo-selection-end-marker");
+ if (node && node.parentElement)
+ node.parentElement.removeChild(node);
+ }
+
+ EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_GROUP, "InsertSignature");
+ try {
+ var signatures, ii, done = false, useWrapper = null;
+
+ signatures = document.getElementsByClassName("-x-evo-signature-wrapper");
+ for (ii = signatures.length; ii-- && !done;) {
+ var wrapper, signature;
+
+ wrapper = signatures[ii];
+ signature = wrapper.firstElementChild;
+
+ /* When we are editing a message with signature, we need to unset the
+ * active signature id as if the signature in the message was edited
+ * by the user we would discard these changes. */
+ if (fromMessage && content && signature) {
+ if (checkChanged) {
+ /* Normalize the signature that we want to insert as the one in the
+ * message already is normalized. */
+ webkit_dom_node_normalize (WEBKIT_DOM_NODE (signature_to_insert));
+ if (!webkit_dom_node_is_equal_node (WEBKIT_DOM_NODE
(signature_to_insert), signature)) {
+ /* Signature in the body is different than the one with the
+ * same id, so set the active signature to None and leave
+ * the signature that is in the body. */
+ uid = "none";
+ ignoreNextChange = true;
+ }
+
+ checkChanged = false;
+ fromMessage = false;
+ } else {
+ /* Old messages will have the signature id in the name attribute,
correct it. */
+ if (signature.hasAttribute("name")) {
+ id = signature.getAttribute("name");
+ signature.id = id;
+ signature.removeAttribute(name);
+ } else {
+ id = signature.id;
+ }
+
+ /* Keep the signature and check if is it the same
+ * as the signature in body or the user previously
+ * changed it. */
+ checkChanged = true;
+ }
+
+ done = true;
+ } else {
+ EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM,
"InsertSignature::old-changes", wrapper, wrapper,
+ EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML |
EvoEditor.CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE);
+ try {
+ /* If the top signature was set we have to remove the newline
+ * that was inserted after it */
+ if (topSignature) {
+ node = document.querySelector(".-x-evo-top-signature-spacer");
+ if (node && (!node.firstChild || !node.textContent ||
+ (node.childNodes.length == 1 && node.firstChild.tagName
== "BR"))) {
+ if (node.parentElement)
+ node.parentElement.removeChild(node);
+ }
+ }
+
+ /* Leave just one signature wrapper there as it will be reused. */
+ if (ii) {
+ if (wrapper.parentElement)
+ wrapper.parentElement.removeChild(wrapper);
+ } else {
+ wrapper.removeChild(signature);
+ useWrapper = wrapper;
+ }
+ } finally {
+ EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM,
"InsertSignature::old-changes");
+ }
+ }
+ }
+
+ if (!done) {
+ if (useWrapper) {
+ EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM,
"InsertSignature::new-changes", useWrapper, useWrapper, EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+ try {
+ useWrapper.appendChild(sigSpan);
+
+ /* Insert a spacer below the top signature */
+ if (topSignature && content) {
+ node = document.createElement("DIV");
+ node.appendChild(document.createElement("BR"));
+ node.className = "-x-evo-top-signature-spacer";
+
+ document.body.insertBefore(node, useWrapper.nextSibling);
+ }
+ } finally {
+ EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM,
"InsertSignature::new-changes");
+ }
+ } else {
+ useWrapper = document.createElement("DIV");
+ useWrapper.className = "-x-evo-signature-wrapper";
+ useWrapper.appendChild(sigSpan);
+
+ EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM,
"InsertSignature::new-changes", document.body, document.body, EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+ try {
+ if (topSignature) {
+ document.body.insertBefore(useWrapper,
document.body.firstChild);
+
+ node = document.createElement("DIV");
+ node.appendChild(document.createElement("BR"));
+ node.className = "-x-evo-top-signature-spacer";
+
+ document.body.insertBefore(node, useWrapper.nextSibling);
+ } else {
+ document.body.appendChild(useWrapper);
+ }
+ } finally {
+ EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM,
"InsertSignature::new-changes");
+ }
+ }
+
+ fromMessage = false;
+
+ // Position the caret and scroll to it
+ if (startBottom) {
+ if (topSignature) {
+ document.getSelection().setPosition(document.body.lastChild, 0);
+ } else if (useWrapper.previousSibling) {
+ document.getSelection().setPosition(useWrapper.previousSibling, 0);
+ } else {
+ document.getSelection().setPosition(useWrapper, 0);
+ }
+ } else {
+ document.getSelection().setPosition(document.body.firstChild, 0);
+ }
+
+ node = document.getSelection().baseNode;
+
+ if (node) {
+ node.scrollIntoViewIfNeeded();
+ }
+ }
+ } finally {
+ EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_GROUP, "InsertSignature");
+ }
+
var res = [];
res["fromMessage"] = fromMessage;
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index cd49e51f3f..79af858b8d 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -2710,10 +2710,17 @@ webkit_editor_insert_signature (EContentEditor *editor,
gboolean *ignore_next_signature_change)
{
JSCValue *jsc_value;
- gchar *res = NULL;
+ gchar *res = NULL, *tmp = NULL;
g_return_val_if_fail (E_IS_WEBKIT_EDITOR (editor), NULL);
+ if (!is_html && content && *content) {
+ tmp = camel_text_to_html (content, CAMEL_MIME_FILTER_TOHTML_PRE, 0);
+
+ if (tmp)
+ content = tmp;
+ }
+
jsc_value = webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor),
"EvoEditor.InsertSignature(%s, %x, %s, %x, %x, %x, %x, %x, %x);",
content ? content : "",
@@ -2726,6 +2733,8 @@ webkit_editor_insert_signature (EContentEditor *editor,
e_webkit_editor_three_state_to_bool (e_content_editor_get_top_signature (editor),
"composer-top-signature"),
!e_webkit_editor_three_state_to_bool (E_THREE_STATE_INCONSISTENT,
"composer-no-signature-delim"));
+ g_free (tmp);
+
if (jsc_value) {
*set_signature_from_message = e_web_view_jsc_get_object_property_boolean (jsc_value,
"fromMessage", FALSE);
*check_if_signature_is_changed = e_web_view_jsc_get_object_property_boolean (jsc_value,
"checkChanged", FALSE);
@@ -2815,22 +2824,13 @@ webkit_editor_replace (EContentEditor *editor,
const gchar *replacement)
{
EWebKitEditor *wk_editor;
- GVariant *result;
- wk_editor = E_WEBKIT_EDITOR (editor);
- if (!wk_editor->priv->web_extension_proxy) {
- printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
- return;
- }
+ g_return_if_fail (E_IS_WEBKIT_EDITOR (editor));
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- wk_editor->priv->web_extension_proxy,
- "DOMSelectionReplace",
- g_variant_new ("(ts)", current_page_id (wk_editor), replacement),
- wk_editor->priv->cancellable);
+ wk_editor = E_WEBKIT_EDITOR (editor);
- if (result)
- g_variant_unref (result);
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+ "EvoEditor.ReplaceSelection(%s);", replacement);
}
static gboolean
@@ -2855,11 +2855,8 @@ webkit_find_controller_found_text_cb (WebKitFindController *find_controller,
/* Repeatedly search for 'word', then replace selection by
* 'replacement'. Repeat until there's at least one occurrence of
* 'word' in the document */
- e_util_invoke_g_dbus_proxy_call_with_error_check (
- wk_editor->priv->web_extension_proxy,
- "DOMSelectionReplace",
- g_variant_new ("(ts)", current_page_id (wk_editor), wk_editor->priv->replace_with),
- wk_editor->priv->cancellable);
+ e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+ "EvoEditor.ReplaceSelection(%s);", wk_editor->priv->replace_with);
g_idle_add ((GSourceFunc) search_next_on_idle, wk_editor);
} else {
@@ -2876,26 +2873,6 @@ webkit_find_controller_failed_to_find_text_cb (WebKitFindController *find_contro
if (wk_editor->priv->performing_replace_all) {
guint replaced_count = wk_editor->priv->replaced_count;
- if (replaced_count > 0) {
- if (!wk_editor->priv->web_extension_proxy) {
- printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
- } else {
- GVariant *result;
-
- result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
- wk_editor->priv->web_extension_proxy,
- "DOMInsertReplaceAllHistoryEvent",
- g_variant_new ("(tss)",
- current_page_id (wk_editor),
- webkit_find_controller_get_search_text (find_controller),
- wk_editor->priv->replace_with),
- NULL);
-
- if (result)
- g_variant_unref (result);
- }
- }
-
webkit_editor_finish_search (wk_editor);
e_content_editor_emit_replace_all_done (E_CONTENT_EDITOR (wk_editor), replaced_count);
} else {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]