Skip to content

Commit

Permalink
Skip truncated links (#40)
Browse files Browse the repository at this point in the history
Co-authored-by: Federico Brigante <me@fregante.com>
  • Loading branch information
Katsute and fregante authored Sep 9, 2023
1 parent edd75a6 commit fc9bb7c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
16 changes: 13 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@ const linkify = (href, options) => createHtmlElement({
// Get DOM node from HTML
const domify = html => document.createRange().createContextualFragment(html);

const getAsString = (string, options) => string.replace(urlRegex(), match => linkify(match, options));
const isTruncated = (url, peek) =>
url.endsWith('...') // `...` is a matched by the URL regex
|| peek.startsWith('…'); // `…` can follow the match

const getAsString = (string, options) => string.replace(urlRegex(), (url, _, offset) =>
(isTruncated(url, string.charAt(offset + url.length)))
? url // Don't linkify truncated URLs
: linkify(url, options));

const getAsDocumentFragment = (string, options) => {
const fragment = document.createDocumentFragment();
for (const [index, text] of Object.entries(string.split(urlRegex()))) {
if (index % 2) { // URLs are always in odd positions
const parts = string.split(urlRegex());

for (const [index, text] of parts.entries()) {
// URLs are always in odd positions
if (index % 2 && !isTruncated(text, parts[index + 1])) {
fragment.append(domify(linkify(text, options)));
} else if (text.length > 0) {
fragment.append(text);
Expand Down
38 changes: 38 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,41 @@ test('supports localhost URLs', t => {
t.is(linkifyUrls('https://localhost'), '<a href="https://localhost">https://localhost</a>');
t.is(linkifyUrls('https://localhost/foo/bar'), '<a href="https://localhost/foo/bar">https://localhost/foo/bar</a>');
});

test('skips truncated URLs', t => {
t.is(linkifyUrls('https://github.com/sindresorhus/linkify-…'), 'https://github.com/sindresorhus/linkify-…');
t.is(linkifyUrls('https://github.com/sindresorhus/linkify-… and https://github.com/sindresorhus/linkify-…'), 'https://github.com/sindresorhus/linkify-… and https://github.com/sindresorhus/linkify-…');
t.is(linkifyUrls('https://github.com/sindresorhus/linkify-urls and more…'), '<a href="https://github.com/sindresorhus/linkify-urls">https://github.com/sindresorhus/linkify-urls</a> and more…');

t.is(linkifyUrls('https://github.com/sindresorhus/linkify-...'), 'https://github.com/sindresorhus/linkify-...');
t.is(linkifyUrls('https://github.com/sindresorhus/linkify-... and https://github.com/sindresorhus/linkify-...'), 'https://github.com/sindresorhus/linkify-... and https://github.com/sindresorhus/linkify-...');
t.is(linkifyUrls('https://github.com/sindresorhus/linkify-urls and more...'), '<a href="https://github.com/sindresorhus/linkify-urls">https://github.com/sindresorhus/linkify-urls</a> and more...');
});

test('skips truncated URLs (DocumentFragment)', t => {
t.is(
html(linkifyUrls('See https://github.com/sindresorhus/linkify-urls and https://github.com/sindresorhus/linkify-…', {
type: 'dom',
})),
html(domify('See <a href="https://github.com/sindresorhus/linkify-urls">https://github.com/sindresorhus/linkify-urls</a> and https://github.com/sindresorhus/linkify-…')),
);
t.is(
html(linkifyUrls('See https://github.com/sindresorhus/linkify-urls… and https://github.com/sindresorhus/linkify-…', {
type: 'dom',
})),
html(domify('See https://github.com/sindresorhus/linkify-urls… and https://github.com/sindresorhus/linkify-…')),
);

t.is(
html(linkifyUrls('See https://github.com/sindresorhus/linkify-urls and https://github.com/sindresorhus/linkify-...', {
type: 'dom',
})),
html(domify('See <a href="https://github.com/sindresorhus/linkify-urls">https://github.com/sindresorhus/linkify-urls</a> and https://github.com/sindresorhus/linkify-...')),
);
t.is(
html(linkifyUrls('See https://github.com/sindresorhus/linkify-... and https://github.com/sindresorhus/linkify-...', {
type: 'dom',
})),
html(domify('See https://github.com/sindresorhus/linkify-... and https://github.com/sindresorhus/linkify-...')),
);
});

0 comments on commit fc9bb7c

Please sign in to comment.