From feed89225f00db68170f405965643dbdf45b64b9 Mon Sep 17 00:00:00 2001 From: Alex Henrie Date: Tue, 22 Oct 2019 18:53:18 -0600 Subject: [PATCH] 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 | 53 ++++++++++++++------------- 2 files changed, 32 insertions(+), 25 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 http://example5.com 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 http://example5.com unknown://example6.com + +I can send email through smtp.gmail.com:587 or through https://www.gmail.com/ """; 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; - }); + url = urlMatch[0]; + } while (!url.match(ComposerPageState.PROTOCOL_REGEX)); - 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); - } + // 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