forked from sindresorhus/linkify-urls
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
49 lines (39 loc) · 1.45 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
'use strict';
// - const urlRegex = require('url-regex');
const createHtmlElement = require('create-html-element');
// Capture the whole URL in group 1 to keep string.split() support
const urlRegex = () => (/((?:https?(?::\/\/))(?:www\.)?[a-zA-Z0-9-_.]+(?:\.[a-zA-Z0-9]{2,})(?:[-a-zA-Z0-9:%_+.~#?&//=@]*))/g);
// Get <a> element as string
const linkify = (href, options) => createHtmlElement({
name: 'a',
attributes: Object.assign({href: ''}, options.attributes, {href}),
value: typeof options.value === 'undefined' ? href : options.value
});
// Get DOM node from HTML
const domify = html => document.createRange().createContextualFragment(html);
const getAsString = (input, options) => {
return input.replace(urlRegex(), match => linkify(match, options));
};
const getAsDocumentFragment = (input, options) => {
return input.split(urlRegex()).reduce((frag, text, index) => {
if (index % 2) { // URLs are always in odd positions
frag.appendChild(domify(linkify(text, options)));
} else if (text.length > 0) {
frag.appendChild(document.createTextNode(text));
}
return frag;
}, document.createDocumentFragment());
};
module.exports = (input, options) => {
options = Object.assign({
attributes: {},
type: 'string'
}, options);
if (options.type === 'string') {
return getAsString(input, options);
}
if (options.type === 'dom') {
return getAsDocumentFragment(input, options);
}
throw new Error('The type option must be either dom or string');
};