[geary: 1/2] Don't linkify text near a URL that looks like a URL with a bad protocol



commit feed89225f00db68170f405965643dbdf45b64b9
Author: Alex Henrie <alexhenrie24 gmail com>
Date:   Tue Oct 22 18:53:18 2019 -0600

    Don't linkify text near a URL that looks like a URL with a bad protocol

 test/js/composer-page-state-test.vala |  4 +++
 ui/composer-web-view.js               | 55 ++++++++++++++++++-----------------
 2 files changed, 33 insertions(+), 26 deletions(-)
---
diff --git a/test/js/composer-page-state-test.vala b/test/js/composer-page-state-test.vala
index 6a7781b2..465bcc12 100644
--- a/test/js/composer-page-state-test.vala
+++ b/test/js/composer-page-state-test.vala
@@ -234,6 +234,8 @@ http://example1.com
 <a href="blarg">http://example5.com</a>
 
 unknown://example6.com
+
+I can send email through smtp.gmail.com:587 or through https://www.gmail.com/
 """);
 
         string expected = """
@@ -246,6 +248,8 @@ unknown://example6.com
 <a href="blarg">http://example5.com</a>
 
 unknown://example6.com
+
+I can send email through smtp.gmail.com:587 or through <a 
href="https://www.gmail.com/";>https://www.gmail.com/</a>
 """;
 
         try {
diff --git a/ui/composer-web-view.js b/ui/composer-web-view.js
index 3abda414..3ad9de21 100644
--- a/ui/composer-web-view.js
+++ b/ui/composer-web-view.js
@@ -576,33 +576,36 @@ ComposerPageState.htmlToText = function(root, blacklist = []) {
 // Linkifies "plain text" link
 ComposerPageState.linkify = function(node) {
     if (node.nodeType == Node.TEXT_NODE) {
-        // Examine text node for something that looks like a URL
-        let input = node.nodeValue;
-        if (input != null) {
-            let output = input.replace(ComposerPageState.URL_REGEX, function(url) {
-                if (url.match(ComposerPageState.PROTOCOL_REGEX) != null) {
-                    url = "\x01" + url + "\x01";
+        while (node.nodeValue) {
+            // Examine text node for something that looks like a URL
+            let urlRegex = new RegExp(ComposerPageState.URL_REGEX);
+            let url;
+            do {
+                let urlMatch = urlRegex.exec(node.nodeValue);
+                if (!urlMatch) {
+                    return;
                 }
-                return url;
-            });
-
-            if (input != output) {
-                // We got one!  Now split the text and swap in a new anchor.
-                let parent = node.parentNode;
-                let sibling = node.nextSibling;
-                for (let part of output.split("\x01")) {
-                    let newNode = null;
-                    if (part.match(ComposerPageState.URL_REGEX) != null) {
-                        newNode = document.createElement("A");
-                        newNode.href = part;
-                        newNode.innerText = part;
-                    } else {
-                        newNode = document.createTextNode(part);
-                    }
-                    parent.insertBefore(newNode, sibling);
-                }
-                parent.removeChild(node);
-            }
+                url = urlMatch[0];
+            } while (!url.match(ComposerPageState.PROTOCOL_REGEX));
+
+            // We got one! Now split the text and swap in a new anchor.
+            let before = node.nodeValue.substring(0, urlRegex.lastIndex - url.length);
+            let after = node.nodeValue.substring(urlRegex.lastIndex);
+
+            let beforeNode = document.createTextNode(before);
+            let linkNode = document.createElement("A");
+            linkNode.href = url;
+            linkNode.textContent = url;
+            let afterNode = document.createTextNode(after);
+
+            let parentNode = node.parentNode;
+            parentNode.insertBefore(beforeNode, node);
+            parentNode.insertBefore(linkNode, node);
+            parentNode.insertBefore(afterNode, node);
+            parentNode.removeChild(node);
+
+            // Keep searching for URLs after this one
+            node = afterNode;
         }
     } else {
         // Recurse


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