Mailspring/internal_packages/message-list/lib/autolinker.es6
Ben Gotow c76582194a rm(autolinker): Use our own very simple autolinker
Summary:
Autolinker is a great open source project but it attempts to parse HTML with regexp, is quite slow, and hangs on specific emails https://github.com/nylas/N1/issues/1540

This is super bad, and also super unnecessary. I think this should do the trick.

Note: I changed the urlRegex in our Utils to be much more liberal. It now matches anything that looks like a URL, not just things with the http:// and https:// prefixes. It's used in the LinkEditor and onboarding screen (detecting auth errors with urls) and I think it should be ok?

Test Plan: Need to write some tests

Reviewers: evan, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D2725
2016-03-14 12:30:54 -07:00

54 lines
1.8 KiB
JavaScript

import {RegExpUtils, DOMUtils} from 'nylas-exports';
function _runOnTextNode(node, matchers) {
if (node.parentElement) {
const withinScript = node.parentElement.tagName === "SCRIPT";
const withinStyle = node.parentElement.tagName === "STYLE";
const withinA = (node.parentElement.closest('a') !== null);
if (withinScript || withinA || withinStyle) {
return;
}
}
if (node.textContent.trim().length < 4) {
return;
}
for (const [prefix, regex] of matchers) {
regex.lastIndex = 0;
const match = regex.exec(node.textContent);
if (match !== null) {
const href = `${prefix}${match[0]}`;
const range = document.createRange();
range.setStart(node, match.index);
range.setEnd(node, match.index + match[0].length);
const aTag = DOMUtils.wrap(range, 'A');
aTag.href = href;
aTag.title = href;
return;
}
}
}
export function autolink(doc) {
// Traverse the new DOM tree and make things that look like links clickable,
// and ensure anything with an href has a title attribute.
const textWalker = document.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT);
const matchers = [
['mailto:', RegExpUtils.emailRegex()],
['tel:', RegExpUtils.phoneRegex()],
['', RegExpUtils.urlRegex({matchEntireString: false})],
];
while (textWalker.nextNode()) {
_runOnTextNode(textWalker.currentNode, matchers);
}
// Traverse the new DOM tree and make sure everything with an href has a title.
const aTagWalker = document.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT, {
acceptNode: (node) =>
(node.href && !node.title) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP
,
});
while (aTagWalker.nextNode()) {
aTagWalker.currentNode.title = aTagWalker.currentNode.href;
}
}