[evolution/wip/mcrha/webkit-jsc-api: 252/292] Add code to strip invalid URL characters from the magic-link URL



commit 2cd6b995fc0fa03d4e9452ed8cca177a3f63a39d
Author: Milan Crha <mcrha redhat com>
Date:   Thu Dec 5 15:23:28 2019 +0100

    Add code to strip invalid URL characters from the magic-link URL

 data/webkit/e-editor.js    | 99 +++++++++++++++++++++++++++++++++++-----------
 data/webkit/e-undo-redo.js |  7 +++-
 2 files changed, 81 insertions(+), 25 deletions(-)
---
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index d1438788bd..3e9c567864 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -2077,7 +2077,7 @@ EvoEditor.UpdateThemeStyleSheet = function(css)
        return EvoEditor.UpdateStyleSheet("x-evo-theme-sheet", css);
 }
 
-EvoEditor.MaybeReplaceTextAfterInput = function(inputEvent, isWordDelim)
+EvoEditor.AfterInputEvent = function(inputEvent, isWordDelim)
 {
        var isInsertParagraph = inputEvent.inputType == "insertParagraph";
 
@@ -2133,9 +2133,7 @@ EvoEditor.MaybeReplaceTextAfterInput = function(inputEvent, isWordDelim)
                }
        }
 
-       var text = baseNode.nodeValue, selectionUpdater, covered = false;
-
-       selectionUpdater = EvoSelection.CreateUpdaterObject();
+       var text = baseNode.nodeValue, covered = false;
 
        if (canLinks) {
                var isEmail = text.search("@") >= 0, match;
@@ -2143,39 +2141,92 @@ EvoEditor.MaybeReplaceTextAfterInput = function(inputEvent, isWordDelim)
                // the replace call below replaces &nbsp; (0xA0) with regular space
                match = EvoEditor.findPattern(text.replace(/ /g, " "), isEmail ? EvoEditor.EMAIL_PATTERN : 
EvoEditor.URL_PATTERN);
                if (match) {
-                       var url = text.substring(match.start, match.end), node;
+                       var url = text.substring(match.start, match.end), node, selection;
 
-                       EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "magicLink", 
baseNode.parentElement, baseNode.parentElement,
-                               EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+                       // because 'search' uses Regex and throws exception on brackets and other 
Regex-sensitive characters
+                       var isInvalidTrailingChar = function(chr) {
+                               var jj;
 
-                       try {
-                               covered = true;
+                               for (jj = 0; jj < EvoEditor.URL_INVALID_TRAILING_CHARS.length; jj++) {
+                                       if (chr == EvoEditor.URL_INVALID_TRAILING_CHARS.charAt(jj))
+                                               return true;
+                               }
 
-                               baseNode.splitText(match.end);
-                               baseNode.splitText(match.start);
+                               return false;
+                       };
 
-                               baseNode = baseNode.nextSibling;
+                       /* URLs are extremely unlikely to end with any punctuation, so
+                        * strip any trailing punctuation off from link and put it after
+                        * the link. Do the same for any closing double-quotes as well. */
+                       while (url.length > 0 && isInvalidTrailingChar(url.charAt(url.length - 1))) {
+                               var open_bracket = 0, close_bracket = url.charAt(url.length - 1);
+
+                               if (close_bracket == ')')
+                                       open_bracket = '(';
+                               else if (close_bracket == '}')
+                                       open_bracket = '{';
+                               else if (close_bracket == ']')
+                                       open_bracket = '[';
+                               else if (close_bracket == '>')
+                                       open_bracket = '<';
+
+                               if (open_bracket != 0) {
+                                       var n_opened = 0, n_closed = 0, ii, chr;
+
+                                       for (ii = 0; ii < url.length; ii++) {
+                                               chr = url.charAt(ii);
+
+                                               if (chr == open_bracket)
+                                                       n_opened++;
+                                               else if (chr == close_bracket)
+                                                       n_closed++;
+                                       }
 
-                               if (isEmail)
-                                       url = "mailto:"; + url;
-                               else if (url.startsWith("www."))
-                                       url = "http://"; + url;
+                                       /* The closing bracket can match one inside the URL,
+                                          thus keep it there. */
+                                       if (n_opened > 0 && n_opened - n_closed >= 0)
+                                               break;
+                               }
 
-                               node = document.createElement("A");
-                               node.href = url;
+                               url = url.substr(0, url.length - 1);
+                               match.end--;
+                       }
 
-                               baseNode.parentElement.insertBefore(node, baseNode);
-                               node.appendChild(baseNode);
-                       } finally {
-                               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "magicLink");
+                       if (url.length > 0) {
+                               selection = EvoSelection.Store(document);
+
+                               EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "magicLink", 
baseNode.parentElement, baseNode.parentElement,
+                                       EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML);
+
+                               try {
+                                       covered = true;
+
+                                       baseNode.splitText(match.end);
+                                       baseNode.splitText(match.start);
+
+                                       baseNode = baseNode.nextSibling;
+
+                                       if (isEmail)
+                                               url = "mailto:"; + url;
+                                       else if (url.startsWith("www."))
+                                               url = "http://"; + url;
+
+                                       node = document.createElement("A");
+                                       node.href = url;
+
+                                       baseNode.parentElement.insertBefore(node, baseNode);
+                                       node.appendChild(baseNode);
+
+                                       EvoSelection.Restore(document, selection);
+                               } finally {
+                                       EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "magicLink");
+                               }
                        }
                }
        }
 
        if (!covered && EvoEditor.MAGIC_SMILEYS) {
        }
-
-       selectionUpdater.restore();
 }
 
 document.onload = EvoEditor.initializeContent;
diff --git a/data/webkit/e-undo-redo.js b/data/webkit/e-undo-redo.js
index 1024d419d6..5155578519 100644
--- a/data/webkit/e-undo-redo.js
+++ b/data/webkit/e-undo-redo.js
@@ -481,7 +481,7 @@ EvoUndoRedo.input_cb = function(inputEvent)
        if (opType == "insertFromDrop")
                EvoUndoRedo.dropTarget = null;
 
-       EvoEditor.MaybeReplaceTextAfterInput(inputEvent, isWordDelim);
+       EvoEditor.AfterInputEvent(inputEvent, isWordDelim);
 }
 
 EvoUndoRedo.drop_cb = function(event)
@@ -623,6 +623,11 @@ EvoUndoRedo.StopRecord = function(kind, opType)
 
        EvoUndoRedo.ongoingRecordings.length = EvoUndoRedo.ongoingRecordings.length - 1;
 
+       // ignore empty group records
+       if (kind == EvoUndoRedo.RECORD_KIND_GROUP && (!record.records || !record.records.length)) {
+               record.ignore = true;
+       }
+
        if (record.ignore) {
                if (!EvoUndoRedo.ongoingRecordings.length &&
                    (record.kind != EvoUndoRedo.RECORD_KIND_EVENT || record.opType != "insertText")) {


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