├── .cjsescache
├── .editorconfig
├── .eslintrc.js
├── .github
└── workflows
│ └── test.yml
├── .gitignore
├── LICENSE
├── README.md
├── build-tlds.js
├── codecov.yml
├── demo
├── demo.css
├── demo.html
└── demo.js
├── dist
├── linkify-plus-plus-core.esm.js
├── linkify-plus-plus-core.esm.js.map
├── linkify-plus-plus-core.js
├── linkify-plus-plus-core.js.map
├── linkify-plus-plus-core.min.js
└── linkify-plus-plus-core.min.js.map
├── eslint.config.mjs
├── index.js
├── lib
├── linkifier.js
├── tlds.json
└── url-matcher.js
├── package-lock.json
├── package.json
├── rollup.config.mjs
├── test
├── __snapshots__
│ └── test.snap.js
└── test.mjs
└── web-test-runner.config.mjs
/.cjsescache:
--------------------------------------------------------------------------------
1 | [
2 | "node_modules/event-lite/event-lite.mjs"
3 | ]
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | indent_style = space
3 | indent_size = 2
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "extends": [
3 | "eslint:recommended",
4 | "plugin:compat/recommended"
5 | ],
6 | "env": {
7 | "es6": true,
8 | "node": true
9 | },
10 | parserOptions: {
11 | ecmaVersion: 2024
12 | },
13 | overrides: [
14 | {
15 | files: ["**/__snapshots__/*.js"],
16 | parserOptions: {
17 | sourceType: "module"
18 | }
19 | }
20 | ]
21 | };
22 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: test
2 | on: [push, pull_request]
3 |
4 | jobs:
5 | test:
6 | runs-on: ubuntu-latest
7 |
8 | steps:
9 | - uses: actions/checkout@v3
10 | - uses: actions/setup-node@v3
11 | with:
12 | node-version: '18'
13 | - run: npm ci
14 | - run: npm run test-cover
15 | - uses: codecov/codecov-action@v5
16 | with:
17 | fail_ci_if_error: true
18 | verbose: true
19 | token: ${{ secrets.CODECOV_TOKEN }}
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011, Anthony Lieuallen
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 | * Neither the name of Anthony Lieuallen nor the names of its contributors may
13 | be used to endorse or promote products derived from this software without
14 | specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Linkify Plus Plus Core
2 | ======================
3 |
4 | [](https://github.com/eight04/linkify-plus-plus-core/actions/workflows/test.yml)
5 | [](https://codecov.io/gh/eight04/linkify-plus-plus-core)
6 |
7 | A JavaScript library for linkification stuff. Used by [linkify-plus-plus](https://github.com/eight04/linkify-plus-plus).
8 |
9 | Demo
10 | ----
11 | https://rawgit.com/eight04/linkify-plus-plus-core/master/demo/demo.html
12 |
13 | Features
14 | --------
15 |
16 | This module exports 2 classes.
17 |
18 | * UrlMatcher - a URL matcher which can match almost all types of links from a string.
19 | * Linkifier - to linkify an element.
20 |
21 | Compatibility
22 | -------------
23 |
24 | * Tested on Firefox >= 56.
25 | * Support HTML/XHTML pages.
26 |
27 | Installation
28 | ------------
29 |
30 | ```
31 | npm install linkify-plus-plus-core
32 | ```
33 |
34 | ```JavaScript
35 | const {UrlMatcher, Linkifier} = require("linkify-plus-plus-core");
36 | // or use the matcher only
37 | const {UrlMatcher} = require("linkify-plus-plus-core/lib/url-matcher")
38 | ```
39 |
40 | There is also a browserified standalone build in `dist` folder, which can be included in your html directly.
41 |
42 | ```
43 |
44 |
48 | ```
49 |
50 | unpkg.com CDN:
51 |
52 | * https://unpkg.com/linkify-plus-plus-core/dist/linkify-plus-plus-core.js
53 | * https://unpkg.com/linkify-plus-plus-core/dist/linkify-plus-plus-core.min.js
54 |
55 | Usage
56 | -----
57 |
58 | ```JavaScript
59 | // create a matcher
60 | const matcher = new UrlMatcher();
61 |
62 | for (const link of matcher.match(text)) {
63 | // matcher.match() returns a generator, yielding an object for each match result
64 | console.log(link.start, link.end, link.text, link.url);
65 | }
66 | ```
67 |
68 | ```JavaScript
69 | // Linkifier needs a matcher to work
70 | const linkifier = new Linkifier(document.body, {matcher: matcher});
71 |
72 | // Linkifier will walk through the DOM tree, match url against all text nodes, and replace them with anchor element.
73 | linkifier.on("complete", elapse => {
74 | console.log(`finished in ${elapse}ms`);
75 | });
76 | linkifier.on("error", err => {
77 | console.log("failed with error:", err);
78 | });
79 | linkifier.start();
80 |
81 | // It is suggested to use `linkify()` function which wraps Linkifier to a promise.
82 | linkify(document.body, {matcher}).then(onComplete, onError);
83 | ```
84 |
85 | API references
86 | --------------
87 |
88 | This module exports:
89 |
90 | * UrlMatcher - a class to find link from string
91 | * Linkifier - a class to linkify elements
92 | * linkify - a function wrapping Linkifier. Return a promise.
93 | * INVALID_TAGS - a table of uppercase tag name, which are invalid ancestors for `` element.
94 |
95 | ### UrlMatcher
96 |
97 | ```js
98 | const urlMatcher = new UrlMatcher({
99 | fuzzyIp: Boolean,
100 | mail: Boolean,
101 | ignoreMustache: Boolean,
102 | unicode: Boolean,
103 | customRules: Array,
104 | standalone: Boolean,
105 | boundaryLeft: String,
106 | boundaryRight: String
107 | });
108 | ```
109 |
110 | All options are optional:
111 |
112 | * `fuzzyIp` - match 4 digits IP, which often looks like version numbers. Default: `true`
113 | * `mail` - match email. Default: `true`
114 | * `ignoreMustache` - ignore links inside mustache "{{", "}}". This is useful to work with other template library like Vue.js. Default: `false`
115 | * `unicode` - match unicode character. Default: `false`
116 | * `customRules` - a list of regex pattern (in string). E.g. `["file:///\\S+", "magnet:\\?\\S+"]`. Default: `[]`
117 | * `standalone` - the link must be surrounded by whitespace. Default: `false`
118 | * `boundaryLeft` - has no effect without the `standalone` option. Allow some characters to be placed between whitespace and link. Some common characters are `{[("'`. Default: `""`
119 | * `boundaryRight` - has no effect without the `standalone` option. Allow some characters to be placed between whitespace and link. Some common characters are `'")]},.;?!`. Default: `""`
120 |
121 | #### urlMatcher.match
122 |
123 | ```js
124 | for (const matchResult of urlMatcher.match(text: String)) {
125 | ...
126 | }
127 | ```
128 |
129 | Match the text and return a generator which yields matched results.
130 |
131 | `matchResult` object:
132 |
133 | ```js
134 | matchResult: {
135 | start: Integer,
136 | end: Integer,
137 | text: String,
138 | url: String,
139 | custom: Boolean,
140 | protocol: String,
141 | auth: String,
142 | domain: String,
143 | port: String,
144 | path: String
145 | }
146 | ```
147 |
148 | * `start` - the start position of the url.
149 | * `end` - the end position of the url.
150 | * `text` - matched text.
151 | * `url` - the url of the link. `.url` doesn't always equal `.text`, that `.text` might lack of the protocol but `.url` is always a full URL.
152 | * `custom` - indicate if the result is matched by custom 4rules.
153 |
154 | Other properties i.e. `.protocol`, `.auth`, `.domain`, `.port`, and `.path` are different parts of the URL.
155 |
156 | ### Linkifier
157 |
158 | ```js
159 | const linkifier = new Linkifier([root: Element, ] options: Object);
160 | ```
161 |
162 | This class extends [`event-lite`](https://www.npmjs.com/package/event-lite).
163 |
164 | * `root` - the element that is going to be linkified.
165 |
166 | `options` object:
167 |
168 | ```js
169 | options: {
170 | matcher: UrlMatcher,
171 | validator?: Function,
172 | newTab?: Boolean,
173 | noOpener?: Boolean,
174 | root?: Element,
175 | embedImage?: Boolean,
176 | maxRunTime?: Number,
177 | timeout?: Number,
178 | recursive?: Boolean
179 | }
180 | ```
181 |
182 | * `matcher` - A `UrlMatcher`, required.
183 |
184 | In fact, any object having a `.match` method which accepts a string and returns an iterable of matched result should work.
185 |
186 | The match result must have `.start`, `.end`, `.text`, and `.url` properties described above.
187 |
188 | * `validator` - A function recieving an element and returning a boolean to decide if the element should be linkified. Note that the elements in `INVALID_TAGS` are already filtered out before the validator.
189 | * `newTab` - add `target="_blank"` to the link. Default: `true`
190 | * `noOpener` - add `rel="noopener"` to the link. Default: `true`
191 | * `root` - if you didn't supply the position argument `root` argument to the constructor, this value is used.
192 | * `embedImage` - create `
` for the link if the URL looks like an image. Default: `true`
193 | * `maxRunTime` - in milliseconds. The linkify process is split into small chunks to avoid blocking. This is the max execution time of each chunk. Default: `100`
194 | * `timeout` - in milliseconds. If linkification have processed over this value, an error is raised. Note that any heavy work between each chunks are counted as in timeout too. Default: `10000`
195 | * `recursive` - if true, linkify the entire node tree. Otherwise, only text nodes under `root` are linkified. Default: `true`
196 |
197 | #### linkifier.start
198 |
199 | ```js
200 | linkifier.start()
201 | ```
202 |
203 | Start linkification. The linkifier would walk through the DOM tree, collect text nodes and `` tags, match URLs with matcher, and convert them into links.
204 |
205 | #### linkifier.abort
206 |
207 | ```js
208 | linkifier.abort()
209 | ```
210 |
211 | Abort linkification.
212 |
213 | #### linkifier events
214 |
215 | `Linkifier` emits following events, which could be listened with `.on`:
216 |
217 | * `complete` - emitted when the linkification completed. Listener arguments:
218 |
219 | - `elapse: Number` - time in milliseconds that the linkifier took to complete.
220 |
221 | * `error` - emitted when the linkification failed. Listener arguments:
222 |
223 | - `error: Error` - The error.
224 |
225 | * `link` - emitted when a link is created. You can alter the style, or implement your link builder to replace the default one. Listener arguments:
226 |
227 | - An object containing following properties:
228 |
229 | - `result: Object` - the result object yielded by `UrlMatcher.match()`
230 | - `range: Range` - the text range that the linkifier is working on. Do not change the range unless you know what you are doing.
231 | - `link: AnchorElement` - the link element.
232 | - `content: DocumentFragment` - the text (including `` tags) extracted from matched text range, which is usually used as the content of the link.
233 |
234 | ### linkify
235 |
236 | ```js
237 | async linkify([root: Element, ] options: Object)
238 | ```
239 |
240 | A convenient function to setup/start a linkifier. See `Linkifier` for the arguments. Additionally, if the options object has some keys starting with `on`, the function treats them as event listeners. You can register event listeners like:
241 |
242 | ```js
243 | linkify({
244 | root,
245 | matcher,
246 | onlink: ({link}) => {...}
247 | })
248 | .then(...);
249 | ```
250 |
251 | Other notes
252 | -----------
253 | * https://www.measurethat.net/Benchmarks/Show/1312/3/generator
254 | * https://www.measurethat.net/Benchmarks/Show/1313/0/generator-with-low-count-of-items
255 |
256 | License
257 | -------
258 | In the very old days, the script is based on Linkify Plus. Although it has been rewritten multiple times, the original license can be found [here](https://github.com/eight04/linkify-plus-plus-core/blob/master/LICENSE).
259 |
260 | TLD list is grabbed from .
261 |
262 | TLD count is grabbed from .
263 |
264 | Changelog
265 | ---------
266 |
267 | * 0.7.0 (Feb 20, 2025)
268 |
269 | - Add: onion TLD.
270 | - Update TLDs.
271 |
272 | * 0.6.1 (Feb 16, 2024)
273 |
274 | - Fix: options is undefined error.
275 |
276 | * 0.6.0 (Feb 14, 2024)
277 |
278 | - Add: `recursive` option in `Linkifier`.
279 | - Update TLDs.
280 |
281 | * 0.5.3 (Mar 10, 2021)
282 |
283 | - Fix: allow domains starting with digits.
284 |
285 | * 0.5.2 (Feb 12, 2021)
286 |
287 | - Fix: infinite loop bug.
288 |
289 | * 0.5.1 (Feb 11, 2021)
290 |
291 | - Update TLDs.
292 | - Change: match custom rules first.
293 | - Fix: handle invalid domains in a better way.
294 |
295 | * 0.5.0 (Oct 29, 2020)
296 |
297 | - Update TLDs.
298 | - Add: mail option.
299 | - Add: embed webp and apng.
300 | - **Change: the matcher will only verify TLD if the protocol is http(s) or mailto.**
301 |
302 | * 0.4.1 (Jun 17, 2019)
303 |
304 | - Update TLDs.
305 |
306 | * 0.4.0 (Feb 17, 2019)
307 |
308 | - **Breaking: drop Firefox < 56.**
309 | - **Breaking: drop babel.**
310 | - **Breaking: INVALID_TAGS is now in lower-case.**
311 | - Add: support XHTML pages.
312 | - Update TLDs.
313 |
314 | * 0.3.0 (Aug 23, 2017)
315 |
316 | - **Drop: Linkifier.prototype.linkify. Now Linkifier uses event pattern.**
317 | - Add linkify function.
318 | - Update TLDs.
319 |
320 | * 0.2.0 (Mar 4, 2017)
321 |
322 | - Use standalone build instead of require.
323 | - Fix: blocking bug with large element without matching urls.
324 |
325 | * 0.1.0 (Feb 23, 2017)
326 |
327 | - First release
328 |
--------------------------------------------------------------------------------
/build-tlds.js:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | const cheerio = require("cheerio");
3 | const punycode = require("punycode");
4 |
5 | async function rp(url) {
6 | const r = await fetch(url);
7 | if (!r.ok) {
8 | throw new Error(`Failed to fetch ${url}`);
9 | }
10 | return r.text();
11 | }
12 |
13 | Promise.all([
14 | rp("http://data.iana.org/TLD/tlds-alpha-by-domain.txt"),
15 | rp("http://research.domaintools.com/statistics/tld-counts/")
16 | ]).then(function([tlds, statistic]) {
17 | var $ = cheerio.load(statistic),
18 | tldCount = {};
19 |
20 | $("#tld-counts tbody").children().each(function(){
21 | var name = $(this).data("key"),
22 | amount = $(this).find(".amount").text().replace(/,/g, "");
23 |
24 | if (amount == "N/A") {
25 | amount = 0;
26 | }
27 |
28 | tldCount[name] = +amount;
29 | });
30 |
31 | tlds = tlds.split("\n")
32 | .map(line => line.toLowerCase())
33 | .filter(
34 | line =>
35 | line
36 | && line[0] != "#"
37 | && (tldCount[line] > 2 || tldCount[line] == undefined)
38 | );
39 |
40 | tlds = tlds.concat(
41 | tlds.filter(tld => tld.startsWith("xn--"))
42 | .map(tld => punycode.decode(tld.substr(4)))
43 | );
44 |
45 | tlds.push("onion");
46 |
47 | var repl = {
48 | maxLength: tlds.reduce(
49 | (max, tld) => tld.length > max ? tld.length : max,
50 | 0
51 | ),
52 |
53 | chars: [...tlds.reduce(
54 | (s, tld) => {
55 | for (let c of tld) {
56 | if (c.charCodeAt(0) >= 128) {
57 | s.add(c);
58 | }
59 | }
60 | return s;
61 | },
62 | new Set
63 | )].join(""),
64 |
65 | table: tlds.reduce(
66 | (o, tld) => {
67 | o[tld] = true;
68 | return o;
69 | },
70 | {}
71 | )
72 | };
73 |
74 | process.stdout.write(JSON.stringify(repl, null, " "));
75 | });
76 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | ignore:
2 | - node_modules
3 |
--------------------------------------------------------------------------------
/demo/demo.css:
--------------------------------------------------------------------------------
1 | body {
2 | word-wrap: break-word;
3 | }
4 | .main a {
5 | background-color: greenyellow;
6 | }
7 | img {
8 | color: red;
9 | }
10 |
--------------------------------------------------------------------------------
/demo/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Linkify Plus Plus Core
6 |
7 |
8 |
9 |
10 |
11 |
12 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/demo/demo.js:
--------------------------------------------------------------------------------
1 | /* eslint-env browser */
2 | /* globals Vue, linkifyPlusPlusCore */
3 | var {UrlMatcher, linkify} = linkifyPlusPlusCore;
4 |
5 | var app = new Vue({
6 | el: ".main",
7 | data: {
8 | text: "Try some links here!\n\nexample.com\nhttp://www.example.com",
9 | options: {
10 | fuzzyIp: true,
11 | ignoreMustache: true,
12 | unicode: false,
13 | newTab: true,
14 | embedImage: true
15 | }
16 | }
17 | });
18 |
19 | var state = {
20 | working: false,
21 | pending: false
22 | };
23 |
24 | function output() {
25 | if (state.working) {
26 | state.pending = true;
27 | return;
28 | }
29 | state.working = true;
30 | var out = document.querySelector("#output");
31 | out.textContent = app.text;
32 | var options = Object.assign(app.options);
33 | options.matcher = new UrlMatcher(options);
34 | linkify(out, options).then(() => {
35 | state.working = false;
36 | if (state.pending) {
37 | state.pending = false;
38 | output();
39 | }
40 | });
41 | }
42 |
43 | app.$watch(function() {
44 | return [this.text, this.options];
45 | }, output, {deep: true});
46 |
47 | output();
48 |
49 | function resize() {
50 | var el = document.querySelector("#input");
51 | el.style.minHeight = Math.max(el.scrollHeight, el.offsetHeight) + "px";
52 | }
53 |
54 | app.$watch("text", resize);
55 |
56 | resize();
57 |
--------------------------------------------------------------------------------
/dist/linkify-plus-plus-core.esm.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"linkify-plus-plus-core.esm.js","sources":["../lib/url-matcher.js","../node_modules/event-lite/event-lite.mjs","../lib/linkifier.js"],"sourcesContent":["var tlds = require(\"./tlds.json\"),\n\tRE = {\n\t\tPROTOCOL: \"([a-z][-a-z*]+://)?\",\n\t\tUSER: \"(?:([\\\\w:.+-]+)@)?\",\n\t\tDOMAIN_UNI: `([a-z0-9-.\\\\u00A0-\\\\uFFFF]+\\\\.[a-z0-9-${tlds.chars}]{1,${tlds.maxLength}})`,\n\t\tDOMAIN: `([a-z0-9-.]+\\\\.[a-z0-9-]{1,${tlds.maxLength}})`,\n\t\tPORT: \"(:\\\\d+\\\\b)?\",\n\t\tPATH_UNI: \"([/?#]\\\\S*)?\",\n\t\tPATH: \"([/?#][\\\\w-.~!$&*+;=:@%/?#(),'\\\\[\\\\]]*)?\"\n\t},\n\tTLD_TABLE = tlds.table;\n\nfunction regexEscape(text) {\n\treturn text.replace(/[[\\]\\\\^-]/g, \"\\\\$&\");\n}\n\nfunction buildRegex({\n\tunicode = false, customRules = [], standalone = false,\n\tboundaryLeft, boundaryRight\n}) {\n\tvar pattern = RE.PROTOCOL + RE.USER;\n\t\n\tif (unicode) {\n\t\tpattern += RE.DOMAIN_UNI + RE.PORT + RE.PATH_UNI;\n\t} else {\n\t\tpattern += RE.DOMAIN + RE.PORT + RE.PATH;\n\t}\n\t\n\tif (customRules.length) {\n\t\tpattern = \"(?:(\" + customRules.join(\"|\") + \")|\" + pattern + \")\";\n\t} else {\n\t\tpattern = \"()\" + pattern;\n\t}\n\t\n\tvar prefix, suffix, invalidSuffix;\n\tif (standalone) {\n\t\tif (boundaryLeft) {\n\t\t\tprefix = \"((?:^|\\\\s)[\" + regexEscape(boundaryLeft) + \"]*?)\";\n\t\t} else {\n\t\t\tprefix = \"(^|\\\\s)\";\n\t\t}\n\t\tif (boundaryRight) {\n\t\t\tsuffix = \"([\" + regexEscape(boundaryRight) + \"]*(?:$|\\\\s))\";\n\t\t} else {\n\t\t\tsuffix = \"($|\\\\s)\";\n\t\t}\n\t\tinvalidSuffix = \"[^\\\\s\" + regexEscape(boundaryRight) + \"]\";\n\t} else {\n\t\tprefix = \"(^|\\\\b|_)\";\n\t\tsuffix = \"()\";\n\t}\n\t\n\tpattern = prefix + pattern + suffix;\n\t\n\treturn {\n\t\turl: new RegExp(pattern, \"igm\"),\n\t\tinvalidSuffix: invalidSuffix && new RegExp(invalidSuffix),\n\t\tmustache: /\\{\\{[\\s\\S]+?\\}\\}/g\n\t};\n}\n\nfunction pathStrip(m, re, repl) {\n\tvar s = m.path.replace(re, repl);\n\n\tif (s == m.path) return;\n\t\n\tm.end -= m.path.length - s.length;\n\tm.suffix = m.path.slice(s.length) + m.suffix;\n\tm.path = s;\n}\n\nfunction pathStripQuote(m, c) {\n\tvar i = 0, s = m.path, end, pos = 0;\n\t\n\tif (!s.endsWith(c)) return;\n\t\n\twhile ((pos = s.indexOf(c, pos)) >= 0) {\n\t\tif (i % 2) {\n\t\t\tend = null;\n\t\t} else {\n\t\t\tend = pos;\n\t\t}\n\t\tpos++;\n\t\ti++;\n\t}\n\t\n\tif (!end) return;\n\t\n\tm.end -= s.length - end;\n\tm.path = s.slice(0, end);\n\tm.suffix = s.slice(end) + m.suffix;\n}\n\nfunction pathStripBrace(m, left, right) {\n\tvar str = m.path,\n\t\tre = new RegExp(\"[\\\\\" + left + \"\\\\\" + right + \"]\", \"g\"),\n\t\tmatch, count = 0, end;\n\n\t// Match loop\n\twhile ((match = re.exec(str))) {\n\t\tif (count % 2 == 0) {\n\t\t\tend = match.index;\n\t\t\tif (match[0] == right) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (match[0] == left) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount++;\n\t}\n\n\tif (!match && count % 2 == 0) {\n\t\treturn;\n\t}\n\t\n\tm.end -= m.path.length - end;\n\tm.path = str.slice(0, end);\n\tm.suffix = str.slice(end) + m.suffix;\n}\n\nfunction isIP(s) {\n\tvar m, i;\n\tif (!(m = s.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/))) {\n\t\treturn false;\n\t}\n\tfor (i = 1; i < m.length; i++) {\n\t\tif (+m[i] > 255 || (m[i].length > 1 && m[i][0] == \"0\")) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction inTLDS(domain) {\n\tvar match = domain.match(/\\.([^.]+)$/);\n\tif (!match) {\n\t\treturn false;\n\t}\n\tvar key = match[1].toLowerCase();\n // eslint-disable-next-line no-prototype-builtins\n\treturn TLD_TABLE.hasOwnProperty(key);\n}\n\nclass UrlMatcher {\n\tconstructor(options = {}) {\n\t\tthis.options = options;\n\t\tthis.regex = buildRegex(options);\n\t}\n\t\n\t*match(text) {\n\t\tvar {\n\t\t\t\tfuzzyIp = true,\n\t\t\t\tignoreMustache = false,\n mail = true\n\t\t\t} = this.options,\n\t\t\t{\n\t\t\t\turl,\n\t\t\t\tinvalidSuffix,\n\t\t\t\tmustache\n\t\t\t} = this.regex,\n\t\t\turlLastIndex, mustacheLastIndex;\n\t\t\t\n\t\tmustache.lastIndex = 0;\n\t\turl.lastIndex = 0;\n\t\t\n\t\tvar mustacheMatch, mustacheRange;\n\t\tif (ignoreMustache) {\n\t\t\tmustacheMatch = mustache.exec(text);\n\t\t\tif (mustacheMatch) {\n\t\t\t\tmustacheRange = {\n\t\t\t\t\tstart: mustacheMatch.index,\n\t\t\t\t\tend: mustache.lastIndex\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t\n\t\tvar urlMatch;\n\t\twhile ((urlMatch = url.exec(text))) {\n const result = {\n start: 0,\n end: 0,\n \n text: \"\",\n url: \"\",\n \n prefix: urlMatch[1],\n custom: urlMatch[2],\n protocol: urlMatch[3],\n auth: urlMatch[4] || \"\",\n domain: urlMatch[5],\n port: urlMatch[6] || \"\",\n path: urlMatch[7] || \"\",\n suffix: urlMatch[8]\n };\n \n if (result.custom) {\n result.start = urlMatch.index;\n result.end = url.lastIndex;\n result.text = result.url = urlMatch[0];\n\t\t\t} else {\n \n result.start = urlMatch.index + result.prefix.length;\n result.end = url.lastIndex - result.suffix.length;\n\t\t\t}\n\t\t\t\n\t\t\tif (mustacheRange && mustacheRange.end <= result.start) {\n\t\t\t\tmustacheMatch = mustache.exec(text);\n\t\t\t\tif (mustacheMatch) {\n\t\t\t\t\tmustacheRange.start = mustacheMatch.index;\n\t\t\t\t\tmustacheRange.end = mustache.lastIndex;\n\t\t\t\t} else {\n\t\t\t\t\tmustacheRange = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// ignore urls inside mustache pair\n\t\t\tif (mustacheRange && result.start < mustacheRange.end && result.end >= mustacheRange.start) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\n\t\t\tif (!result.custom) {\n\t\t\t\t// adjust path and suffix\n\t\t\t\tif (result.path) {\n\t\t\t\t\t// Strip BBCode\n\t\t\t\t\tpathStrip(result, /\\[\\/?(b|i|u|url|img|quote|code|size|color)\\].*/i, \"\");\n\t\t\t\t\t\n\t\t\t\t\t// Strip braces\n\t\t\t\t\tpathStripBrace(result, \"(\", \")\");\n\t\t\t\t\tpathStripBrace(result, \"[\", \"]\");\n\t\t\t\t\tpathStripBrace(result, \"{\", \"}\");\n\t\t\t\t\t\n\t\t\t\t\t// Strip quotes\n\t\t\t\t\tpathStripQuote(result, \"'\");\n\t\t\t\t\tpathStripQuote(result, '\"');\n\t\t\t\t\t\n\t\t\t\t\t// Remove trailing \".,?\"\n\t\t\t\t\tpathStrip(result, /(^|[^-_])[.,?]+$/, \"$1\");\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// check suffix\n\t\t\t\tif (invalidSuffix && invalidSuffix.test(result.suffix)) {\n\t\t\t\t\tif (/\\s$/.test(result.suffix)) {\n\t\t\t\t\t\turl.lastIndex--;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n \n // ignore fuzzy ip\n\t\t\t\tif (!fuzzyIp && isIP(result.domain) &&\n !result.protocol && !result.auth && !result.path) {\n continue;\n }\n \n\t\t\t\t// mailto protocol\n\t\t\t\tif (!result.protocol && result.auth) {\n\t\t\t\t\tvar matchMail = result.auth.match(/^mailto:(.+)/);\n\t\t\t\t\tif (matchMail) {\n\t\t\t\t\t\tresult.protocol = \"mailto:\";\n\t\t\t\t\t\tresult.auth = matchMail[1];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// http alias\n\t\t\t\tif (result.protocol && result.protocol.match(/^(hxxp|h\\*\\*p|ttp)/)) {\n\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t}\n\n\t\t\t\t// guess protocol\n\t\t\t\tif (!result.protocol) {\n\t\t\t\t\tvar domainMatch;\n\t\t\t\t\tif ((domainMatch = result.domain.match(/^(ftp|irc)/))) {\n\t\t\t\t\t\tresult.protocol = domainMatch[0] + \"://\";\n\t\t\t\t\t} else if (result.domain.match(/^(www|web)/)) {\n\t\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t\t} else if (result.auth && result.auth.indexOf(\":\") < 0 && !result.path) {\n\t\t\t\t\t\tresult.protocol = \"mailto:\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t\t}\n\t\t\t\t}\n \n // ignore mail\n if (!mail && result.protocol === \"mailto:\") {\n continue;\n }\n \n\t\t\t\t// verify domain\n if (!isIP(result.domain)) {\n if (/^(http|https|mailto)/.test(result.protocol) && !inTLDS(result.domain)) {\n continue;\n }\n \n const invalidLabel = getInvalidLabel(result.domain);\n if (invalidLabel) {\n url.lastIndex = urlMatch.index + invalidLabel.index + 1;\n continue;\n }\n }\n\n\t\t\t\t// Create URL\n\t\t\t\tresult.url = result.protocol + (result.auth && result.auth + \"@\") + result.domain + result.port + result.path;\n\t\t\t\tresult.text = text.slice(result.start, result.end);\n\t\t\t}\n\t\t\t\n\t\t\t// since regex is shared with other parse generators, cache lastIndex position and restore later\n\t\t\tmustacheLastIndex = mustache.lastIndex;\n\t\t\turlLastIndex = url.lastIndex;\n\t\t\t\n\t\t\tyield result;\n\t\t\t\n\t\t\turl.lastIndex = urlLastIndex;\n\t\t\tmustache.lastIndex = mustacheLastIndex;\n\t\t}\n\t}\n}\n\nfunction getInvalidLabel(domain) {\n // https://tools.ietf.org/html/rfc1035\n // https://serverfault.com/questions/638260/is-it-valid-for-a-hostname-to-start-with-a-digit\n let index = 0;\n const parts = domain.split(\".\");\n for (const part of parts) {\n if (\n !part ||\n part.startsWith(\"-\") ||\n part.endsWith(\"-\")\n ) {\n return {\n index,\n value: part\n };\n }\n index += part.length + 1;\n }\n}\n\nmodule.exports = {\n\tUrlMatcher\n};\n","/**\n * event-lite.js - Light-weight EventEmitter (less than 1KB when gzipped)\n *\n * @copyright Yusuke Kawasaki\n * @license MIT\n * @constructor\n * @see https://github.com/kawanet/event-lite\n * @see http://kawanet.github.io/event-lite/EventLite.html\n * @example\n * var EventLite = require(\"event-lite\");\n *\n * function MyClass() {...} // your class\n *\n * EventLite.mixin(MyClass.prototype); // import event methods\n *\n * var obj = new MyClass();\n * obj.on(\"foo\", function() {...}); // add event listener\n * obj.once(\"bar\", function() {...}); // add one-time event listener\n * obj.emit(\"foo\"); // dispatch event\n * obj.emit(\"bar\"); // dispatch another event\n * obj.off(\"foo\"); // remove event listener\n */\n\nexport default function EventLite() {\n if (!(this instanceof EventLite)) return new EventLite();\n}\n\n// (function(EventLite) {\n // export the class for node.js\n // if (\"undefined\" !== typeof module) module.exports = EventLite;\n\n // property name to hold listeners\n var LISTENERS = \"listeners\";\n\n // methods to export\n var methods = {\n on: on,\n once: once,\n off: off,\n emit: emit\n };\n\n // mixin to self\n mixin(EventLite.prototype);\n\n // export mixin function\n EventLite.mixin = mixin;\n\n /**\n * Import on(), once(), off() and emit() methods into target object.\n *\n * @function EventLite.mixin\n * @param target {Prototype}\n */\n\n function mixin(target) {\n for (var key in methods) {\n target[key] = methods[key];\n }\n return target;\n }\n\n /**\n * Add an event listener.\n *\n * @function EventLite.prototype.on\n * @param type {string}\n * @param func {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function on(type, func) {\n getListeners(this, type).push(func);\n return this;\n }\n\n /**\n * Add one-time event listener.\n *\n * @function EventLite.prototype.once\n * @param type {string}\n * @param func {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function once(type, func) {\n var that = this;\n wrap.originalListener = func;\n getListeners(that, type).push(wrap);\n return that;\n\n function wrap() {\n off.call(that, type, wrap);\n func.apply(this, arguments);\n }\n }\n\n /**\n * Remove an event listener.\n *\n * @function EventLite.prototype.off\n * @param [type] {string}\n * @param [func] {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function off(type, func) {\n var that = this;\n var listners;\n if (!arguments.length) {\n delete that[LISTENERS];\n } else if (!func) {\n listners = that[LISTENERS];\n if (listners) {\n delete listners[type];\n if (!Object.keys(listners).length) return off.call(that);\n }\n } else {\n listners = getListeners(that, type, true);\n if (listners) {\n listners = listners.filter(ne);\n if (!listners.length) return off.call(that, type);\n that[LISTENERS][type] = listners;\n }\n }\n return that;\n\n function ne(test) {\n return test !== func && test.originalListener !== func;\n }\n }\n\n /**\n * Dispatch (trigger) an event.\n *\n * @function EventLite.prototype.emit\n * @param type {string}\n * @param [value] {*}\n * @returns {boolean} True when a listener received the event\n */\n\n function emit(type, value) {\n var that = this;\n var listeners = getListeners(that, type, true);\n if (!listeners) return false;\n var arglen = arguments.length;\n if (arglen === 1) {\n listeners.forEach(zeroarg);\n } else if (arglen === 2) {\n listeners.forEach(onearg);\n } else {\n var args = Array.prototype.slice.call(arguments, 1);\n listeners.forEach(moreargs);\n }\n return !!listeners.length;\n\n function zeroarg(func) {\n func.call(that);\n }\n\n function onearg(func) {\n func.call(that, value);\n }\n\n function moreargs(func) {\n func.apply(that, args);\n }\n }\n\n /**\n * @ignore\n */\n\n function getListeners(that, type, readonly) {\n if (readonly && !that[LISTENERS]) return;\n var listeners = that[LISTENERS] || (that[LISTENERS] = {});\n return listeners[type] || (listeners[type] = []);\n }\n\n// })(EventLite);\n","/* eslint-env browser */\n\nvar Events = require(\"event-lite\");\n\nvar INVALID_TAGS = {\n\ta: true,\n\tnoscript: true,\n\toption: true,\n\tscript: true,\n\tstyle: true,\n\ttextarea: true,\n\tsvg: true,\n\tcanvas: true,\n\tbutton: true,\n\tselect: true,\n\ttemplate: true,\n\tmeter: true,\n\tprogress: true,\n\tmath: true,\n\ttime: true\n};\n\nclass Pos {\n\tconstructor(container, offset, i = 0) {\n\t\tthis.container = container;\n\t\tthis.offset = offset;\n\t\tthis.i = i;\n\t}\n\t\n\tadd(change) {\n\t\tvar cont = this.container,\n\t\t\toffset = this.offset;\n\n\t\tthis.i += change;\n\t\t\n\t\t// If the container is #text.parentNode\n\t\tif (cont.childNodes.length) {\n\t\t\tcont = cont.childNodes[offset];\n\t\t\toffset = 0;\n\t\t}\n\n\t\t// If the container is #text\n\t\twhile (cont) {\n\t\t\tif (cont.nodeType == 3) {\n\t\t\t\tif (!cont.LEN) {\n\t\t\t\t\tcont.LEN = cont.nodeValue.length;\n\t\t\t\t}\n\t\t\t\tif (offset + change <= cont.LEN) {\n\t\t\t\t\tthis.container = cont;\n\t\t\t\t\tthis.offset = offset + change;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tchange = offset + change - cont.LEN;\n\t\t\t\toffset = 0;\n\t\t\t}\n\t\t\tcont = cont.nextSibling;\n\t\t}\n\t}\n\t\n\tmoveTo(offset) {\n\t\tthis.add(offset - this.i);\n\t}\n}\n\nfunction cloneContents(range) {\n\tif (range.startContainer == range.endContainer) {\n\t\treturn document.createTextNode(range.toString());\n\t}\n\treturn range.cloneContents();\n}\n\nvar DEFAULT_OPTIONS = {\n\tmaxRunTime: 100,\n\ttimeout: 10000,\n\tnewTab: true,\n\tnoOpener: true,\n\tembedImage: true,\n recursive: true,\n};\n\nclass Linkifier extends Events {\n\tconstructor(root, options = {}) {\n\t\tsuper();\n\t\tif (!(root instanceof Node)) {\n\t\t\toptions = root;\n\t\t\troot = options.root;\n\t\t}\n\t\tthis.root = root;\n\t\tthis.options = Object.assign({}, DEFAULT_OPTIONS, options);\n\t\tthis.aborted = false;\n\t}\n\tstart() {\n\t\tvar time = Date.now,\n\t\t\tstartTime = time(),\n\t\t\tchunks = this.generateChunks();\n\t\t\t\n\t\tvar next = () => {\n\t\t\tif (this.aborted) {\n\t\t\t\tthis.emit(\"error\", new Error(\"Aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar chunkStart = time(),\n\t\t\t\tnow;\n\t\t\t\t\n\t\t\tdo {\n\t\t\t\tif (chunks.next().done) {\n\t\t\t\t\tthis.emit(\"complete\", time() - startTime);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} while ((now = time()) - chunkStart < this.options.maxRunTime);\n\t\t\t\n\t\t\tif (now - startTime > this.options.timeout) {\n\t\t\t\tthis.emit(\"error\", new Error(`max execution time exceeded: ${now - startTime}, on ${this.root}`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tsetTimeout(next);\n\t\t};\n\t\t\t\n\t\tsetTimeout(next);\n\t}\n\tabort() {\n\t\tthis.aborted = true;\n\t}\n\t*generateRanges() {\n\t\tvar {validator, recursive} = this.options;\n\t\tvar filter = {\n\t\t\tacceptNode: function(node) {\n\t\t\t\tif (validator && !validator(node)) {\n\t\t\t\t\treturn NodeFilter.FILTER_REJECT;\n\t\t\t\t}\n\t\t\t\tif (INVALID_TAGS[node.localName]) {\n\t\t\t\t\treturn NodeFilter.FILTER_REJECT;\n\t\t\t\t}\n\t\t\t\tif (node.localName == \"wbr\") {\n\t\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t\t}\n\t\t\t\tif (node.nodeType == 3) {\n\t\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t\t}\n\t\t\t\treturn recursive ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_REJECT;\n\t\t\t}\n\t\t};\n\t\t// Generate linkified ranges.\n\t\tvar walker = document.createTreeWalker(\n\t\t\tthis.root,\n\t\t\tNodeFilter.SHOW_TEXT + NodeFilter.SHOW_ELEMENT,\n\t\t\tfilter\n\t\t), start, end, current, range;\n\n\t\tend = start = walker.nextNode();\n\t\tif (!start) {\n\t\t\treturn;\n\t\t}\n\t\trange = document.createRange();\n\t\trange.setStartBefore(start);\n\t\twhile ((current = walker.nextNode())) {\n\t\t\tif (end.nextSibling == current) {\n\t\t\t\tend = current;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trange.setEndAfter(end);\n\t\t\tyield range;\n\n\t\t\tend = start = current;\n\t\t\trange.setStartBefore(start);\n\t\t}\n\t\trange.setEndAfter(end);\n\t\tyield range;\n\t}\n\t*generateChunks() {\n\t\tvar {matcher} = this.options;\n\t\tfor (var range of this.generateRanges()) {\n\t\t\tvar frag = null,\n\t\t\t\tpos = null,\n\t\t\t\ttext = range.toString(),\n\t\t\t\ttextRange = null;\n\t\t\tfor (var result of matcher.match(text)) {\n\t\t\t\tif (!frag) {\n\t\t\t\t\tfrag = document.createDocumentFragment();\n\t\t\t\t\tpos = new Pos(range.startContainer, range.startOffset);\n\t\t\t\t\ttextRange = range.cloneRange();\n\t\t\t\t}\n\t\t\t\t// clone text\n\t\t\t\tpos.moveTo(result.start);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\tfrag.appendChild(cloneContents(textRange));\n\t\t\t\t\n\t\t\t\t// clone link\n\t\t\t\ttextRange.collapse();\n\t\t\t\tpos.moveTo(result.end);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\t\n\t\t\t\tvar content = cloneContents(textRange),\n\t\t\t\t\tlink = this.buildLink(result, content);\n\n\t\t\t\ttextRange.collapse();\n\n\t\t\t\tfrag.appendChild(link);\n\t\t\t\tthis.emit(\"link\", {link, range, result, content});\n\t\t\t}\n\t\t\tif (pos) {\n\t\t\t\tpos.moveTo(text.length);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\tfrag.appendChild(cloneContents(textRange));\n\t\t\t\t\n\t\t\t\trange.deleteContents();\n\t\t\t\trange.insertNode(frag);\n\t\t\t}\n\t\t\tyield;\n\t\t}\n\t}\n\tbuildLink(result, content) {\n\t\tvar {newTab, embedImage, noOpener} = this.options;\n\t\tvar link = document.createElement(\"a\");\n\t\tlink.href = result.url;\n\t\tlink.title = \"Linkify Plus Plus\";\n\t\tlink.className = \"linkifyplus\";\n\t\tif (newTab) {\n\t\t\tlink.target = \"_blank\";\n\t\t}\n\t\tif (noOpener) {\n\t\t\tlink.rel = \"noopener\";\n\t\t}\n\t\tvar child;\n\t\tif (embedImage && /^[^?#]+\\.(?:jpg|jpeg|png|apng|gif|svg|webp)(?:$|[?#])/i.test(result.url)) {\n\t\t\tchild = new Image;\n\t\t\tchild.src = result.url;\n\t\t\tchild.alt = result.text;\n\t\t} else {\n\t\t\tchild = content;\n\t\t}\n\t\tlink.appendChild(child);\n\t\treturn link;\n\t}\n}\n\nfunction linkify(...args) {\n\treturn new Promise((resolve, reject) => {\n\t\tvar linkifier = new Linkifier(...args);\n\t\tlinkifier.on(\"error\", reject);\n\t\tlinkifier.on(\"complete\", resolve);\n\t\tfor (var key of Object.keys(linkifier.options)) {\n\t\t\tif (key.startsWith(\"on\")) {\n\t\t\t\tlinkifier.on(key.slice(2), linkifier.options[key]);\n\t\t\t}\n\t\t}\n\t\tlinkifier.start();\n\t});\n}\n\nmodule.exports = {\n\tINVALID_TAGS,\n\tLinkifier,\n\tlinkify\n};\n"],"names":["tlds.chars","tlds.maxLength","tlds.table","Events"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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","x_google_ignoreList":[1]}
--------------------------------------------------------------------------------
/dist/linkify-plus-plus-core.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"linkify-plus-plus-core.js","sources":["../lib/url-matcher.js","../node_modules/event-lite/event-lite.mjs","../lib/linkifier.js"],"sourcesContent":["var tlds = require(\"./tlds.json\"),\n\tRE = {\n\t\tPROTOCOL: \"([a-z][-a-z*]+://)?\",\n\t\tUSER: \"(?:([\\\\w:.+-]+)@)?\",\n\t\tDOMAIN_UNI: `([a-z0-9-.\\\\u00A0-\\\\uFFFF]+\\\\.[a-z0-9-${tlds.chars}]{1,${tlds.maxLength}})`,\n\t\tDOMAIN: `([a-z0-9-.]+\\\\.[a-z0-9-]{1,${tlds.maxLength}})`,\n\t\tPORT: \"(:\\\\d+\\\\b)?\",\n\t\tPATH_UNI: \"([/?#]\\\\S*)?\",\n\t\tPATH: \"([/?#][\\\\w-.~!$&*+;=:@%/?#(),'\\\\[\\\\]]*)?\"\n\t},\n\tTLD_TABLE = tlds.table;\n\nfunction regexEscape(text) {\n\treturn text.replace(/[[\\]\\\\^-]/g, \"\\\\$&\");\n}\n\nfunction buildRegex({\n\tunicode = false, customRules = [], standalone = false,\n\tboundaryLeft, boundaryRight\n}) {\n\tvar pattern = RE.PROTOCOL + RE.USER;\n\t\n\tif (unicode) {\n\t\tpattern += RE.DOMAIN_UNI + RE.PORT + RE.PATH_UNI;\n\t} else {\n\t\tpattern += RE.DOMAIN + RE.PORT + RE.PATH;\n\t}\n\t\n\tif (customRules.length) {\n\t\tpattern = \"(?:(\" + customRules.join(\"|\") + \")|\" + pattern + \")\";\n\t} else {\n\t\tpattern = \"()\" + pattern;\n\t}\n\t\n\tvar prefix, suffix, invalidSuffix;\n\tif (standalone) {\n\t\tif (boundaryLeft) {\n\t\t\tprefix = \"((?:^|\\\\s)[\" + regexEscape(boundaryLeft) + \"]*?)\";\n\t\t} else {\n\t\t\tprefix = \"(^|\\\\s)\";\n\t\t}\n\t\tif (boundaryRight) {\n\t\t\tsuffix = \"([\" + regexEscape(boundaryRight) + \"]*(?:$|\\\\s))\";\n\t\t} else {\n\t\t\tsuffix = \"($|\\\\s)\";\n\t\t}\n\t\tinvalidSuffix = \"[^\\\\s\" + regexEscape(boundaryRight) + \"]\";\n\t} else {\n\t\tprefix = \"(^|\\\\b|_)\";\n\t\tsuffix = \"()\";\n\t}\n\t\n\tpattern = prefix + pattern + suffix;\n\t\n\treturn {\n\t\turl: new RegExp(pattern, \"igm\"),\n\t\tinvalidSuffix: invalidSuffix && new RegExp(invalidSuffix),\n\t\tmustache: /\\{\\{[\\s\\S]+?\\}\\}/g\n\t};\n}\n\nfunction pathStrip(m, re, repl) {\n\tvar s = m.path.replace(re, repl);\n\n\tif (s == m.path) return;\n\t\n\tm.end -= m.path.length - s.length;\n\tm.suffix = m.path.slice(s.length) + m.suffix;\n\tm.path = s;\n}\n\nfunction pathStripQuote(m, c) {\n\tvar i = 0, s = m.path, end, pos = 0;\n\t\n\tif (!s.endsWith(c)) return;\n\t\n\twhile ((pos = s.indexOf(c, pos)) >= 0) {\n\t\tif (i % 2) {\n\t\t\tend = null;\n\t\t} else {\n\t\t\tend = pos;\n\t\t}\n\t\tpos++;\n\t\ti++;\n\t}\n\t\n\tif (!end) return;\n\t\n\tm.end -= s.length - end;\n\tm.path = s.slice(0, end);\n\tm.suffix = s.slice(end) + m.suffix;\n}\n\nfunction pathStripBrace(m, left, right) {\n\tvar str = m.path,\n\t\tre = new RegExp(\"[\\\\\" + left + \"\\\\\" + right + \"]\", \"g\"),\n\t\tmatch, count = 0, end;\n\n\t// Match loop\n\twhile ((match = re.exec(str))) {\n\t\tif (count % 2 == 0) {\n\t\t\tend = match.index;\n\t\t\tif (match[0] == right) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (match[0] == left) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount++;\n\t}\n\n\tif (!match && count % 2 == 0) {\n\t\treturn;\n\t}\n\t\n\tm.end -= m.path.length - end;\n\tm.path = str.slice(0, end);\n\tm.suffix = str.slice(end) + m.suffix;\n}\n\nfunction isIP(s) {\n\tvar m, i;\n\tif (!(m = s.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/))) {\n\t\treturn false;\n\t}\n\tfor (i = 1; i < m.length; i++) {\n\t\tif (+m[i] > 255 || (m[i].length > 1 && m[i][0] == \"0\")) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction inTLDS(domain) {\n\tvar match = domain.match(/\\.([^.]+)$/);\n\tif (!match) {\n\t\treturn false;\n\t}\n\tvar key = match[1].toLowerCase();\n // eslint-disable-next-line no-prototype-builtins\n\treturn TLD_TABLE.hasOwnProperty(key);\n}\n\nclass UrlMatcher {\n\tconstructor(options = {}) {\n\t\tthis.options = options;\n\t\tthis.regex = buildRegex(options);\n\t}\n\t\n\t*match(text) {\n\t\tvar {\n\t\t\t\tfuzzyIp = true,\n\t\t\t\tignoreMustache = false,\n mail = true\n\t\t\t} = this.options,\n\t\t\t{\n\t\t\t\turl,\n\t\t\t\tinvalidSuffix,\n\t\t\t\tmustache\n\t\t\t} = this.regex,\n\t\t\turlLastIndex, mustacheLastIndex;\n\t\t\t\n\t\tmustache.lastIndex = 0;\n\t\turl.lastIndex = 0;\n\t\t\n\t\tvar mustacheMatch, mustacheRange;\n\t\tif (ignoreMustache) {\n\t\t\tmustacheMatch = mustache.exec(text);\n\t\t\tif (mustacheMatch) {\n\t\t\t\tmustacheRange = {\n\t\t\t\t\tstart: mustacheMatch.index,\n\t\t\t\t\tend: mustache.lastIndex\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t\n\t\tvar urlMatch;\n\t\twhile ((urlMatch = url.exec(text))) {\n const result = {\n start: 0,\n end: 0,\n \n text: \"\",\n url: \"\",\n \n prefix: urlMatch[1],\n custom: urlMatch[2],\n protocol: urlMatch[3],\n auth: urlMatch[4] || \"\",\n domain: urlMatch[5],\n port: urlMatch[6] || \"\",\n path: urlMatch[7] || \"\",\n suffix: urlMatch[8]\n };\n \n if (result.custom) {\n result.start = urlMatch.index;\n result.end = url.lastIndex;\n result.text = result.url = urlMatch[0];\n\t\t\t} else {\n \n result.start = urlMatch.index + result.prefix.length;\n result.end = url.lastIndex - result.suffix.length;\n\t\t\t}\n\t\t\t\n\t\t\tif (mustacheRange && mustacheRange.end <= result.start) {\n\t\t\t\tmustacheMatch = mustache.exec(text);\n\t\t\t\tif (mustacheMatch) {\n\t\t\t\t\tmustacheRange.start = mustacheMatch.index;\n\t\t\t\t\tmustacheRange.end = mustache.lastIndex;\n\t\t\t\t} else {\n\t\t\t\t\tmustacheRange = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// ignore urls inside mustache pair\n\t\t\tif (mustacheRange && result.start < mustacheRange.end && result.end >= mustacheRange.start) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\n\t\t\tif (!result.custom) {\n\t\t\t\t// adjust path and suffix\n\t\t\t\tif (result.path) {\n\t\t\t\t\t// Strip BBCode\n\t\t\t\t\tpathStrip(result, /\\[\\/?(b|i|u|url|img|quote|code|size|color)\\].*/i, \"\");\n\t\t\t\t\t\n\t\t\t\t\t// Strip braces\n\t\t\t\t\tpathStripBrace(result, \"(\", \")\");\n\t\t\t\t\tpathStripBrace(result, \"[\", \"]\");\n\t\t\t\t\tpathStripBrace(result, \"{\", \"}\");\n\t\t\t\t\t\n\t\t\t\t\t// Strip quotes\n\t\t\t\t\tpathStripQuote(result, \"'\");\n\t\t\t\t\tpathStripQuote(result, '\"');\n\t\t\t\t\t\n\t\t\t\t\t// Remove trailing \".,?\"\n\t\t\t\t\tpathStrip(result, /(^|[^-_])[.,?]+$/, \"$1\");\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// check suffix\n\t\t\t\tif (invalidSuffix && invalidSuffix.test(result.suffix)) {\n\t\t\t\t\tif (/\\s$/.test(result.suffix)) {\n\t\t\t\t\t\turl.lastIndex--;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n \n // ignore fuzzy ip\n\t\t\t\tif (!fuzzyIp && isIP(result.domain) &&\n !result.protocol && !result.auth && !result.path) {\n continue;\n }\n \n\t\t\t\t// mailto protocol\n\t\t\t\tif (!result.protocol && result.auth) {\n\t\t\t\t\tvar matchMail = result.auth.match(/^mailto:(.+)/);\n\t\t\t\t\tif (matchMail) {\n\t\t\t\t\t\tresult.protocol = \"mailto:\";\n\t\t\t\t\t\tresult.auth = matchMail[1];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// http alias\n\t\t\t\tif (result.protocol && result.protocol.match(/^(hxxp|h\\*\\*p|ttp)/)) {\n\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t}\n\n\t\t\t\t// guess protocol\n\t\t\t\tif (!result.protocol) {\n\t\t\t\t\tvar domainMatch;\n\t\t\t\t\tif ((domainMatch = result.domain.match(/^(ftp|irc)/))) {\n\t\t\t\t\t\tresult.protocol = domainMatch[0] + \"://\";\n\t\t\t\t\t} else if (result.domain.match(/^(www|web)/)) {\n\t\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t\t} else if (result.auth && result.auth.indexOf(\":\") < 0 && !result.path) {\n\t\t\t\t\t\tresult.protocol = \"mailto:\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t\t}\n\t\t\t\t}\n \n // ignore mail\n if (!mail && result.protocol === \"mailto:\") {\n continue;\n }\n \n\t\t\t\t// verify domain\n if (!isIP(result.domain)) {\n if (/^(http|https|mailto)/.test(result.protocol) && !inTLDS(result.domain)) {\n continue;\n }\n \n const invalidLabel = getInvalidLabel(result.domain);\n if (invalidLabel) {\n url.lastIndex = urlMatch.index + invalidLabel.index + 1;\n continue;\n }\n }\n\n\t\t\t\t// Create URL\n\t\t\t\tresult.url = result.protocol + (result.auth && result.auth + \"@\") + result.domain + result.port + result.path;\n\t\t\t\tresult.text = text.slice(result.start, result.end);\n\t\t\t}\n\t\t\t\n\t\t\t// since regex is shared with other parse generators, cache lastIndex position and restore later\n\t\t\tmustacheLastIndex = mustache.lastIndex;\n\t\t\turlLastIndex = url.lastIndex;\n\t\t\t\n\t\t\tyield result;\n\t\t\t\n\t\t\turl.lastIndex = urlLastIndex;\n\t\t\tmustache.lastIndex = mustacheLastIndex;\n\t\t}\n\t}\n}\n\nfunction getInvalidLabel(domain) {\n // https://tools.ietf.org/html/rfc1035\n // https://serverfault.com/questions/638260/is-it-valid-for-a-hostname-to-start-with-a-digit\n let index = 0;\n const parts = domain.split(\".\");\n for (const part of parts) {\n if (\n !part ||\n part.startsWith(\"-\") ||\n part.endsWith(\"-\")\n ) {\n return {\n index,\n value: part\n };\n }\n index += part.length + 1;\n }\n}\n\nmodule.exports = {\n\tUrlMatcher\n};\n","/**\n * event-lite.js - Light-weight EventEmitter (less than 1KB when gzipped)\n *\n * @copyright Yusuke Kawasaki\n * @license MIT\n * @constructor\n * @see https://github.com/kawanet/event-lite\n * @see http://kawanet.github.io/event-lite/EventLite.html\n * @example\n * var EventLite = require(\"event-lite\");\n *\n * function MyClass() {...} // your class\n *\n * EventLite.mixin(MyClass.prototype); // import event methods\n *\n * var obj = new MyClass();\n * obj.on(\"foo\", function() {...}); // add event listener\n * obj.once(\"bar\", function() {...}); // add one-time event listener\n * obj.emit(\"foo\"); // dispatch event\n * obj.emit(\"bar\"); // dispatch another event\n * obj.off(\"foo\"); // remove event listener\n */\n\nexport default function EventLite() {\n if (!(this instanceof EventLite)) return new EventLite();\n}\n\n// (function(EventLite) {\n // export the class for node.js\n // if (\"undefined\" !== typeof module) module.exports = EventLite;\n\n // property name to hold listeners\n var LISTENERS = \"listeners\";\n\n // methods to export\n var methods = {\n on: on,\n once: once,\n off: off,\n emit: emit\n };\n\n // mixin to self\n mixin(EventLite.prototype);\n\n // export mixin function\n EventLite.mixin = mixin;\n\n /**\n * Import on(), once(), off() and emit() methods into target object.\n *\n * @function EventLite.mixin\n * @param target {Prototype}\n */\n\n function mixin(target) {\n for (var key in methods) {\n target[key] = methods[key];\n }\n return target;\n }\n\n /**\n * Add an event listener.\n *\n * @function EventLite.prototype.on\n * @param type {string}\n * @param func {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function on(type, func) {\n getListeners(this, type).push(func);\n return this;\n }\n\n /**\n * Add one-time event listener.\n *\n * @function EventLite.prototype.once\n * @param type {string}\n * @param func {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function once(type, func) {\n var that = this;\n wrap.originalListener = func;\n getListeners(that, type).push(wrap);\n return that;\n\n function wrap() {\n off.call(that, type, wrap);\n func.apply(this, arguments);\n }\n }\n\n /**\n * Remove an event listener.\n *\n * @function EventLite.prototype.off\n * @param [type] {string}\n * @param [func] {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function off(type, func) {\n var that = this;\n var listners;\n if (!arguments.length) {\n delete that[LISTENERS];\n } else if (!func) {\n listners = that[LISTENERS];\n if (listners) {\n delete listners[type];\n if (!Object.keys(listners).length) return off.call(that);\n }\n } else {\n listners = getListeners(that, type, true);\n if (listners) {\n listners = listners.filter(ne);\n if (!listners.length) return off.call(that, type);\n that[LISTENERS][type] = listners;\n }\n }\n return that;\n\n function ne(test) {\n return test !== func && test.originalListener !== func;\n }\n }\n\n /**\n * Dispatch (trigger) an event.\n *\n * @function EventLite.prototype.emit\n * @param type {string}\n * @param [value] {*}\n * @returns {boolean} True when a listener received the event\n */\n\n function emit(type, value) {\n var that = this;\n var listeners = getListeners(that, type, true);\n if (!listeners) return false;\n var arglen = arguments.length;\n if (arglen === 1) {\n listeners.forEach(zeroarg);\n } else if (arglen === 2) {\n listeners.forEach(onearg);\n } else {\n var args = Array.prototype.slice.call(arguments, 1);\n listeners.forEach(moreargs);\n }\n return !!listeners.length;\n\n function zeroarg(func) {\n func.call(that);\n }\n\n function onearg(func) {\n func.call(that, value);\n }\n\n function moreargs(func) {\n func.apply(that, args);\n }\n }\n\n /**\n * @ignore\n */\n\n function getListeners(that, type, readonly) {\n if (readonly && !that[LISTENERS]) return;\n var listeners = that[LISTENERS] || (that[LISTENERS] = {});\n return listeners[type] || (listeners[type] = []);\n }\n\n// })(EventLite);\n","/* eslint-env browser */\n\nvar Events = require(\"event-lite\");\n\nvar INVALID_TAGS = {\n\ta: true,\n\tnoscript: true,\n\toption: true,\n\tscript: true,\n\tstyle: true,\n\ttextarea: true,\n\tsvg: true,\n\tcanvas: true,\n\tbutton: true,\n\tselect: true,\n\ttemplate: true,\n\tmeter: true,\n\tprogress: true,\n\tmath: true,\n\ttime: true\n};\n\nclass Pos {\n\tconstructor(container, offset, i = 0) {\n\t\tthis.container = container;\n\t\tthis.offset = offset;\n\t\tthis.i = i;\n\t}\n\t\n\tadd(change) {\n\t\tvar cont = this.container,\n\t\t\toffset = this.offset;\n\n\t\tthis.i += change;\n\t\t\n\t\t// If the container is #text.parentNode\n\t\tif (cont.childNodes.length) {\n\t\t\tcont = cont.childNodes[offset];\n\t\t\toffset = 0;\n\t\t}\n\n\t\t// If the container is #text\n\t\twhile (cont) {\n\t\t\tif (cont.nodeType == 3) {\n\t\t\t\tif (!cont.LEN) {\n\t\t\t\t\tcont.LEN = cont.nodeValue.length;\n\t\t\t\t}\n\t\t\t\tif (offset + change <= cont.LEN) {\n\t\t\t\t\tthis.container = cont;\n\t\t\t\t\tthis.offset = offset + change;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tchange = offset + change - cont.LEN;\n\t\t\t\toffset = 0;\n\t\t\t}\n\t\t\tcont = cont.nextSibling;\n\t\t}\n\t}\n\t\n\tmoveTo(offset) {\n\t\tthis.add(offset - this.i);\n\t}\n}\n\nfunction cloneContents(range) {\n\tif (range.startContainer == range.endContainer) {\n\t\treturn document.createTextNode(range.toString());\n\t}\n\treturn range.cloneContents();\n}\n\nvar DEFAULT_OPTIONS = {\n\tmaxRunTime: 100,\n\ttimeout: 10000,\n\tnewTab: true,\n\tnoOpener: true,\n\tembedImage: true,\n recursive: true,\n};\n\nclass Linkifier extends Events {\n\tconstructor(root, options = {}) {\n\t\tsuper();\n\t\tif (!(root instanceof Node)) {\n\t\t\toptions = root;\n\t\t\troot = options.root;\n\t\t}\n\t\tthis.root = root;\n\t\tthis.options = Object.assign({}, DEFAULT_OPTIONS, options);\n\t\tthis.aborted = false;\n\t}\n\tstart() {\n\t\tvar time = Date.now,\n\t\t\tstartTime = time(),\n\t\t\tchunks = this.generateChunks();\n\t\t\t\n\t\tvar next = () => {\n\t\t\tif (this.aborted) {\n\t\t\t\tthis.emit(\"error\", new Error(\"Aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar chunkStart = time(),\n\t\t\t\tnow;\n\t\t\t\t\n\t\t\tdo {\n\t\t\t\tif (chunks.next().done) {\n\t\t\t\t\tthis.emit(\"complete\", time() - startTime);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} while ((now = time()) - chunkStart < this.options.maxRunTime);\n\t\t\t\n\t\t\tif (now - startTime > this.options.timeout) {\n\t\t\t\tthis.emit(\"error\", new Error(`max execution time exceeded: ${now - startTime}, on ${this.root}`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tsetTimeout(next);\n\t\t};\n\t\t\t\n\t\tsetTimeout(next);\n\t}\n\tabort() {\n\t\tthis.aborted = true;\n\t}\n\t*generateRanges() {\n\t\tvar {validator, recursive} = this.options;\n\t\tvar filter = {\n\t\t\tacceptNode: function(node) {\n\t\t\t\tif (validator && !validator(node)) {\n\t\t\t\t\treturn NodeFilter.FILTER_REJECT;\n\t\t\t\t}\n\t\t\t\tif (INVALID_TAGS[node.localName]) {\n\t\t\t\t\treturn NodeFilter.FILTER_REJECT;\n\t\t\t\t}\n\t\t\t\tif (node.localName == \"wbr\") {\n\t\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t\t}\n\t\t\t\tif (node.nodeType == 3) {\n\t\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t\t}\n\t\t\t\treturn recursive ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_REJECT;\n\t\t\t}\n\t\t};\n\t\t// Generate linkified ranges.\n\t\tvar walker = document.createTreeWalker(\n\t\t\tthis.root,\n\t\t\tNodeFilter.SHOW_TEXT + NodeFilter.SHOW_ELEMENT,\n\t\t\tfilter\n\t\t), start, end, current, range;\n\n\t\tend = start = walker.nextNode();\n\t\tif (!start) {\n\t\t\treturn;\n\t\t}\n\t\trange = document.createRange();\n\t\trange.setStartBefore(start);\n\t\twhile ((current = walker.nextNode())) {\n\t\t\tif (end.nextSibling == current) {\n\t\t\t\tend = current;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trange.setEndAfter(end);\n\t\t\tyield range;\n\n\t\t\tend = start = current;\n\t\t\trange.setStartBefore(start);\n\t\t}\n\t\trange.setEndAfter(end);\n\t\tyield range;\n\t}\n\t*generateChunks() {\n\t\tvar {matcher} = this.options;\n\t\tfor (var range of this.generateRanges()) {\n\t\t\tvar frag = null,\n\t\t\t\tpos = null,\n\t\t\t\ttext = range.toString(),\n\t\t\t\ttextRange = null;\n\t\t\tfor (var result of matcher.match(text)) {\n\t\t\t\tif (!frag) {\n\t\t\t\t\tfrag = document.createDocumentFragment();\n\t\t\t\t\tpos = new Pos(range.startContainer, range.startOffset);\n\t\t\t\t\ttextRange = range.cloneRange();\n\t\t\t\t}\n\t\t\t\t// clone text\n\t\t\t\tpos.moveTo(result.start);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\tfrag.appendChild(cloneContents(textRange));\n\t\t\t\t\n\t\t\t\t// clone link\n\t\t\t\ttextRange.collapse();\n\t\t\t\tpos.moveTo(result.end);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\t\n\t\t\t\tvar content = cloneContents(textRange),\n\t\t\t\t\tlink = this.buildLink(result, content);\n\n\t\t\t\ttextRange.collapse();\n\n\t\t\t\tfrag.appendChild(link);\n\t\t\t\tthis.emit(\"link\", {link, range, result, content});\n\t\t\t}\n\t\t\tif (pos) {\n\t\t\t\tpos.moveTo(text.length);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\tfrag.appendChild(cloneContents(textRange));\n\t\t\t\t\n\t\t\t\trange.deleteContents();\n\t\t\t\trange.insertNode(frag);\n\t\t\t}\n\t\t\tyield;\n\t\t}\n\t}\n\tbuildLink(result, content) {\n\t\tvar {newTab, embedImage, noOpener} = this.options;\n\t\tvar link = document.createElement(\"a\");\n\t\tlink.href = result.url;\n\t\tlink.title = \"Linkify Plus Plus\";\n\t\tlink.className = \"linkifyplus\";\n\t\tif (newTab) {\n\t\t\tlink.target = \"_blank\";\n\t\t}\n\t\tif (noOpener) {\n\t\t\tlink.rel = \"noopener\";\n\t\t}\n\t\tvar child;\n\t\tif (embedImage && /^[^?#]+\\.(?:jpg|jpeg|png|apng|gif|svg|webp)(?:$|[?#])/i.test(result.url)) {\n\t\t\tchild = new Image;\n\t\t\tchild.src = result.url;\n\t\t\tchild.alt = result.text;\n\t\t} else {\n\t\t\tchild = content;\n\t\t}\n\t\tlink.appendChild(child);\n\t\treturn link;\n\t}\n}\n\nfunction linkify(...args) {\n\treturn new Promise((resolve, reject) => {\n\t\tvar linkifier = new Linkifier(...args);\n\t\tlinkifier.on(\"error\", reject);\n\t\tlinkifier.on(\"complete\", resolve);\n\t\tfor (var key of Object.keys(linkifier.options)) {\n\t\t\tif (key.startsWith(\"on\")) {\n\t\t\t\tlinkifier.on(key.slice(2), linkifier.options[key]);\n\t\t\t}\n\t\t}\n\t\tlinkifier.start();\n\t});\n}\n\nmodule.exports = {\n\tINVALID_TAGS,\n\tLinkifier,\n\tlinkify\n};\n"],"names":["tlds.chars","tlds.maxLength","tlds.table","Events"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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","x_google_ignoreList":[1]}
--------------------------------------------------------------------------------
/dist/linkify-plus-plus-core.min.js:
--------------------------------------------------------------------------------
1 | var linkifyPlusPlusCore=function(e){"use strict";var t="(:\\d+\\b)?",a={aaa:!0,aarp:!0,abb:!0,abbott:!0,abbvie:!0,abc:!0,able:!0,abogado:!0,abudhabi:!0,ac:!0,academy:!0,accountant:!0,accountants:!0,aco:!0,actor:!0,ad:!0,adult:!0,ae:!0,aeg:!0,aero:!0,aetna:!0,af:!0,afl:!0,africa:!0,ag:!0,agency:!0,ai:!0,aig:!0,airbus:!0,airforce:!0,akdn:!0,al:!0,allfinanz:!0,allstate:!0,ally:!0,alsace:!0,alstom:!0,am:!0,amazon:!0,americanexpress:!0,amex:!0,amfam:!0,amica:!0,amsterdam:!0,analytics:!0,android:!0,anz:!0,ao:!0,apartments:!0,app:!0,apple:!0,aq:!0,aquarelle:!0,ar:!0,archi:!0,army:!0,arpa:!0,art:!0,arte:!0,as:!0,asia:!0,associates:!0,at:!0,attorney:!0,au:!0,auction:!0,audi:!0,audio:!0,auspost:!0,auto:!0,autos:!0,aw:!0,aws:!0,ax:!0,axa:!0,az:!0,azure:!0,ba:!0,baby:!0,band:!0,bank:!0,bar:!0,barcelona:!0,barclaycard:!0,barclays:!0,bargains:!0,basketball:!0,bauhaus:!0,bayern:!0,bb:!0,bbc:!0,bbva:!0,bcn:!0,bd:!0,be:!0,beauty:!0,beer:!0,bentley:!0,berlin:!0,best:!0,bet:!0,bf:!0,bg:!0,bh:!0,bi:!0,bible:!0,bid:!0,bike:!0,bing:!0,bingo:!0,bio:!0,biz:!0,bj:!0,black:!0,blackfriday:!0,blog:!0,bloomberg:!0,blue:!0,bm:!0,bmw:!0,bn:!0,bnpparibas:!0,bo:!0,boats:!0,bond:!0,boo:!0,bostik:!0,boston:!0,bot:!0,boutique:!0,box:!0,br:!0,bradesco:!0,bridgestone:!0,broadway:!0,broker:!0,brother:!0,brussels:!0,bs:!0,bt:!0,build:!0,builders:!0,business:!0,buzz:!0,bw:!0,by:!0,bz:!0,bzh:!0,ca:!0,cab:!0,cafe:!0,cam:!0,camera:!0,camp:!0,canon:!0,capetown:!0,capital:!0,car:!0,cards:!0,care:!0,career:!0,careers:!0,cars:!0,casa:!0,case:!0,cash:!0,casino:!0,cat:!0,catering:!0,catholic:!0,cba:!0,cbn:!0,cc:!0,cd:!0,center:!0,ceo:!0,cern:!0,cf:!0,cfa:!0,cfd:!0,cg:!0,ch:!0,chanel:!0,channel:!0,charity:!0,chase:!0,chat:!0,cheap:!0,chintai:!0,christmas:!0,church:!0,ci:!0,cisco:!0,citi:!0,citic:!0,city:!0,ck:!0,cl:!0,claims:!0,cleaning:!0,click:!0,clinic:!0,clothing:!0,cloud:!0,club:!0,clubmed:!0,cm:!0,cn:!0,co:!0,coach:!0,codes:!0,coffee:!0,college:!0,cologne:!0,com:!0,commbank:!0,community:!0,company:!0,compare:!0,computer:!0,condos:!0,construction:!0,consulting:!0,contact:!0,contractors:!0,cooking:!0,cool:!0,coop:!0,corsica:!0,country:!0,coupons:!0,courses:!0,cpa:!0,cr:!0,credit:!0,creditcard:!0,creditunion:!0,cricket:!0,crown:!0,crs:!0,cruises:!0,cu:!0,cuisinella:!0,cv:!0,cw:!0,cx:!0,cy:!0,cymru:!0,cyou:!0,cz:!0,dad:!0,dance:!0,date:!0,dating:!0,day:!0,de:!0,deal:!0,dealer:!0,deals:!0,degree:!0,delivery:!0,dell:!0,deloitte:!0,democrat:!0,dental:!0,dentist:!0,desi:!0,design:!0,dev:!0,dhl:!0,diamonds:!0,diet:!0,digital:!0,direct:!0,directory:!0,discount:!0,discover:!0,diy:!0,dj:!0,dk:!0,dm:!0,do:!0,doctor:!0,dog:!0,domains:!0,download:!0,dubai:!0,dupont:!0,durban:!0,dvag:!0,dz:!0,earth:!0,ec:!0,eco:!0,edeka:!0,edu:!0,education:!0,ee:!0,eg:!0,email:!0,emerck:!0,energy:!0,engineer:!0,engineering:!0,enterprises:!0,equipment:!0,er:!0,ericsson:!0,erni:!0,es:!0,esq:!0,estate:!0,et:!0,eu:!0,eurovision:!0,eus:!0,events:!0,exchange:!0,expert:!0,exposed:!0,express:!0,extraspace:!0,fage:!0,fail:!0,fairwinds:!0,faith:!0,family:!0,fan:!0,fans:!0,farm:!0,fashion:!0,feedback:!0,ferrero:!0,fi:!0,film:!0,finance:!0,financial:!0,firmdale:!0,fish:!0,fishing:!0,fit:!0,fitness:!0,fj:!0,fk:!0,flickr:!0,flights:!0,flir:!0,florist:!0,flowers:!0,fm:!0,fo:!0,foo:!0,food:!0,football:!0,ford:!0,forex:!0,forsale:!0,forum:!0,foundation:!0,fox:!0,fr:!0,fresenius:!0,frl:!0,frogans:!0,fujitsu:!0,fun:!0,fund:!0,furniture:!0,futbol:!0,fyi:!0,ga:!0,gal:!0,gallery:!0,game:!0,games:!0,garden:!0,gay:!0,gd:!0,gdn:!0,ge:!0,gea:!0,gent:!0,genting:!0,gf:!0,gg:!0,gh:!0,gi:!0,gift:!0,gifts:!0,gives:!0,giving:!0,gl:!0,glass:!0,gle:!0,global:!0,globo:!0,gm:!0,gmail:!0,gmbh:!0,gmo:!0,gmx:!0,gn:!0,godaddy:!0,gold:!0,golf:!0,goog:!0,google:!0,gop:!0,gov:!0,gp:!0,gq:!0,gr:!0,grainger:!0,graphics:!0,gratis:!0,green:!0,gripe:!0,group:!0,gs:!0,gt:!0,gu:!0,gucci:!0,guide:!0,guitars:!0,guru:!0,gw:!0,gy:!0,hair:!0,hamburg:!0,haus:!0,health:!0,healthcare:!0,help:!0,helsinki:!0,here:!0,hermes:!0,hiphop:!0,hisamitsu:!0,hitachi:!0,hiv:!0,hk:!0,hm:!0,hn:!0,hockey:!0,holdings:!0,holiday:!0,homes:!0,honda:!0,horse:!0,hospital:!0,host:!0,hosting:!0,hotmail:!0,house:!0,how:!0,hr:!0,hsbc:!0,ht:!0,hu:!0,hyatt:!0,hyundai:!0,ice:!0,icu:!0,id:!0,ie:!0,ieee:!0,ifm:!0,ikano:!0,il:!0,im:!0,imamat:!0,immo:!0,immobilien:!0,in:!0,inc:!0,industries:!0,info:!0,ing:!0,ink:!0,institute:!0,insurance:!0,insure:!0,int:!0,international:!0,investments:!0,io:!0,ipiranga:!0,iq:!0,ir:!0,irish:!0,is:!0,ismaili:!0,ist:!0,istanbul:!0,it:!0,itau:!0,itv:!0,jaguar:!0,java:!0,jcb:!0,je:!0,jetzt:!0,jewelry:!0,jio:!0,jll:!0,jm:!0,jmp:!0,jnj:!0,jo:!0,jobs:!0,joburg:!0,jp:!0,jpmorgan:!0,jprs:!0,juegos:!0,kaufen:!0,ke:!0,kfh:!0,kg:!0,kh:!0,ki:!0,kia:!0,kids:!0,kim:!0,kitchen:!0,kiwi:!0,km:!0,kn:!0,koeln:!0,komatsu:!0,kp:!0,kpmg:!0,kpn:!0,kr:!0,krd:!0,kred:!0,kw:!0,ky:!0,kyoto:!0,kz:!0,la:!0,lamborghini:!0,lancaster:!0,land:!0,landrover:!0,lanxess:!0,lat:!0,latrobe:!0,law:!0,lawyer:!0,lb:!0,lc:!0,lease:!0,leclerc:!0,legal:!0,lexus:!0,lgbt:!0,li:!0,lidl:!0,life:!0,lifestyle:!0,lighting:!0,lilly:!0,limited:!0,limo:!0,lincoln:!0,link:!0,live:!0,living:!0,lk:!0,llc:!0,loan:!0,loans:!0,locker:!0,locus:!0,lol:!0,london:!0,lotto:!0,love:!0,lr:!0,ls:!0,lt:!0,ltd:!0,ltda:!0,lu:!0,lundbeck:!0,luxe:!0,luxury:!0,lv:!0,ly:!0,ma:!0,madrid:!0,maif:!0,maison:!0,makeup:!0,man:!0,management:!0,mango:!0,market:!0,marketing:!0,markets:!0,marriott:!0,mattel:!0,mba:!0,mc:!0,md:!0,me:!0,med:!0,media:!0,meet:!0,melbourne:!0,meme:!0,memorial:!0,men:!0,menu:!0,mg:!0,mh:!0,miami:!0,microsoft:!0,mil:!0,mini:!0,mit:!0,mk:!0,ml:!0,mlb:!0,mm:!0,mma:!0,mn:!0,mo:!0,mobi:!0,moda:!0,moe:!0,moi:!0,mom:!0,monash:!0,money:!0,monster:!0,mortgage:!0,moscow:!0,motorcycles:!0,mov:!0,movie:!0,mp:!0,mq:!0,mr:!0,ms:!0,mt:!0,mtn:!0,mtr:!0,mu:!0,museum:!0,music:!0,mv:!0,mw:!0,mx:!0,my:!0,mz:!0,na:!0,nab:!0,nagoya:!0,name:!0,navy:!0,nc:!0,ne:!0,nec:!0,net:!0,netbank:!0,network:!0,neustar:!0,new:!0,news:!0,next:!0,nexus:!0,nf:!0,ng:!0,ngo:!0,nhk:!0,ni:!0,nico:!0,nike:!0,ninja:!0,nissan:!0,nl:!0,no:!0,nokia:!0,now:!0,nowruz:!0,np:!0,nr:!0,nra:!0,nrw:!0,ntt:!0,nu:!0,nyc:!0,nz:!0,observer:!0,office:!0,okinawa:!0,om:!0,omega:!0,one:!0,ong:!0,onl:!0,online:!0,ooo:!0,oracle:!0,orange:!0,org:!0,organic:!0,osaka:!0,otsuka:!0,ovh:!0,pa:!0,page:!0,panasonic:!0,paris:!0,partners:!0,parts:!0,party:!0,pe:!0,pet:!0,pf:!0,pfizer:!0,pg:!0,ph:!0,pharmacy:!0,phd:!0,philips:!0,photo:!0,photography:!0,photos:!0,physio:!0,pics:!0,pictet:!0,pictures:!0,ping:!0,pink:!0,pioneer:!0,pizza:!0,pk:!0,pl:!0,place:!0,play:!0,plumbing:!0,plus:!0,pm:!0,pn:!0,pohl:!0,poker:!0,politie:!0,porn:!0,post:!0,pr:!0,praxi:!0,press:!0,prime:!0,pro:!0,productions:!0,prof:!0,promo:!0,properties:!0,property:!0,protection:!0,pru:!0,prudential:!0,ps:!0,pt:!0,pub:!0,pw:!0,pwc:!0,py:!0,qa:!0,qpon:!0,quebec:!0,quest:!0,racing:!0,radio:!0,re:!0,realestate:!0,realtor:!0,realty:!0,recipes:!0,red:!0,redstone:!0,rehab:!0,reise:!0,reisen:!0,reit:!0,ren:!0,rent:!0,rentals:!0,repair:!0,report:!0,republican:!0,rest:!0,restaurant:!0,review:!0,reviews:!0,rexroth:!0,rich:!0,ricoh:!0,rio:!0,rip:!0,ro:!0,rocks:!0,rodeo:!0,rogers:!0,rs:!0,rsvp:!0,ru:!0,rugby:!0,ruhr:!0,run:!0,rw:!0,ryukyu:!0,sa:!0,saarland:!0,sale:!0,salon:!0,samsung:!0,sandvik:!0,sandvikcoromant:!0,sanofi:!0,sap:!0,sarl:!0,saxo:!0,sb:!0,sbi:!0,sbs:!0,sc:!0,scb:!0,schaeffler:!0,schmidt:!0,school:!0,schule:!0,schwarz:!0,science:!0,scot:!0,sd:!0,se:!0,seat:!0,security:!0,select:!0,sener:!0,services:!0,seven:!0,sew:!0,sex:!0,sexy:!0,sfr:!0,sg:!0,sh:!0,sharp:!0,shell:!0,shiksha:!0,shoes:!0,shop:!0,shopping:!0,show:!0,si:!0,singles:!0,site:!0,sk:!0,ski:!0,skin:!0,sky:!0,skype:!0,sl:!0,sm:!0,smart:!0,sn:!0,sncf:!0,so:!0,soccer:!0,social:!0,softbank:!0,software:!0,sohu:!0,solar:!0,solutions:!0,sony:!0,soy:!0,spa:!0,space:!0,sport:!0,sr:!0,srl:!0,ss:!0,st:!0,stada:!0,statebank:!0,statefarm:!0,stc:!0,stockholm:!0,storage:!0,store:!0,stream:!0,studio:!0,study:!0,style:!0,su:!0,sucks:!0,supplies:!0,supply:!0,support:!0,surf:!0,surgery:!0,suzuki:!0,sv:!0,swatch:!0,swiss:!0,sx:!0,sy:!0,sydney:!0,systems:!0,sz:!0,taipei:!0,target:!0,tatamotors:!0,tatar:!0,tattoo:!0,tax:!0,taxi:!0,tc:!0,td:!0,team:!0,tech:!0,technology:!0,tel:!0,temasek:!0,tennis:!0,teva:!0,tf:!0,tg:!0,th:!0,theater:!0,theatre:!0,tickets:!0,tienda:!0,tips:!0,tires:!0,tirol:!0,tj:!0,tk:!0,tl:!0,tm:!0,tn:!0,to:!0,today:!0,tokyo:!0,tools:!0,top:!0,toray:!0,toshiba:!0,total:!0,tours:!0,town:!0,toyota:!0,toys:!0,tr:!0,trade:!0,trading:!0,training:!0,travel:!0,travelers:!0,trust:!0,tt:!0,tube:!0,tui:!0,tv:!0,tvs:!0,tw:!0,tz:!0,ua:!0,ug:!0,uk:!0,unicom:!0,university:!0,uno:!0,uol:!0,us:!0,uy:!0,uz:!0,va:!0,vacations:!0,vana:!0,vanguard:!0,vc:!0,ve:!0,vegas:!0,ventures:!0,versicherung:!0,vet:!0,vg:!0,vi:!0,viajes:!0,video:!0,vig:!0,villas:!0,vin:!0,vip:!0,vision:!0,vivo:!0,vlaanderen:!0,vn:!0,vodka:!0,vote:!0,voting:!0,voto:!0,voyage:!0,vu:!0,wales:!0,walter:!0,wang:!0,watch:!0,watches:!0,webcam:!0,weber:!0,website:!0,wed:!0,wedding:!0,weir:!0,wf:!0,whoswho:!0,wien:!0,wiki:!0,williamhill:!0,win:!0,windows:!0,wine:!0,wme:!0,woodside:!0,work:!0,works:!0,world:!0,ws:!0,wtf:!0,xbox:!0,xin:!0,"xn--1ck2e1b":!0,"xn--1qqw23a":!0,"xn--2scrj9c":!0,"xn--3bst00m":!0,"xn--3ds443g":!0,"xn--3e0b707e":!0,"xn--3hcrj9c":!0,"xn--45br5cyl":!0,"xn--45brj9c":!0,"xn--45q11c":!0,"xn--4dbrk0ce":!0,"xn--4gbrim":!0,"xn--54b7fta0cc":!0,"xn--55qx5d":!0,"xn--5tzm5g":!0,"xn--6frz82g":!0,"xn--6qq986b3xl":!0,"xn--80adxhks":!0,"xn--80ao21a":!0,"xn--80asehdb":!0,"xn--80aswg":!0,"xn--8y0a063a":!0,"xn--90a3ac":!0,"xn--90ae":!0,"xn--90ais":!0,"xn--9dbq2a":!0,"xn--bck1b9a5dre4c":!0,"xn--c1avg":!0,"xn--cck2b3b":!0,"xn--clchc0ea0b2g2a9gcd":!0,"xn--czr694b":!0,"xn--czrs0t":!0,"xn--czru2d":!0,"xn--d1acj3b":!0,"xn--d1alf":!0,"xn--e1a4c":!0,"xn--fct429k":!0,"xn--fiq228c5hs":!0,"xn--fiq64b":!0,"xn--fiqs8s":!0,"xn--fiqz9s":!0,"xn--fjq720a":!0,"xn--fpcrj9c3d":!0,"xn--fzc2c9e2c":!0,"xn--g2xx48c":!0,"xn--gckr3f0f":!0,"xn--gecrj9c":!0,"xn--h2breg3eve":!0,"xn--h2brj9c":!0,"xn--h2brj9c8c":!0,"xn--hxt814e":!0,"xn--i1b6b1a6a2e":!0,"xn--imr513n":!0,"xn--io0a7i":!0,"xn--j1amh":!0,"xn--j6w193g":!0,"xn--jvr189m":!0,"xn--kcrx77d1x4a":!0,"xn--kprw13d":!0,"xn--kpry57d":!0,"xn--kput3i":!0,"xn--l1acc":!0,"xn--lgbbat1ad8j":!0,"xn--mgb9awbf":!0,"xn--mgba3a4f16a":!0,"xn--mgbaam7a8h":!0,"xn--mgbab2bd":!0,"xn--mgbah1a3hjkrd":!0,"xn--mgbai9azgqp6j":!0,"xn--mgbayh7gpa":!0,"xn--mgbbh1a":!0,"xn--mgbc0a9azcg":!0,"xn--mgbca7dzdo":!0,"xn--mgbcpq6gpa1a":!0,"xn--mgberp4a5d4ar":!0,"xn--mgbgu82a":!0,"xn--mgbpl2fh":!0,"xn--mgbtx2b":!0,"xn--mix891f":!0,"xn--mk1bu44c":!0,"xn--ngbc5azd":!0,"xn--ngbe9e0a":!0,"xn--node":!0,"xn--nqv7f":!0,"xn--nyqy26a":!0,"xn--o3cw4h":!0,"xn--ogbpf8fl":!0,"xn--otu796d":!0,"xn--p1acf":!0,"xn--p1ai":!0,"xn--pgbs0dh":!0,"xn--q7ce6a":!0,"xn--q9jyb4c":!0,"xn--qxa6a":!0,"xn--qxam":!0,"xn--rhqv96g":!0,"xn--rovu88b":!0,"xn--rvc1e0am3e":!0,"xn--s9brj9c":!0,"xn--ses554g":!0,"xn--t60b56a":!0,"xn--tckwe":!0,"xn--unup4y":!0,"xn--vermgensberatung-pwb":!0,"xn--vhquv":!0,"xn--vuq861b":!0,"xn--wgbh1c":!0,"xn--wgbl6a":!0,"xn--xhq521b":!0,"xn--xkc2al3hye2a":!0,"xn--xkc2dl3a5ee0h":!0,"xn--y9a3aq":!0,"xn--yfro4i67o":!0,"xn--ygbi2ammx":!0,"xn--zfr164b":!0,xxx:!0,xyz:!0,yachts:!0,yahoo:!0,yandex:!0,ye:!0,yodobashi:!0,yoga:!0,yokohama:!0,youtube:!0,yt:!0,za:!0,zappos:!0,zara:!0,zip:!0,zm:!0,zone:!0,zuerich:!0,zw:!0,"セール":!0,"佛山":!0,"ಭಾರತ":!0,"集团":!0,"在线":!0,"한국":!0,"ଭାରତ":!0,"ভাৰত":!0,"ভারত":!0,"八卦":!0,"ישראל":!0,"موقع":!0,"বাংলা":!0,"公司":!0,"网站":!0,"移动":!0,"我爱你":!0,"москва":!0,"қаз":!0,"онлайн":!0,"сайт":!0,"联通":!0,"срб":!0,"бг":!0,"бел":!0,"קום":!0,"ファッション":!0,"орг":!0,"ストア":!0,"சிங்கப்பூர்":!0,"商标":!0,"商店":!0,"商城":!0,"дети":!0,"мкд":!0,"ею":!0,"家電":!0,"中文网":!0,"中信":!0,"中国":!0,"中國":!0,"娱乐":!0,"భారత్":!0,"ලංකා":!0,"购物":!0,"クラウド":!0,"ભારત":!0,"भारतम्":!0,"भारत":!0,"भारोत":!0,"网店":!0,"संगठन":!0,"餐厅":!0,"网络":!0,"укр":!0,"香港":!0,"食品":!0,"飞利浦":!0,"台湾":!0,"台灣":!0,"手机":!0,"мон":!0,"الجزائر":!0,"عمان":!0,"ایران":!0,"امارات":!0,"بازار":!0,"موريتانيا":!0,"پاکستان":!0,"الاردن":!0,"بارت":!0,"المغرب":!0,"ابوظبي":!0,"البحرين":!0,"السعودية":!0,"ڀارت":!0,"سودان":!0,"عراق":!0,"澳門":!0,"닷컴":!0,"شبكة":!0,"بيتك":!0,"გე":!0,"机构":!0,"健康":!0,"ไทย":!0,"سورية":!0,"招聘":!0,"рус":!0,"рф":!0,"تونس":!0,"ລາວ":!0,"みんな":!0,"ευ":!0,"ελ":!0,"世界":!0,"書籍":!0,"ഭാരതം":!0,"ਭਾਰਤ":!0,"网址":!0,"닷넷":!0,"コム":!0,"游戏":!0,"vermögensberatung":!0,"企业":!0,"信息":!0,"مصر":!0,"قطر":!0,"广东":!0,"இலங்கை":!0,"இந்தியா":!0,"հայ":!0,"新加坡":!0,"فلسطين":!0,"政务":!0,onion:!0};function n(e){return e.replace(/[[\]\\^-]/g,"\\$&")}function i(e,t,a){var n=e.path.replace(t,a);n!=e.path&&(e.end-=e.path.length-n.length,e.suffix=e.path.slice(n.length)+e.suffix,e.path=n)}function o(e,t){var a,n=0,i=e.path,o=0;if(i.endsWith(t)){for(;(o=i.indexOf(t,o))>=0;)a=n%2?null:o,o++,n++;a&&(e.end-=i.length-a,e.path=i.slice(0,a),e.suffix=i.slice(a)+e.suffix)}}function r(e,t,a){for(var n,i,o=e.path,r=new RegExp("[\\"+t+"\\"+a+"]","g"),s=0;n=r.exec(o);){if(s%2==0){if(i=n.index,n[0]==a)break}else if(n[0]==t)break;s++}(n||s%2!=0)&&(e.end-=e.path.length-i,e.path=o.slice(0,i),e.suffix=o.slice(i)+e.suffix)}function s(e){var t,a;if(!(t=e.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)))return!1;for(a=1;a255||t[a].length>1&&"0"==t[a][0])return!1;return!0}function c(e){var t=e.match(/\.([^.]+)$/);if(!t)return!1;var n=t[1].toLowerCase();return a.hasOwnProperty(n)}function l(e){let t=0;const a=e.split(".");for(const e of a){if(!e||e.startsWith("-")||e.endsWith("-"))return{index:t,value:e};t+=e.length+1}}
2 | /**
3 | * event-lite.js - Light-weight EventEmitter (less than 1KB when gzipped)
4 | *
5 | * @copyright Yusuke Kawasaki
6 | * @license MIT
7 | * @constructor
8 | * @see https://github.com/kawanet/event-lite
9 | * @see http://kawanet.github.io/event-lite/EventLite.html
10 | * @example
11 | * var EventLite = require("event-lite");
12 | *
13 | * function MyClass() {...} // your class
14 | *
15 | * EventLite.mixin(MyClass.prototype); // import event methods
16 | *
17 | * var obj = new MyClass();
18 | * obj.on("foo", function() {...}); // add event listener
19 | * obj.once("bar", function() {...}); // add one-time event listener
20 | * obj.emit("foo"); // dispatch event
21 | * obj.emit("bar"); // dispatch another event
22 | * obj.off("foo"); // remove event listener
23 | */function u(){if(!(this instanceof u))return new u}var d="listeners",m={on:function(e,t){return p(this,e).push(t),this},once:function(e,t){var a=this;return n.originalListener=t,p(a,e).push(n),a;function n(){g.call(a,e,n),t.apply(this,arguments)}},off:g,emit:function(e,t){var a=this,n=p(a,e,!0);if(!n)return!1;var i=arguments.length;if(1===i)n.forEach((function(e){e.call(a)}));else if(2===i)n.forEach((function(e){e.call(a,t)}));else{var o=Array.prototype.slice.call(arguments,1);n.forEach((function(e){e.apply(a,o)}))}return!!n.length}};function h(e){for(var t in m)e[t]=m[t];return e}function g(e,t){var a,n=this;if(arguments.length){if(t){if(a=p(n,e,!0)){if(!(a=a.filter((function(e){return e!==t&&e.originalListener!==t}))).length)return g.call(n,e);n[d][e]=a}}else if((a=n[d])&&(delete a[e],!Object.keys(a).length))return g.call(n)}else delete n[d];return n}function p(e,t,a){if(!a||e[d]){var n=e[d]||(e[d]={});return n[t]||(n[t]=[])}}h(u.prototype),u.mixin=h;var f={a:!0,noscript:!0,option:!0,script:!0,style:!0,textarea:!0,svg:!0,canvas:!0,button:!0,select:!0,template:!0,meter:!0,progress:!0,math:!0,time:!0};class b{constructor(e,t,a=0){this.container=e,this.offset=t,this.i=a}add(e){var t=this.container,a=this.offset;for(this.i+=e,t.childNodes.length&&(t=t.childNodes[a],a=0);t;){if(3==t.nodeType){if(t.LEN||(t.LEN=t.nodeValue.length),a+e<=t.LEN)return this.container=t,void(this.offset=a+e);e=a+e-t.LEN,a=0}t=t.nextSibling}}moveTo(e){this.add(e-this.i)}}function x(e){return e.startContainer==e.endContainer?document.createTextNode(e.toString()):e.cloneContents()}var v={maxRunTime:100,timeout:1e4,newTab:!0,noOpener:!0,embedImage:!0,recursive:!0};class y extends u{constructor(e,t={}){super(),e instanceof Node||(e=(t=e).root),this.root=e,this.options=Object.assign({},v,t),this.aborted=!1}start(){var e=Date.now,t=e(),a=this.generateChunks(),n=()=>{if(this.aborted)this.emit("error",new Error("Aborted"));else{var i,o=e();do{if(a.next().done)return void this.emit("complete",e()-t)}while((i=e())-othis.options.timeout?this.emit("error",new Error(`max execution time exceeded: ${i-t}, on ${this.root}`)):setTimeout(n)}};setTimeout(n)}abort(){this.aborted=!0}*generateRanges(){var e,t,a,n,{validator:i,recursive:o}=this.options,r={acceptNode:function(e){return i&&!i(e)||f[e.localName]?NodeFilter.FILTER_REJECT:"wbr"==e.localName||3==e.nodeType?NodeFilter.FILTER_ACCEPT:o?NodeFilter.FILTER_SKIP:NodeFilter.FILTER_REJECT}},s=document.createTreeWalker(this.root,NodeFilter.SHOW_TEXT+NodeFilter.SHOW_ELEMENT,r);if(t=e=s.nextNode(),e){for((n=document.createRange()).setStartBefore(e);a=s.nextNode();)t.nextSibling!=a?(n.setEndAfter(t),yield n,t=e=a,n.setStartBefore(e)):t=a;n.setEndAfter(t),yield n}}*generateChunks(){var{matcher:e}=this.options;for(var t of this.generateRanges()){var a=null,n=null,i=t.toString(),o=null;for(var r of e.match(i)){a||(a=document.createDocumentFragment(),n=new b(t.startContainer,t.startOffset),o=t.cloneRange()),n.moveTo(r.start),o.setEnd(n.container,n.offset),a.appendChild(x(o)),o.collapse(),n.moveTo(r.end),o.setEnd(n.container,n.offset);var s=x(o),c=this.buildLink(r,s);o.collapse(),a.appendChild(c),this.emit("link",{link:c,range:t,result:r,content:s})}n&&(n.moveTo(i.length),o.setEnd(n.container,n.offset),a.appendChild(x(o)),t.deleteContents(),t.insertNode(a)),yield}}buildLink(e,t){var a,{newTab:n,embedImage:i,noOpener:o}=this.options,r=document.createElement("a");return r.href=e.url,r.title="Linkify Plus Plus",r.className="linkifyplus",n&&(r.target="_blank"),o&&(r.rel="noopener"),i&&/^[^?#]+\.(?:jpg|jpeg|png|apng|gif|svg|webp)(?:$|[?#])/i.test(e.url)?((a=new Image).src=e.url,a.alt=e.text):a=t,r.appendChild(a),r}}return e.INVALID_TAGS=f,e.Linkifier=y,e.UrlMatcher=class{constructor(e={}){this.options=e,this.regex=function({unicode:e=!1,customRules:a=[],standalone:i=!1,boundaryLeft:o,boundaryRight:r}){var s,c,l,u="([a-z][-a-z*]+://)?(?:([\\w:.+-]+)@)?";return u+=e?"([a-z0-9-.\\u00A0-\\uFFFF]+\\.[a-z0-9-セール佛山ಭಾರತ集团在线한국ଭାରତভাৰতর八卦ישראלموقعবংল公司网站移动我爱你москвақзнлйт联通рбгеקוםファッションストアசிங்கபூர商标店城дию家電中文信国國娱乐భారత్ලංකා购物クラウドભારતभारतम्ोसंगठन餐厅络у香港食品飞利浦台湾灣手机الجزئرنیتبيپکسدغظحةڀ澳門닷컴شكგე构健康ไทย招聘фລາວみんなευλ世界書籍ഭാരതംਭਾਰਤ址넷コム游戏ö企业息صط广东இலைநதயாհայ新加坡ف政务]{1,24})"+t+"([/?#]\\S*)?":"([a-z0-9-.]+\\.[a-z0-9-]{1,24})"+t+"([/?#][\\w-.~!$&*+;=:@%/?#(),'\\[\\]]*)?",u=a.length?"(?:("+a.join("|")+")|"+u+")":"()"+u,i?(s=o?"((?:^|\\s)["+n(o)+"]*?)":"(^|\\s)",c=r?"(["+n(r)+"]*(?:$|\\s))":"($|\\s)",l="[^\\s"+n(r)+"]"):(s="(^|\\b|_)",c="()"),u=s+u+c,{url:new RegExp(u,"igm"),invalidSuffix:l&&new RegExp(l),mustache:/\{\{[\s\S]+?\}\}/g}}(e)}*match(e){var t,a,n,u,d,{fuzzyIp:m=!0,ignoreMustache:h=!1,mail:g=!0}=this.options,{url:p,invalidSuffix:f,mustache:b}=this.regex;for(b.lastIndex=0,p.lastIndex=0,h&&(n=b.exec(e))&&(u={start:n.index,end:b.lastIndex});d=p.exec(e);){const h={start:0,end:0,text:"",url:"",prefix:d[1],custom:d[2],protocol:d[3],auth:d[4]||"",domain:d[5],port:d[6]||"",path:d[7]||"",suffix:d[8]};if(h.custom?(h.start=d.index,h.end=p.lastIndex,h.text=h.url=d[0]):(h.start=d.index+h.prefix.length,h.end=p.lastIndex-h.suffix.length),u&&u.end<=h.start&&((n=b.exec(e))?(u.start=n.index,u.end=b.lastIndex):u=null),!(u&&h.start=u.start)){if(!h.custom){if(h.path&&(i(h,/\[\/?(b|i|u|url|img|quote|code|size|color)\].*/i,""),r(h,"(",")"),r(h,"[","]"),r(h,"{","}"),o(h,"'"),o(h,'"'),i(h,/(^|[^-_])[.,?]+$/,"$1")),f&&f.test(h.suffix)){/\s$/.test(h.suffix)&&p.lastIndex--;continue}if(!m&&s(h.domain)&&!h.protocol&&!h.auth&&!h.path)continue;if(!h.protocol&&h.auth){var x=h.auth.match(/^mailto:(.+)/);x&&(h.protocol="mailto:",h.auth=x[1])}var v;if(h.protocol&&h.protocol.match(/^(hxxp|h\*\*p|ttp)/)&&(h.protocol="http://"),h.protocol||((v=h.domain.match(/^(ftp|irc)/))?h.protocol=v[0]+"://":h.domain.match(/^(www|web)/)?h.protocol="http://":h.auth&&h.auth.indexOf(":")<0&&!h.path?h.protocol="mailto:":h.protocol="http://"),!g&&"mailto:"===h.protocol)continue;if(!s(h.domain)){if(/^(http|https|mailto)/.test(h.protocol)&&!c(h.domain))continue;const e=l(h.domain);if(e){p.lastIndex=d.index+e.index+1;continue}}h.url=h.protocol+(h.auth&&h.auth+"@")+h.domain+h.port+h.path,h.text=e.slice(h.start,h.end)}a=b.lastIndex,t=p.lastIndex,yield h,p.lastIndex=t,b.lastIndex=a}}}},e.linkify=function(...e){return new Promise(((t,a)=>{var n=new y(...e);for(var i of(n.on("error",a),n.on("complete",t),Object.keys(n.options)))i.startsWith("on")&&n.on(i.slice(2),n.options[i]);n.start()}))},e}({});
24 | //# sourceMappingURL=linkify-plus-plus-core.min.js.map
25 |
--------------------------------------------------------------------------------
/dist/linkify-plus-plus-core.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"linkify-plus-plus-core.min.js","sources":["../lib/url-matcher.js","../node_modules/event-lite/event-lite.mjs","../lib/linkifier.js"],"sourcesContent":["var tlds = require(\"./tlds.json\"),\n\tRE = {\n\t\tPROTOCOL: \"([a-z][-a-z*]+://)?\",\n\t\tUSER: \"(?:([\\\\w:.+-]+)@)?\",\n\t\tDOMAIN_UNI: `([a-z0-9-.\\\\u00A0-\\\\uFFFF]+\\\\.[a-z0-9-${tlds.chars}]{1,${tlds.maxLength}})`,\n\t\tDOMAIN: `([a-z0-9-.]+\\\\.[a-z0-9-]{1,${tlds.maxLength}})`,\n\t\tPORT: \"(:\\\\d+\\\\b)?\",\n\t\tPATH_UNI: \"([/?#]\\\\S*)?\",\n\t\tPATH: \"([/?#][\\\\w-.~!$&*+;=:@%/?#(),'\\\\[\\\\]]*)?\"\n\t},\n\tTLD_TABLE = tlds.table;\n\nfunction regexEscape(text) {\n\treturn text.replace(/[[\\]\\\\^-]/g, \"\\\\$&\");\n}\n\nfunction buildRegex({\n\tunicode = false, customRules = [], standalone = false,\n\tboundaryLeft, boundaryRight\n}) {\n\tvar pattern = RE.PROTOCOL + RE.USER;\n\t\n\tif (unicode) {\n\t\tpattern += RE.DOMAIN_UNI + RE.PORT + RE.PATH_UNI;\n\t} else {\n\t\tpattern += RE.DOMAIN + RE.PORT + RE.PATH;\n\t}\n\t\n\tif (customRules.length) {\n\t\tpattern = \"(?:(\" + customRules.join(\"|\") + \")|\" + pattern + \")\";\n\t} else {\n\t\tpattern = \"()\" + pattern;\n\t}\n\t\n\tvar prefix, suffix, invalidSuffix;\n\tif (standalone) {\n\t\tif (boundaryLeft) {\n\t\t\tprefix = \"((?:^|\\\\s)[\" + regexEscape(boundaryLeft) + \"]*?)\";\n\t\t} else {\n\t\t\tprefix = \"(^|\\\\s)\";\n\t\t}\n\t\tif (boundaryRight) {\n\t\t\tsuffix = \"([\" + regexEscape(boundaryRight) + \"]*(?:$|\\\\s))\";\n\t\t} else {\n\t\t\tsuffix = \"($|\\\\s)\";\n\t\t}\n\t\tinvalidSuffix = \"[^\\\\s\" + regexEscape(boundaryRight) + \"]\";\n\t} else {\n\t\tprefix = \"(^|\\\\b|_)\";\n\t\tsuffix = \"()\";\n\t}\n\t\n\tpattern = prefix + pattern + suffix;\n\t\n\treturn {\n\t\turl: new RegExp(pattern, \"igm\"),\n\t\tinvalidSuffix: invalidSuffix && new RegExp(invalidSuffix),\n\t\tmustache: /\\{\\{[\\s\\S]+?\\}\\}/g\n\t};\n}\n\nfunction pathStrip(m, re, repl) {\n\tvar s = m.path.replace(re, repl);\n\n\tif (s == m.path) return;\n\t\n\tm.end -= m.path.length - s.length;\n\tm.suffix = m.path.slice(s.length) + m.suffix;\n\tm.path = s;\n}\n\nfunction pathStripQuote(m, c) {\n\tvar i = 0, s = m.path, end, pos = 0;\n\t\n\tif (!s.endsWith(c)) return;\n\t\n\twhile ((pos = s.indexOf(c, pos)) >= 0) {\n\t\tif (i % 2) {\n\t\t\tend = null;\n\t\t} else {\n\t\t\tend = pos;\n\t\t}\n\t\tpos++;\n\t\ti++;\n\t}\n\t\n\tif (!end) return;\n\t\n\tm.end -= s.length - end;\n\tm.path = s.slice(0, end);\n\tm.suffix = s.slice(end) + m.suffix;\n}\n\nfunction pathStripBrace(m, left, right) {\n\tvar str = m.path,\n\t\tre = new RegExp(\"[\\\\\" + left + \"\\\\\" + right + \"]\", \"g\"),\n\t\tmatch, count = 0, end;\n\n\t// Match loop\n\twhile ((match = re.exec(str))) {\n\t\tif (count % 2 == 0) {\n\t\t\tend = match.index;\n\t\t\tif (match[0] == right) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (match[0] == left) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount++;\n\t}\n\n\tif (!match && count % 2 == 0) {\n\t\treturn;\n\t}\n\t\n\tm.end -= m.path.length - end;\n\tm.path = str.slice(0, end);\n\tm.suffix = str.slice(end) + m.suffix;\n}\n\nfunction isIP(s) {\n\tvar m, i;\n\tif (!(m = s.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/))) {\n\t\treturn false;\n\t}\n\tfor (i = 1; i < m.length; i++) {\n\t\tif (+m[i] > 255 || (m[i].length > 1 && m[i][0] == \"0\")) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction inTLDS(domain) {\n\tvar match = domain.match(/\\.([^.]+)$/);\n\tif (!match) {\n\t\treturn false;\n\t}\n\tvar key = match[1].toLowerCase();\n // eslint-disable-next-line no-prototype-builtins\n\treturn TLD_TABLE.hasOwnProperty(key);\n}\n\nclass UrlMatcher {\n\tconstructor(options = {}) {\n\t\tthis.options = options;\n\t\tthis.regex = buildRegex(options);\n\t}\n\t\n\t*match(text) {\n\t\tvar {\n\t\t\t\tfuzzyIp = true,\n\t\t\t\tignoreMustache = false,\n mail = true\n\t\t\t} = this.options,\n\t\t\t{\n\t\t\t\turl,\n\t\t\t\tinvalidSuffix,\n\t\t\t\tmustache\n\t\t\t} = this.regex,\n\t\t\turlLastIndex, mustacheLastIndex;\n\t\t\t\n\t\tmustache.lastIndex = 0;\n\t\turl.lastIndex = 0;\n\t\t\n\t\tvar mustacheMatch, mustacheRange;\n\t\tif (ignoreMustache) {\n\t\t\tmustacheMatch = mustache.exec(text);\n\t\t\tif (mustacheMatch) {\n\t\t\t\tmustacheRange = {\n\t\t\t\t\tstart: mustacheMatch.index,\n\t\t\t\t\tend: mustache.lastIndex\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t\n\t\tvar urlMatch;\n\t\twhile ((urlMatch = url.exec(text))) {\n const result = {\n start: 0,\n end: 0,\n \n text: \"\",\n url: \"\",\n \n prefix: urlMatch[1],\n custom: urlMatch[2],\n protocol: urlMatch[3],\n auth: urlMatch[4] || \"\",\n domain: urlMatch[5],\n port: urlMatch[6] || \"\",\n path: urlMatch[7] || \"\",\n suffix: urlMatch[8]\n };\n \n if (result.custom) {\n result.start = urlMatch.index;\n result.end = url.lastIndex;\n result.text = result.url = urlMatch[0];\n\t\t\t} else {\n \n result.start = urlMatch.index + result.prefix.length;\n result.end = url.lastIndex - result.suffix.length;\n\t\t\t}\n\t\t\t\n\t\t\tif (mustacheRange && mustacheRange.end <= result.start) {\n\t\t\t\tmustacheMatch = mustache.exec(text);\n\t\t\t\tif (mustacheMatch) {\n\t\t\t\t\tmustacheRange.start = mustacheMatch.index;\n\t\t\t\t\tmustacheRange.end = mustache.lastIndex;\n\t\t\t\t} else {\n\t\t\t\t\tmustacheRange = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// ignore urls inside mustache pair\n\t\t\tif (mustacheRange && result.start < mustacheRange.end && result.end >= mustacheRange.start) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\n\t\t\tif (!result.custom) {\n\t\t\t\t// adjust path and suffix\n\t\t\t\tif (result.path) {\n\t\t\t\t\t// Strip BBCode\n\t\t\t\t\tpathStrip(result, /\\[\\/?(b|i|u|url|img|quote|code|size|color)\\].*/i, \"\");\n\t\t\t\t\t\n\t\t\t\t\t// Strip braces\n\t\t\t\t\tpathStripBrace(result, \"(\", \")\");\n\t\t\t\t\tpathStripBrace(result, \"[\", \"]\");\n\t\t\t\t\tpathStripBrace(result, \"{\", \"}\");\n\t\t\t\t\t\n\t\t\t\t\t// Strip quotes\n\t\t\t\t\tpathStripQuote(result, \"'\");\n\t\t\t\t\tpathStripQuote(result, '\"');\n\t\t\t\t\t\n\t\t\t\t\t// Remove trailing \".,?\"\n\t\t\t\t\tpathStrip(result, /(^|[^-_])[.,?]+$/, \"$1\");\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// check suffix\n\t\t\t\tif (invalidSuffix && invalidSuffix.test(result.suffix)) {\n\t\t\t\t\tif (/\\s$/.test(result.suffix)) {\n\t\t\t\t\t\turl.lastIndex--;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n \n // ignore fuzzy ip\n\t\t\t\tif (!fuzzyIp && isIP(result.domain) &&\n !result.protocol && !result.auth && !result.path) {\n continue;\n }\n \n\t\t\t\t// mailto protocol\n\t\t\t\tif (!result.protocol && result.auth) {\n\t\t\t\t\tvar matchMail = result.auth.match(/^mailto:(.+)/);\n\t\t\t\t\tif (matchMail) {\n\t\t\t\t\t\tresult.protocol = \"mailto:\";\n\t\t\t\t\t\tresult.auth = matchMail[1];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// http alias\n\t\t\t\tif (result.protocol && result.protocol.match(/^(hxxp|h\\*\\*p|ttp)/)) {\n\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t}\n\n\t\t\t\t// guess protocol\n\t\t\t\tif (!result.protocol) {\n\t\t\t\t\tvar domainMatch;\n\t\t\t\t\tif ((domainMatch = result.domain.match(/^(ftp|irc)/))) {\n\t\t\t\t\t\tresult.protocol = domainMatch[0] + \"://\";\n\t\t\t\t\t} else if (result.domain.match(/^(www|web)/)) {\n\t\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t\t} else if (result.auth && result.auth.indexOf(\":\") < 0 && !result.path) {\n\t\t\t\t\t\tresult.protocol = \"mailto:\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult.protocol = \"http://\";\n\t\t\t\t\t}\n\t\t\t\t}\n \n // ignore mail\n if (!mail && result.protocol === \"mailto:\") {\n continue;\n }\n \n\t\t\t\t// verify domain\n if (!isIP(result.domain)) {\n if (/^(http|https|mailto)/.test(result.protocol) && !inTLDS(result.domain)) {\n continue;\n }\n \n const invalidLabel = getInvalidLabel(result.domain);\n if (invalidLabel) {\n url.lastIndex = urlMatch.index + invalidLabel.index + 1;\n continue;\n }\n }\n\n\t\t\t\t// Create URL\n\t\t\t\tresult.url = result.protocol + (result.auth && result.auth + \"@\") + result.domain + result.port + result.path;\n\t\t\t\tresult.text = text.slice(result.start, result.end);\n\t\t\t}\n\t\t\t\n\t\t\t// since regex is shared with other parse generators, cache lastIndex position and restore later\n\t\t\tmustacheLastIndex = mustache.lastIndex;\n\t\t\turlLastIndex = url.lastIndex;\n\t\t\t\n\t\t\tyield result;\n\t\t\t\n\t\t\turl.lastIndex = urlLastIndex;\n\t\t\tmustache.lastIndex = mustacheLastIndex;\n\t\t}\n\t}\n}\n\nfunction getInvalidLabel(domain) {\n // https://tools.ietf.org/html/rfc1035\n // https://serverfault.com/questions/638260/is-it-valid-for-a-hostname-to-start-with-a-digit\n let index = 0;\n const parts = domain.split(\".\");\n for (const part of parts) {\n if (\n !part ||\n part.startsWith(\"-\") ||\n part.endsWith(\"-\")\n ) {\n return {\n index,\n value: part\n };\n }\n index += part.length + 1;\n }\n}\n\nmodule.exports = {\n\tUrlMatcher\n};\n","/**\n * event-lite.js - Light-weight EventEmitter (less than 1KB when gzipped)\n *\n * @copyright Yusuke Kawasaki\n * @license MIT\n * @constructor\n * @see https://github.com/kawanet/event-lite\n * @see http://kawanet.github.io/event-lite/EventLite.html\n * @example\n * var EventLite = require(\"event-lite\");\n *\n * function MyClass() {...} // your class\n *\n * EventLite.mixin(MyClass.prototype); // import event methods\n *\n * var obj = new MyClass();\n * obj.on(\"foo\", function() {...}); // add event listener\n * obj.once(\"bar\", function() {...}); // add one-time event listener\n * obj.emit(\"foo\"); // dispatch event\n * obj.emit(\"bar\"); // dispatch another event\n * obj.off(\"foo\"); // remove event listener\n */\n\nexport default function EventLite() {\n if (!(this instanceof EventLite)) return new EventLite();\n}\n\n// (function(EventLite) {\n // export the class for node.js\n // if (\"undefined\" !== typeof module) module.exports = EventLite;\n\n // property name to hold listeners\n var LISTENERS = \"listeners\";\n\n // methods to export\n var methods = {\n on: on,\n once: once,\n off: off,\n emit: emit\n };\n\n // mixin to self\n mixin(EventLite.prototype);\n\n // export mixin function\n EventLite.mixin = mixin;\n\n /**\n * Import on(), once(), off() and emit() methods into target object.\n *\n * @function EventLite.mixin\n * @param target {Prototype}\n */\n\n function mixin(target) {\n for (var key in methods) {\n target[key] = methods[key];\n }\n return target;\n }\n\n /**\n * Add an event listener.\n *\n * @function EventLite.prototype.on\n * @param type {string}\n * @param func {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function on(type, func) {\n getListeners(this, type).push(func);\n return this;\n }\n\n /**\n * Add one-time event listener.\n *\n * @function EventLite.prototype.once\n * @param type {string}\n * @param func {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function once(type, func) {\n var that = this;\n wrap.originalListener = func;\n getListeners(that, type).push(wrap);\n return that;\n\n function wrap() {\n off.call(that, type, wrap);\n func.apply(this, arguments);\n }\n }\n\n /**\n * Remove an event listener.\n *\n * @function EventLite.prototype.off\n * @param [type] {string}\n * @param [func] {Function}\n * @returns {EventLite} Self for method chaining\n */\n\n function off(type, func) {\n var that = this;\n var listners;\n if (!arguments.length) {\n delete that[LISTENERS];\n } else if (!func) {\n listners = that[LISTENERS];\n if (listners) {\n delete listners[type];\n if (!Object.keys(listners).length) return off.call(that);\n }\n } else {\n listners = getListeners(that, type, true);\n if (listners) {\n listners = listners.filter(ne);\n if (!listners.length) return off.call(that, type);\n that[LISTENERS][type] = listners;\n }\n }\n return that;\n\n function ne(test) {\n return test !== func && test.originalListener !== func;\n }\n }\n\n /**\n * Dispatch (trigger) an event.\n *\n * @function EventLite.prototype.emit\n * @param type {string}\n * @param [value] {*}\n * @returns {boolean} True when a listener received the event\n */\n\n function emit(type, value) {\n var that = this;\n var listeners = getListeners(that, type, true);\n if (!listeners) return false;\n var arglen = arguments.length;\n if (arglen === 1) {\n listeners.forEach(zeroarg);\n } else if (arglen === 2) {\n listeners.forEach(onearg);\n } else {\n var args = Array.prototype.slice.call(arguments, 1);\n listeners.forEach(moreargs);\n }\n return !!listeners.length;\n\n function zeroarg(func) {\n func.call(that);\n }\n\n function onearg(func) {\n func.call(that, value);\n }\n\n function moreargs(func) {\n func.apply(that, args);\n }\n }\n\n /**\n * @ignore\n */\n\n function getListeners(that, type, readonly) {\n if (readonly && !that[LISTENERS]) return;\n var listeners = that[LISTENERS] || (that[LISTENERS] = {});\n return listeners[type] || (listeners[type] = []);\n }\n\n// })(EventLite);\n","/* eslint-env browser */\n\nvar Events = require(\"event-lite\");\n\nvar INVALID_TAGS = {\n\ta: true,\n\tnoscript: true,\n\toption: true,\n\tscript: true,\n\tstyle: true,\n\ttextarea: true,\n\tsvg: true,\n\tcanvas: true,\n\tbutton: true,\n\tselect: true,\n\ttemplate: true,\n\tmeter: true,\n\tprogress: true,\n\tmath: true,\n\ttime: true\n};\n\nclass Pos {\n\tconstructor(container, offset, i = 0) {\n\t\tthis.container = container;\n\t\tthis.offset = offset;\n\t\tthis.i = i;\n\t}\n\t\n\tadd(change) {\n\t\tvar cont = this.container,\n\t\t\toffset = this.offset;\n\n\t\tthis.i += change;\n\t\t\n\t\t// If the container is #text.parentNode\n\t\tif (cont.childNodes.length) {\n\t\t\tcont = cont.childNodes[offset];\n\t\t\toffset = 0;\n\t\t}\n\n\t\t// If the container is #text\n\t\twhile (cont) {\n\t\t\tif (cont.nodeType == 3) {\n\t\t\t\tif (!cont.LEN) {\n\t\t\t\t\tcont.LEN = cont.nodeValue.length;\n\t\t\t\t}\n\t\t\t\tif (offset + change <= cont.LEN) {\n\t\t\t\t\tthis.container = cont;\n\t\t\t\t\tthis.offset = offset + change;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tchange = offset + change - cont.LEN;\n\t\t\t\toffset = 0;\n\t\t\t}\n\t\t\tcont = cont.nextSibling;\n\t\t}\n\t}\n\t\n\tmoveTo(offset) {\n\t\tthis.add(offset - this.i);\n\t}\n}\n\nfunction cloneContents(range) {\n\tif (range.startContainer == range.endContainer) {\n\t\treturn document.createTextNode(range.toString());\n\t}\n\treturn range.cloneContents();\n}\n\nvar DEFAULT_OPTIONS = {\n\tmaxRunTime: 100,\n\ttimeout: 10000,\n\tnewTab: true,\n\tnoOpener: true,\n\tembedImage: true,\n recursive: true,\n};\n\nclass Linkifier extends Events {\n\tconstructor(root, options = {}) {\n\t\tsuper();\n\t\tif (!(root instanceof Node)) {\n\t\t\toptions = root;\n\t\t\troot = options.root;\n\t\t}\n\t\tthis.root = root;\n\t\tthis.options = Object.assign({}, DEFAULT_OPTIONS, options);\n\t\tthis.aborted = false;\n\t}\n\tstart() {\n\t\tvar time = Date.now,\n\t\t\tstartTime = time(),\n\t\t\tchunks = this.generateChunks();\n\t\t\t\n\t\tvar next = () => {\n\t\t\tif (this.aborted) {\n\t\t\t\tthis.emit(\"error\", new Error(\"Aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar chunkStart = time(),\n\t\t\t\tnow;\n\t\t\t\t\n\t\t\tdo {\n\t\t\t\tif (chunks.next().done) {\n\t\t\t\t\tthis.emit(\"complete\", time() - startTime);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} while ((now = time()) - chunkStart < this.options.maxRunTime);\n\t\t\t\n\t\t\tif (now - startTime > this.options.timeout) {\n\t\t\t\tthis.emit(\"error\", new Error(`max execution time exceeded: ${now - startTime}, on ${this.root}`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tsetTimeout(next);\n\t\t};\n\t\t\t\n\t\tsetTimeout(next);\n\t}\n\tabort() {\n\t\tthis.aborted = true;\n\t}\n\t*generateRanges() {\n\t\tvar {validator, recursive} = this.options;\n\t\tvar filter = {\n\t\t\tacceptNode: function(node) {\n\t\t\t\tif (validator && !validator(node)) {\n\t\t\t\t\treturn NodeFilter.FILTER_REJECT;\n\t\t\t\t}\n\t\t\t\tif (INVALID_TAGS[node.localName]) {\n\t\t\t\t\treturn NodeFilter.FILTER_REJECT;\n\t\t\t\t}\n\t\t\t\tif (node.localName == \"wbr\") {\n\t\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t\t}\n\t\t\t\tif (node.nodeType == 3) {\n\t\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t\t}\n\t\t\t\treturn recursive ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_REJECT;\n\t\t\t}\n\t\t};\n\t\t// Generate linkified ranges.\n\t\tvar walker = document.createTreeWalker(\n\t\t\tthis.root,\n\t\t\tNodeFilter.SHOW_TEXT + NodeFilter.SHOW_ELEMENT,\n\t\t\tfilter\n\t\t), start, end, current, range;\n\n\t\tend = start = walker.nextNode();\n\t\tif (!start) {\n\t\t\treturn;\n\t\t}\n\t\trange = document.createRange();\n\t\trange.setStartBefore(start);\n\t\twhile ((current = walker.nextNode())) {\n\t\t\tif (end.nextSibling == current) {\n\t\t\t\tend = current;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\trange.setEndAfter(end);\n\t\t\tyield range;\n\n\t\t\tend = start = current;\n\t\t\trange.setStartBefore(start);\n\t\t}\n\t\trange.setEndAfter(end);\n\t\tyield range;\n\t}\n\t*generateChunks() {\n\t\tvar {matcher} = this.options;\n\t\tfor (var range of this.generateRanges()) {\n\t\t\tvar frag = null,\n\t\t\t\tpos = null,\n\t\t\t\ttext = range.toString(),\n\t\t\t\ttextRange = null;\n\t\t\tfor (var result of matcher.match(text)) {\n\t\t\t\tif (!frag) {\n\t\t\t\t\tfrag = document.createDocumentFragment();\n\t\t\t\t\tpos = new Pos(range.startContainer, range.startOffset);\n\t\t\t\t\ttextRange = range.cloneRange();\n\t\t\t\t}\n\t\t\t\t// clone text\n\t\t\t\tpos.moveTo(result.start);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\tfrag.appendChild(cloneContents(textRange));\n\t\t\t\t\n\t\t\t\t// clone link\n\t\t\t\ttextRange.collapse();\n\t\t\t\tpos.moveTo(result.end);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\t\n\t\t\t\tvar content = cloneContents(textRange),\n\t\t\t\t\tlink = this.buildLink(result, content);\n\n\t\t\t\ttextRange.collapse();\n\n\t\t\t\tfrag.appendChild(link);\n\t\t\t\tthis.emit(\"link\", {link, range, result, content});\n\t\t\t}\n\t\t\tif (pos) {\n\t\t\t\tpos.moveTo(text.length);\n\t\t\t\ttextRange.setEnd(pos.container, pos.offset);\n\t\t\t\tfrag.appendChild(cloneContents(textRange));\n\t\t\t\t\n\t\t\t\trange.deleteContents();\n\t\t\t\trange.insertNode(frag);\n\t\t\t}\n\t\t\tyield;\n\t\t}\n\t}\n\tbuildLink(result, content) {\n\t\tvar {newTab, embedImage, noOpener} = this.options;\n\t\tvar link = document.createElement(\"a\");\n\t\tlink.href = result.url;\n\t\tlink.title = \"Linkify Plus Plus\";\n\t\tlink.className = \"linkifyplus\";\n\t\tif (newTab) {\n\t\t\tlink.target = \"_blank\";\n\t\t}\n\t\tif (noOpener) {\n\t\t\tlink.rel = \"noopener\";\n\t\t}\n\t\tvar child;\n\t\tif (embedImage && /^[^?#]+\\.(?:jpg|jpeg|png|apng|gif|svg|webp)(?:$|[?#])/i.test(result.url)) {\n\t\t\tchild = new Image;\n\t\t\tchild.src = result.url;\n\t\t\tchild.alt = result.text;\n\t\t} else {\n\t\t\tchild = content;\n\t\t}\n\t\tlink.appendChild(child);\n\t\treturn link;\n\t}\n}\n\nfunction linkify(...args) {\n\treturn new Promise((resolve, reject) => {\n\t\tvar linkifier = new Linkifier(...args);\n\t\tlinkifier.on(\"error\", reject);\n\t\tlinkifier.on(\"complete\", resolve);\n\t\tfor (var key of Object.keys(linkifier.options)) {\n\t\t\tif (key.startsWith(\"on\")) {\n\t\t\t\tlinkifier.on(key.slice(2), linkifier.options[key]);\n\t\t\t}\n\t\t}\n\t\tlinkifier.start();\n\t});\n}\n\nmodule.exports = {\n\tINVALID_TAGS,\n\tLinkifier,\n\tlinkify\n};\n"],"names":["RE","TLD_TABLE","regexEscape","text","replace","pathStrip","m","re","repl","s","path","end","length","suffix","slice","pathStripQuote","c","i","pos","endsWith","indexOf","pathStripBrace","left","right","match","str","RegExp","count","exec","index","isIP","inTLDS","domain","key","toLowerCase","hasOwnProperty","getInvalidLabel","parts","split","part","startsWith","value","EventLite","this","LISTENERS","methods","on","type","func","getListeners","push","once","that","wrap","originalListener","off","call","apply","arguments","emit","listeners","arglen","forEach","args","Array","prototype","mixin","target","listners","filter","test","Object","keys","readonly","INVALID_TAGS","a","noscript","option","script","style","textarea","svg","canvas","button","select","template","meter","progress","math","time","Pos","constructor","container","offset","add","change","cont","childNodes","nodeType","LEN","nodeValue","nextSibling","moveTo","cloneContents","range","startContainer","endContainer","document","createTextNode","toString","DEFAULT_OPTIONS","maxRunTime","timeout","newTab","noOpener","embedImage","recursive","Linkifier","Events","root","options","super","Node","assign","aborted","start","Date","now","startTime","chunks","generateChunks","next","Error","chunkStart","done","setTimeout","abort","generateRanges","current","validator","acceptNode","node","localName","NodeFilter","FILTER_REJECT","FILTER_ACCEPT","FILTER_SKIP","walker","createTreeWalker","SHOW_TEXT","SHOW_ELEMENT","nextNode","createRange","setStartBefore","setEndAfter","matcher","frag","textRange","result","createDocumentFragment","startOffset","cloneRange","setEnd","appendChild","collapse","content","link","buildLink","deleteContents","insertNode","child","createElement","href","url","title","className","rel","Image","src","alt","regex","unicode","customRules","standalone","boundaryLeft","boundaryRight","prefix","invalidSuffix","pattern","join","mustache","buildRegex","urlLastIndex","mustacheLastIndex","mustacheMatch","mustacheRange","urlMatch","fuzzyIp","ignoreMustache","mail","lastIndex","custom","protocol","auth","port","matchMail","domainMatch","invalidLabel","Promise","resolve","reject","linkifier"],"mappings":"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","x_google_ignoreList":[1]}
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import js from "@eslint/js";
2 | import globals from "globals";
3 | import compat from "eslint-plugin-compat";
4 |
5 | export default [
6 | {
7 | ignores: [
8 | "dist",
9 | "dist-extension",
10 | "**/__snapshots__/*.js"
11 | ]
12 | },
13 | js.configs.recommended,
14 | compat.configs["flat/recommended"],
15 | {
16 | "rules": {
17 | "dot-notation": 2,
18 | "max-statements-per-line": 2,
19 | },
20 | languageOptions: {
21 | globals: {
22 | ...globals.browser,
23 | ...globals.node,
24 | ...globals.mocha
25 | }
26 | }
27 | },
28 | ];
29 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var {UrlMatcher} = require("./lib/url-matcher"),
2 | {INVALID_TAGS, Linkifier, linkify} = require("./lib/linkifier");
3 |
4 | module.exports = {
5 | UrlMatcher,
6 | Linkifier,
7 | INVALID_TAGS,
8 | linkify
9 | };
10 |
--------------------------------------------------------------------------------
/lib/linkifier.js:
--------------------------------------------------------------------------------
1 | /* eslint-env browser */
2 |
3 | var Events = require("event-lite");
4 |
5 | var INVALID_TAGS = {
6 | a: true,
7 | noscript: true,
8 | option: true,
9 | script: true,
10 | style: true,
11 | textarea: true,
12 | svg: true,
13 | canvas: true,
14 | button: true,
15 | select: true,
16 | template: true,
17 | meter: true,
18 | progress: true,
19 | math: true,
20 | time: true
21 | };
22 |
23 | class Pos {
24 | constructor(container, offset, i = 0) {
25 | this.container = container;
26 | this.offset = offset;
27 | this.i = i;
28 | }
29 |
30 | add(change) {
31 | var cont = this.container,
32 | offset = this.offset;
33 |
34 | this.i += change;
35 |
36 | // If the container is #text.parentNode
37 | if (cont.childNodes.length) {
38 | cont = cont.childNodes[offset];
39 | offset = 0;
40 | }
41 |
42 | // If the container is #text
43 | while (cont) {
44 | if (cont.nodeType == 3) {
45 | if (!cont.LEN) {
46 | cont.LEN = cont.nodeValue.length;
47 | }
48 | if (offset + change <= cont.LEN) {
49 | this.container = cont;
50 | this.offset = offset + change;
51 | return;
52 | }
53 | change = offset + change - cont.LEN;
54 | offset = 0;
55 | }
56 | cont = cont.nextSibling;
57 | }
58 | }
59 |
60 | moveTo(offset) {
61 | this.add(offset - this.i);
62 | }
63 | }
64 |
65 | function cloneContents(range) {
66 | if (range.startContainer == range.endContainer) {
67 | return document.createTextNode(range.toString());
68 | }
69 | return range.cloneContents();
70 | }
71 |
72 | var DEFAULT_OPTIONS = {
73 | maxRunTime: 100,
74 | timeout: 10000,
75 | newTab: true,
76 | noOpener: true,
77 | embedImage: true,
78 | recursive: true,
79 | };
80 |
81 | class Linkifier extends Events {
82 | constructor(root, options = {}) {
83 | super();
84 | if (!(root instanceof Node)) {
85 | options = root;
86 | root = options.root;
87 | }
88 | this.root = root;
89 | this.options = Object.assign({}, DEFAULT_OPTIONS, options);
90 | this.aborted = false;
91 | }
92 | start() {
93 | var time = Date.now,
94 | startTime = time(),
95 | chunks = this.generateChunks();
96 |
97 | var next = () => {
98 | if (this.aborted) {
99 | this.emit("error", new Error("Aborted"));
100 | return;
101 | }
102 | var chunkStart = time(),
103 | now;
104 |
105 | do {
106 | if (chunks.next().done) {
107 | this.emit("complete", time() - startTime);
108 | return;
109 | }
110 | } while ((now = time()) - chunkStart < this.options.maxRunTime);
111 |
112 | if (now - startTime > this.options.timeout) {
113 | this.emit("error", new Error(`max execution time exceeded: ${now - startTime}, on ${this.root}`));
114 | return;
115 | }
116 |
117 | setTimeout(next);
118 | };
119 |
120 | setTimeout(next);
121 | }
122 | abort() {
123 | this.aborted = true;
124 | }
125 | *generateRanges() {
126 | var {validator, recursive} = this.options;
127 | var filter = {
128 | acceptNode: function(node) {
129 | if (validator && !validator(node)) {
130 | return NodeFilter.FILTER_REJECT;
131 | }
132 | if (INVALID_TAGS[node.localName]) {
133 | return NodeFilter.FILTER_REJECT;
134 | }
135 | if (node.localName == "wbr") {
136 | return NodeFilter.FILTER_ACCEPT;
137 | }
138 | if (node.nodeType == 3) {
139 | return NodeFilter.FILTER_ACCEPT;
140 | }
141 | return recursive ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_REJECT;
142 | }
143 | };
144 | // Generate linkified ranges.
145 | var walker = document.createTreeWalker(
146 | this.root,
147 | NodeFilter.SHOW_TEXT + NodeFilter.SHOW_ELEMENT,
148 | filter
149 | ), start, end, current, range;
150 |
151 | end = start = walker.nextNode();
152 | if (!start) {
153 | return;
154 | }
155 | range = document.createRange();
156 | range.setStartBefore(start);
157 | while ((current = walker.nextNode())) {
158 | if (end.nextSibling == current) {
159 | end = current;
160 | continue;
161 | }
162 | range.setEndAfter(end);
163 | yield range;
164 |
165 | end = start = current;
166 | range.setStartBefore(start);
167 | }
168 | range.setEndAfter(end);
169 | yield range;
170 | }
171 | *generateChunks() {
172 | var {matcher} = this.options;
173 | for (var range of this.generateRanges()) {
174 | var frag = null,
175 | pos = null,
176 | text = range.toString(),
177 | textRange = null;
178 | for (var result of matcher.match(text)) {
179 | if (!frag) {
180 | frag = document.createDocumentFragment();
181 | pos = new Pos(range.startContainer, range.startOffset);
182 | textRange = range.cloneRange();
183 | }
184 | // clone text
185 | pos.moveTo(result.start);
186 | textRange.setEnd(pos.container, pos.offset);
187 | frag.appendChild(cloneContents(textRange));
188 |
189 | // clone link
190 | textRange.collapse();
191 | pos.moveTo(result.end);
192 | textRange.setEnd(pos.container, pos.offset);
193 |
194 | var content = cloneContents(textRange),
195 | link = this.buildLink(result, content);
196 |
197 | textRange.collapse();
198 |
199 | frag.appendChild(link);
200 | this.emit("link", {link, range, result, content});
201 | }
202 | if (pos) {
203 | pos.moveTo(text.length);
204 | textRange.setEnd(pos.container, pos.offset);
205 | frag.appendChild(cloneContents(textRange));
206 |
207 | range.deleteContents();
208 | range.insertNode(frag);
209 | }
210 | yield;
211 | }
212 | }
213 | buildLink(result, content) {
214 | var {newTab, embedImage, noOpener} = this.options;
215 | var link = document.createElement("a");
216 | link.href = result.url;
217 | link.title = "Linkify Plus Plus";
218 | link.className = "linkifyplus";
219 | if (newTab) {
220 | link.target = "_blank";
221 | }
222 | if (noOpener) {
223 | link.rel = "noopener";
224 | }
225 | var child;
226 | if (embedImage && /^[^?#]+\.(?:jpg|jpeg|png|apng|gif|svg|webp)(?:$|[?#])/i.test(result.url)) {
227 | child = new Image;
228 | child.src = result.url;
229 | child.alt = result.text;
230 | } else {
231 | child = content;
232 | }
233 | link.appendChild(child);
234 | return link;
235 | }
236 | }
237 |
238 | function linkify(...args) {
239 | return new Promise((resolve, reject) => {
240 | var linkifier = new Linkifier(...args);
241 | linkifier.on("error", reject);
242 | linkifier.on("complete", resolve);
243 | for (var key of Object.keys(linkifier.options)) {
244 | if (key.startsWith("on")) {
245 | linkifier.on(key.slice(2), linkifier.options[key]);
246 | }
247 | }
248 | linkifier.start();
249 | });
250 | }
251 |
252 | module.exports = {
253 | INVALID_TAGS,
254 | Linkifier,
255 | linkify
256 | };
257 |
--------------------------------------------------------------------------------
/lib/tlds.json:
--------------------------------------------------------------------------------
1 | {
2 | "maxLength": 24,
3 | "chars": "セール佛山ಭಾರತ集团在线한국ଭାରତভাৰতর八卦ישראלموقعবংল公司网站移动我爱你москвақзнлйт联通рбгеקוםファッションストアசிங்கபூர商标店城дию家電中文信国國娱乐భారత్ලංකා购物クラウドભારતभारतम्ोसंगठन餐厅络у香港食品飞利浦台湾灣手机الجزئرنیتبيپکسدغظحةڀ澳門닷컴شكგე构健康ไทย招聘фລາວみんなευλ世界書籍ഭാരതംਭਾਰਤ址넷コム游戏ö企业息صط广东இலைநதயாհայ新加坡ف政务",
4 | "table": {
5 | "aaa": true,
6 | "aarp": true,
7 | "abb": true,
8 | "abbott": true,
9 | "abbvie": true,
10 | "abc": true,
11 | "able": true,
12 | "abogado": true,
13 | "abudhabi": true,
14 | "ac": true,
15 | "academy": true,
16 | "accountant": true,
17 | "accountants": true,
18 | "aco": true,
19 | "actor": true,
20 | "ad": true,
21 | "adult": true,
22 | "ae": true,
23 | "aeg": true,
24 | "aero": true,
25 | "aetna": true,
26 | "af": true,
27 | "afl": true,
28 | "africa": true,
29 | "ag": true,
30 | "agency": true,
31 | "ai": true,
32 | "aig": true,
33 | "airbus": true,
34 | "airforce": true,
35 | "akdn": true,
36 | "al": true,
37 | "allfinanz": true,
38 | "allstate": true,
39 | "ally": true,
40 | "alsace": true,
41 | "alstom": true,
42 | "am": true,
43 | "amazon": true,
44 | "americanexpress": true,
45 | "amex": true,
46 | "amfam": true,
47 | "amica": true,
48 | "amsterdam": true,
49 | "analytics": true,
50 | "android": true,
51 | "anz": true,
52 | "ao": true,
53 | "apartments": true,
54 | "app": true,
55 | "apple": true,
56 | "aq": true,
57 | "aquarelle": true,
58 | "ar": true,
59 | "archi": true,
60 | "army": true,
61 | "arpa": true,
62 | "art": true,
63 | "arte": true,
64 | "as": true,
65 | "asia": true,
66 | "associates": true,
67 | "at": true,
68 | "attorney": true,
69 | "au": true,
70 | "auction": true,
71 | "audi": true,
72 | "audio": true,
73 | "auspost": true,
74 | "auto": true,
75 | "autos": true,
76 | "aw": true,
77 | "aws": true,
78 | "ax": true,
79 | "axa": true,
80 | "az": true,
81 | "azure": true,
82 | "ba": true,
83 | "baby": true,
84 | "band": true,
85 | "bank": true,
86 | "bar": true,
87 | "barcelona": true,
88 | "barclaycard": true,
89 | "barclays": true,
90 | "bargains": true,
91 | "basketball": true,
92 | "bauhaus": true,
93 | "bayern": true,
94 | "bb": true,
95 | "bbc": true,
96 | "bbva": true,
97 | "bcn": true,
98 | "bd": true,
99 | "be": true,
100 | "beauty": true,
101 | "beer": true,
102 | "bentley": true,
103 | "berlin": true,
104 | "best": true,
105 | "bet": true,
106 | "bf": true,
107 | "bg": true,
108 | "bh": true,
109 | "bi": true,
110 | "bible": true,
111 | "bid": true,
112 | "bike": true,
113 | "bing": true,
114 | "bingo": true,
115 | "bio": true,
116 | "biz": true,
117 | "bj": true,
118 | "black": true,
119 | "blackfriday": true,
120 | "blog": true,
121 | "bloomberg": true,
122 | "blue": true,
123 | "bm": true,
124 | "bmw": true,
125 | "bn": true,
126 | "bnpparibas": true,
127 | "bo": true,
128 | "boats": true,
129 | "bond": true,
130 | "boo": true,
131 | "bostik": true,
132 | "boston": true,
133 | "bot": true,
134 | "boutique": true,
135 | "box": true,
136 | "br": true,
137 | "bradesco": true,
138 | "bridgestone": true,
139 | "broadway": true,
140 | "broker": true,
141 | "brother": true,
142 | "brussels": true,
143 | "bs": true,
144 | "bt": true,
145 | "build": true,
146 | "builders": true,
147 | "business": true,
148 | "buzz": true,
149 | "bw": true,
150 | "by": true,
151 | "bz": true,
152 | "bzh": true,
153 | "ca": true,
154 | "cab": true,
155 | "cafe": true,
156 | "cam": true,
157 | "camera": true,
158 | "camp": true,
159 | "canon": true,
160 | "capetown": true,
161 | "capital": true,
162 | "car": true,
163 | "cards": true,
164 | "care": true,
165 | "career": true,
166 | "careers": true,
167 | "cars": true,
168 | "casa": true,
169 | "case": true,
170 | "cash": true,
171 | "casino": true,
172 | "cat": true,
173 | "catering": true,
174 | "catholic": true,
175 | "cba": true,
176 | "cbn": true,
177 | "cc": true,
178 | "cd": true,
179 | "center": true,
180 | "ceo": true,
181 | "cern": true,
182 | "cf": true,
183 | "cfa": true,
184 | "cfd": true,
185 | "cg": true,
186 | "ch": true,
187 | "chanel": true,
188 | "channel": true,
189 | "charity": true,
190 | "chase": true,
191 | "chat": true,
192 | "cheap": true,
193 | "chintai": true,
194 | "christmas": true,
195 | "church": true,
196 | "ci": true,
197 | "cisco": true,
198 | "citi": true,
199 | "citic": true,
200 | "city": true,
201 | "ck": true,
202 | "cl": true,
203 | "claims": true,
204 | "cleaning": true,
205 | "click": true,
206 | "clinic": true,
207 | "clothing": true,
208 | "cloud": true,
209 | "club": true,
210 | "clubmed": true,
211 | "cm": true,
212 | "cn": true,
213 | "co": true,
214 | "coach": true,
215 | "codes": true,
216 | "coffee": true,
217 | "college": true,
218 | "cologne": true,
219 | "com": true,
220 | "commbank": true,
221 | "community": true,
222 | "company": true,
223 | "compare": true,
224 | "computer": true,
225 | "condos": true,
226 | "construction": true,
227 | "consulting": true,
228 | "contact": true,
229 | "contractors": true,
230 | "cooking": true,
231 | "cool": true,
232 | "coop": true,
233 | "corsica": true,
234 | "country": true,
235 | "coupons": true,
236 | "courses": true,
237 | "cpa": true,
238 | "cr": true,
239 | "credit": true,
240 | "creditcard": true,
241 | "creditunion": true,
242 | "cricket": true,
243 | "crown": true,
244 | "crs": true,
245 | "cruises": true,
246 | "cu": true,
247 | "cuisinella": true,
248 | "cv": true,
249 | "cw": true,
250 | "cx": true,
251 | "cy": true,
252 | "cymru": true,
253 | "cyou": true,
254 | "cz": true,
255 | "dad": true,
256 | "dance": true,
257 | "date": true,
258 | "dating": true,
259 | "day": true,
260 | "de": true,
261 | "deal": true,
262 | "dealer": true,
263 | "deals": true,
264 | "degree": true,
265 | "delivery": true,
266 | "dell": true,
267 | "deloitte": true,
268 | "democrat": true,
269 | "dental": true,
270 | "dentist": true,
271 | "desi": true,
272 | "design": true,
273 | "dev": true,
274 | "dhl": true,
275 | "diamonds": true,
276 | "diet": true,
277 | "digital": true,
278 | "direct": true,
279 | "directory": true,
280 | "discount": true,
281 | "discover": true,
282 | "diy": true,
283 | "dj": true,
284 | "dk": true,
285 | "dm": true,
286 | "do": true,
287 | "doctor": true,
288 | "dog": true,
289 | "domains": true,
290 | "download": true,
291 | "dubai": true,
292 | "dupont": true,
293 | "durban": true,
294 | "dvag": true,
295 | "dz": true,
296 | "earth": true,
297 | "ec": true,
298 | "eco": true,
299 | "edeka": true,
300 | "edu": true,
301 | "education": true,
302 | "ee": true,
303 | "eg": true,
304 | "email": true,
305 | "emerck": true,
306 | "energy": true,
307 | "engineer": true,
308 | "engineering": true,
309 | "enterprises": true,
310 | "equipment": true,
311 | "er": true,
312 | "ericsson": true,
313 | "erni": true,
314 | "es": true,
315 | "esq": true,
316 | "estate": true,
317 | "et": true,
318 | "eu": true,
319 | "eurovision": true,
320 | "eus": true,
321 | "events": true,
322 | "exchange": true,
323 | "expert": true,
324 | "exposed": true,
325 | "express": true,
326 | "extraspace": true,
327 | "fage": true,
328 | "fail": true,
329 | "fairwinds": true,
330 | "faith": true,
331 | "family": true,
332 | "fan": true,
333 | "fans": true,
334 | "farm": true,
335 | "fashion": true,
336 | "feedback": true,
337 | "ferrero": true,
338 | "fi": true,
339 | "film": true,
340 | "finance": true,
341 | "financial": true,
342 | "firmdale": true,
343 | "fish": true,
344 | "fishing": true,
345 | "fit": true,
346 | "fitness": true,
347 | "fj": true,
348 | "fk": true,
349 | "flickr": true,
350 | "flights": true,
351 | "flir": true,
352 | "florist": true,
353 | "flowers": true,
354 | "fm": true,
355 | "fo": true,
356 | "foo": true,
357 | "food": true,
358 | "football": true,
359 | "ford": true,
360 | "forex": true,
361 | "forsale": true,
362 | "forum": true,
363 | "foundation": true,
364 | "fox": true,
365 | "fr": true,
366 | "fresenius": true,
367 | "frl": true,
368 | "frogans": true,
369 | "fujitsu": true,
370 | "fun": true,
371 | "fund": true,
372 | "furniture": true,
373 | "futbol": true,
374 | "fyi": true,
375 | "ga": true,
376 | "gal": true,
377 | "gallery": true,
378 | "game": true,
379 | "games": true,
380 | "garden": true,
381 | "gay": true,
382 | "gd": true,
383 | "gdn": true,
384 | "ge": true,
385 | "gea": true,
386 | "gent": true,
387 | "genting": true,
388 | "gf": true,
389 | "gg": true,
390 | "gh": true,
391 | "gi": true,
392 | "gift": true,
393 | "gifts": true,
394 | "gives": true,
395 | "giving": true,
396 | "gl": true,
397 | "glass": true,
398 | "gle": true,
399 | "global": true,
400 | "globo": true,
401 | "gm": true,
402 | "gmail": true,
403 | "gmbh": true,
404 | "gmo": true,
405 | "gmx": true,
406 | "gn": true,
407 | "godaddy": true,
408 | "gold": true,
409 | "golf": true,
410 | "goog": true,
411 | "google": true,
412 | "gop": true,
413 | "gov": true,
414 | "gp": true,
415 | "gq": true,
416 | "gr": true,
417 | "grainger": true,
418 | "graphics": true,
419 | "gratis": true,
420 | "green": true,
421 | "gripe": true,
422 | "group": true,
423 | "gs": true,
424 | "gt": true,
425 | "gu": true,
426 | "gucci": true,
427 | "guide": true,
428 | "guitars": true,
429 | "guru": true,
430 | "gw": true,
431 | "gy": true,
432 | "hair": true,
433 | "hamburg": true,
434 | "haus": true,
435 | "health": true,
436 | "healthcare": true,
437 | "help": true,
438 | "helsinki": true,
439 | "here": true,
440 | "hermes": true,
441 | "hiphop": true,
442 | "hisamitsu": true,
443 | "hitachi": true,
444 | "hiv": true,
445 | "hk": true,
446 | "hm": true,
447 | "hn": true,
448 | "hockey": true,
449 | "holdings": true,
450 | "holiday": true,
451 | "homes": true,
452 | "honda": true,
453 | "horse": true,
454 | "hospital": true,
455 | "host": true,
456 | "hosting": true,
457 | "hotmail": true,
458 | "house": true,
459 | "how": true,
460 | "hr": true,
461 | "hsbc": true,
462 | "ht": true,
463 | "hu": true,
464 | "hyatt": true,
465 | "hyundai": true,
466 | "ice": true,
467 | "icu": true,
468 | "id": true,
469 | "ie": true,
470 | "ieee": true,
471 | "ifm": true,
472 | "ikano": true,
473 | "il": true,
474 | "im": true,
475 | "imamat": true,
476 | "immo": true,
477 | "immobilien": true,
478 | "in": true,
479 | "inc": true,
480 | "industries": true,
481 | "info": true,
482 | "ing": true,
483 | "ink": true,
484 | "institute": true,
485 | "insurance": true,
486 | "insure": true,
487 | "int": true,
488 | "international": true,
489 | "investments": true,
490 | "io": true,
491 | "ipiranga": true,
492 | "iq": true,
493 | "ir": true,
494 | "irish": true,
495 | "is": true,
496 | "ismaili": true,
497 | "ist": true,
498 | "istanbul": true,
499 | "it": true,
500 | "itau": true,
501 | "itv": true,
502 | "jaguar": true,
503 | "java": true,
504 | "jcb": true,
505 | "je": true,
506 | "jetzt": true,
507 | "jewelry": true,
508 | "jio": true,
509 | "jll": true,
510 | "jm": true,
511 | "jmp": true,
512 | "jnj": true,
513 | "jo": true,
514 | "jobs": true,
515 | "joburg": true,
516 | "jp": true,
517 | "jpmorgan": true,
518 | "jprs": true,
519 | "juegos": true,
520 | "kaufen": true,
521 | "ke": true,
522 | "kfh": true,
523 | "kg": true,
524 | "kh": true,
525 | "ki": true,
526 | "kia": true,
527 | "kids": true,
528 | "kim": true,
529 | "kitchen": true,
530 | "kiwi": true,
531 | "km": true,
532 | "kn": true,
533 | "koeln": true,
534 | "komatsu": true,
535 | "kp": true,
536 | "kpmg": true,
537 | "kpn": true,
538 | "kr": true,
539 | "krd": true,
540 | "kred": true,
541 | "kw": true,
542 | "ky": true,
543 | "kyoto": true,
544 | "kz": true,
545 | "la": true,
546 | "lamborghini": true,
547 | "lancaster": true,
548 | "land": true,
549 | "landrover": true,
550 | "lanxess": true,
551 | "lat": true,
552 | "latrobe": true,
553 | "law": true,
554 | "lawyer": true,
555 | "lb": true,
556 | "lc": true,
557 | "lease": true,
558 | "leclerc": true,
559 | "legal": true,
560 | "lexus": true,
561 | "lgbt": true,
562 | "li": true,
563 | "lidl": true,
564 | "life": true,
565 | "lifestyle": true,
566 | "lighting": true,
567 | "lilly": true,
568 | "limited": true,
569 | "limo": true,
570 | "lincoln": true,
571 | "link": true,
572 | "live": true,
573 | "living": true,
574 | "lk": true,
575 | "llc": true,
576 | "loan": true,
577 | "loans": true,
578 | "locker": true,
579 | "locus": true,
580 | "lol": true,
581 | "london": true,
582 | "lotto": true,
583 | "love": true,
584 | "lr": true,
585 | "ls": true,
586 | "lt": true,
587 | "ltd": true,
588 | "ltda": true,
589 | "lu": true,
590 | "lundbeck": true,
591 | "luxe": true,
592 | "luxury": true,
593 | "lv": true,
594 | "ly": true,
595 | "ma": true,
596 | "madrid": true,
597 | "maif": true,
598 | "maison": true,
599 | "makeup": true,
600 | "man": true,
601 | "management": true,
602 | "mango": true,
603 | "market": true,
604 | "marketing": true,
605 | "markets": true,
606 | "marriott": true,
607 | "mattel": true,
608 | "mba": true,
609 | "mc": true,
610 | "md": true,
611 | "me": true,
612 | "med": true,
613 | "media": true,
614 | "meet": true,
615 | "melbourne": true,
616 | "meme": true,
617 | "memorial": true,
618 | "men": true,
619 | "menu": true,
620 | "mg": true,
621 | "mh": true,
622 | "miami": true,
623 | "microsoft": true,
624 | "mil": true,
625 | "mini": true,
626 | "mit": true,
627 | "mk": true,
628 | "ml": true,
629 | "mlb": true,
630 | "mm": true,
631 | "mma": true,
632 | "mn": true,
633 | "mo": true,
634 | "mobi": true,
635 | "moda": true,
636 | "moe": true,
637 | "moi": true,
638 | "mom": true,
639 | "monash": true,
640 | "money": true,
641 | "monster": true,
642 | "mortgage": true,
643 | "moscow": true,
644 | "motorcycles": true,
645 | "mov": true,
646 | "movie": true,
647 | "mp": true,
648 | "mq": true,
649 | "mr": true,
650 | "ms": true,
651 | "mt": true,
652 | "mtn": true,
653 | "mtr": true,
654 | "mu": true,
655 | "museum": true,
656 | "music": true,
657 | "mv": true,
658 | "mw": true,
659 | "mx": true,
660 | "my": true,
661 | "mz": true,
662 | "na": true,
663 | "nab": true,
664 | "nagoya": true,
665 | "name": true,
666 | "navy": true,
667 | "nc": true,
668 | "ne": true,
669 | "nec": true,
670 | "net": true,
671 | "netbank": true,
672 | "network": true,
673 | "neustar": true,
674 | "new": true,
675 | "news": true,
676 | "next": true,
677 | "nexus": true,
678 | "nf": true,
679 | "ng": true,
680 | "ngo": true,
681 | "nhk": true,
682 | "ni": true,
683 | "nico": true,
684 | "nike": true,
685 | "ninja": true,
686 | "nissan": true,
687 | "nl": true,
688 | "no": true,
689 | "nokia": true,
690 | "now": true,
691 | "nowruz": true,
692 | "np": true,
693 | "nr": true,
694 | "nra": true,
695 | "nrw": true,
696 | "ntt": true,
697 | "nu": true,
698 | "nyc": true,
699 | "nz": true,
700 | "observer": true,
701 | "office": true,
702 | "okinawa": true,
703 | "om": true,
704 | "omega": true,
705 | "one": true,
706 | "ong": true,
707 | "onl": true,
708 | "online": true,
709 | "ooo": true,
710 | "oracle": true,
711 | "orange": true,
712 | "org": true,
713 | "organic": true,
714 | "osaka": true,
715 | "otsuka": true,
716 | "ovh": true,
717 | "pa": true,
718 | "page": true,
719 | "panasonic": true,
720 | "paris": true,
721 | "partners": true,
722 | "parts": true,
723 | "party": true,
724 | "pe": true,
725 | "pet": true,
726 | "pf": true,
727 | "pfizer": true,
728 | "pg": true,
729 | "ph": true,
730 | "pharmacy": true,
731 | "phd": true,
732 | "philips": true,
733 | "photo": true,
734 | "photography": true,
735 | "photos": true,
736 | "physio": true,
737 | "pics": true,
738 | "pictet": true,
739 | "pictures": true,
740 | "ping": true,
741 | "pink": true,
742 | "pioneer": true,
743 | "pizza": true,
744 | "pk": true,
745 | "pl": true,
746 | "place": true,
747 | "play": true,
748 | "plumbing": true,
749 | "plus": true,
750 | "pm": true,
751 | "pn": true,
752 | "pohl": true,
753 | "poker": true,
754 | "politie": true,
755 | "porn": true,
756 | "post": true,
757 | "pr": true,
758 | "praxi": true,
759 | "press": true,
760 | "prime": true,
761 | "pro": true,
762 | "productions": true,
763 | "prof": true,
764 | "promo": true,
765 | "properties": true,
766 | "property": true,
767 | "protection": true,
768 | "pru": true,
769 | "prudential": true,
770 | "ps": true,
771 | "pt": true,
772 | "pub": true,
773 | "pw": true,
774 | "pwc": true,
775 | "py": true,
776 | "qa": true,
777 | "qpon": true,
778 | "quebec": true,
779 | "quest": true,
780 | "racing": true,
781 | "radio": true,
782 | "re": true,
783 | "realestate": true,
784 | "realtor": true,
785 | "realty": true,
786 | "recipes": true,
787 | "red": true,
788 | "redstone": true,
789 | "rehab": true,
790 | "reise": true,
791 | "reisen": true,
792 | "reit": true,
793 | "ren": true,
794 | "rent": true,
795 | "rentals": true,
796 | "repair": true,
797 | "report": true,
798 | "republican": true,
799 | "rest": true,
800 | "restaurant": true,
801 | "review": true,
802 | "reviews": true,
803 | "rexroth": true,
804 | "rich": true,
805 | "ricoh": true,
806 | "rio": true,
807 | "rip": true,
808 | "ro": true,
809 | "rocks": true,
810 | "rodeo": true,
811 | "rogers": true,
812 | "rs": true,
813 | "rsvp": true,
814 | "ru": true,
815 | "rugby": true,
816 | "ruhr": true,
817 | "run": true,
818 | "rw": true,
819 | "ryukyu": true,
820 | "sa": true,
821 | "saarland": true,
822 | "sale": true,
823 | "salon": true,
824 | "samsung": true,
825 | "sandvik": true,
826 | "sandvikcoromant": true,
827 | "sanofi": true,
828 | "sap": true,
829 | "sarl": true,
830 | "saxo": true,
831 | "sb": true,
832 | "sbi": true,
833 | "sbs": true,
834 | "sc": true,
835 | "scb": true,
836 | "schaeffler": true,
837 | "schmidt": true,
838 | "school": true,
839 | "schule": true,
840 | "schwarz": true,
841 | "science": true,
842 | "scot": true,
843 | "sd": true,
844 | "se": true,
845 | "seat": true,
846 | "security": true,
847 | "select": true,
848 | "sener": true,
849 | "services": true,
850 | "seven": true,
851 | "sew": true,
852 | "sex": true,
853 | "sexy": true,
854 | "sfr": true,
855 | "sg": true,
856 | "sh": true,
857 | "sharp": true,
858 | "shell": true,
859 | "shiksha": true,
860 | "shoes": true,
861 | "shop": true,
862 | "shopping": true,
863 | "show": true,
864 | "si": true,
865 | "singles": true,
866 | "site": true,
867 | "sk": true,
868 | "ski": true,
869 | "skin": true,
870 | "sky": true,
871 | "skype": true,
872 | "sl": true,
873 | "sm": true,
874 | "smart": true,
875 | "sn": true,
876 | "sncf": true,
877 | "so": true,
878 | "soccer": true,
879 | "social": true,
880 | "softbank": true,
881 | "software": true,
882 | "sohu": true,
883 | "solar": true,
884 | "solutions": true,
885 | "sony": true,
886 | "soy": true,
887 | "spa": true,
888 | "space": true,
889 | "sport": true,
890 | "sr": true,
891 | "srl": true,
892 | "ss": true,
893 | "st": true,
894 | "stada": true,
895 | "statebank": true,
896 | "statefarm": true,
897 | "stc": true,
898 | "stockholm": true,
899 | "storage": true,
900 | "store": true,
901 | "stream": true,
902 | "studio": true,
903 | "study": true,
904 | "style": true,
905 | "su": true,
906 | "sucks": true,
907 | "supplies": true,
908 | "supply": true,
909 | "support": true,
910 | "surf": true,
911 | "surgery": true,
912 | "suzuki": true,
913 | "sv": true,
914 | "swatch": true,
915 | "swiss": true,
916 | "sx": true,
917 | "sy": true,
918 | "sydney": true,
919 | "systems": true,
920 | "sz": true,
921 | "taipei": true,
922 | "target": true,
923 | "tatamotors": true,
924 | "tatar": true,
925 | "tattoo": true,
926 | "tax": true,
927 | "taxi": true,
928 | "tc": true,
929 | "td": true,
930 | "team": true,
931 | "tech": true,
932 | "technology": true,
933 | "tel": true,
934 | "temasek": true,
935 | "tennis": true,
936 | "teva": true,
937 | "tf": true,
938 | "tg": true,
939 | "th": true,
940 | "theater": true,
941 | "theatre": true,
942 | "tickets": true,
943 | "tienda": true,
944 | "tips": true,
945 | "tires": true,
946 | "tirol": true,
947 | "tj": true,
948 | "tk": true,
949 | "tl": true,
950 | "tm": true,
951 | "tn": true,
952 | "to": true,
953 | "today": true,
954 | "tokyo": true,
955 | "tools": true,
956 | "top": true,
957 | "toray": true,
958 | "toshiba": true,
959 | "total": true,
960 | "tours": true,
961 | "town": true,
962 | "toyota": true,
963 | "toys": true,
964 | "tr": true,
965 | "trade": true,
966 | "trading": true,
967 | "training": true,
968 | "travel": true,
969 | "travelers": true,
970 | "trust": true,
971 | "tt": true,
972 | "tube": true,
973 | "tui": true,
974 | "tv": true,
975 | "tvs": true,
976 | "tw": true,
977 | "tz": true,
978 | "ua": true,
979 | "ug": true,
980 | "uk": true,
981 | "unicom": true,
982 | "university": true,
983 | "uno": true,
984 | "uol": true,
985 | "us": true,
986 | "uy": true,
987 | "uz": true,
988 | "va": true,
989 | "vacations": true,
990 | "vana": true,
991 | "vanguard": true,
992 | "vc": true,
993 | "ve": true,
994 | "vegas": true,
995 | "ventures": true,
996 | "versicherung": true,
997 | "vet": true,
998 | "vg": true,
999 | "vi": true,
1000 | "viajes": true,
1001 | "video": true,
1002 | "vig": true,
1003 | "villas": true,
1004 | "vin": true,
1005 | "vip": true,
1006 | "vision": true,
1007 | "vivo": true,
1008 | "vlaanderen": true,
1009 | "vn": true,
1010 | "vodka": true,
1011 | "vote": true,
1012 | "voting": true,
1013 | "voto": true,
1014 | "voyage": true,
1015 | "vu": true,
1016 | "wales": true,
1017 | "walter": true,
1018 | "wang": true,
1019 | "watch": true,
1020 | "watches": true,
1021 | "webcam": true,
1022 | "weber": true,
1023 | "website": true,
1024 | "wed": true,
1025 | "wedding": true,
1026 | "weir": true,
1027 | "wf": true,
1028 | "whoswho": true,
1029 | "wien": true,
1030 | "wiki": true,
1031 | "williamhill": true,
1032 | "win": true,
1033 | "windows": true,
1034 | "wine": true,
1035 | "wme": true,
1036 | "woodside": true,
1037 | "work": true,
1038 | "works": true,
1039 | "world": true,
1040 | "ws": true,
1041 | "wtf": true,
1042 | "xbox": true,
1043 | "xin": true,
1044 | "xn--1ck2e1b": true,
1045 | "xn--1qqw23a": true,
1046 | "xn--2scrj9c": true,
1047 | "xn--3bst00m": true,
1048 | "xn--3ds443g": true,
1049 | "xn--3e0b707e": true,
1050 | "xn--3hcrj9c": true,
1051 | "xn--45br5cyl": true,
1052 | "xn--45brj9c": true,
1053 | "xn--45q11c": true,
1054 | "xn--4dbrk0ce": true,
1055 | "xn--4gbrim": true,
1056 | "xn--54b7fta0cc": true,
1057 | "xn--55qx5d": true,
1058 | "xn--5tzm5g": true,
1059 | "xn--6frz82g": true,
1060 | "xn--6qq986b3xl": true,
1061 | "xn--80adxhks": true,
1062 | "xn--80ao21a": true,
1063 | "xn--80asehdb": true,
1064 | "xn--80aswg": true,
1065 | "xn--8y0a063a": true,
1066 | "xn--90a3ac": true,
1067 | "xn--90ae": true,
1068 | "xn--90ais": true,
1069 | "xn--9dbq2a": true,
1070 | "xn--bck1b9a5dre4c": true,
1071 | "xn--c1avg": true,
1072 | "xn--cck2b3b": true,
1073 | "xn--clchc0ea0b2g2a9gcd": true,
1074 | "xn--czr694b": true,
1075 | "xn--czrs0t": true,
1076 | "xn--czru2d": true,
1077 | "xn--d1acj3b": true,
1078 | "xn--d1alf": true,
1079 | "xn--e1a4c": true,
1080 | "xn--fct429k": true,
1081 | "xn--fiq228c5hs": true,
1082 | "xn--fiq64b": true,
1083 | "xn--fiqs8s": true,
1084 | "xn--fiqz9s": true,
1085 | "xn--fjq720a": true,
1086 | "xn--fpcrj9c3d": true,
1087 | "xn--fzc2c9e2c": true,
1088 | "xn--g2xx48c": true,
1089 | "xn--gckr3f0f": true,
1090 | "xn--gecrj9c": true,
1091 | "xn--h2breg3eve": true,
1092 | "xn--h2brj9c": true,
1093 | "xn--h2brj9c8c": true,
1094 | "xn--hxt814e": true,
1095 | "xn--i1b6b1a6a2e": true,
1096 | "xn--imr513n": true,
1097 | "xn--io0a7i": true,
1098 | "xn--j1amh": true,
1099 | "xn--j6w193g": true,
1100 | "xn--jvr189m": true,
1101 | "xn--kcrx77d1x4a": true,
1102 | "xn--kprw13d": true,
1103 | "xn--kpry57d": true,
1104 | "xn--kput3i": true,
1105 | "xn--l1acc": true,
1106 | "xn--lgbbat1ad8j": true,
1107 | "xn--mgb9awbf": true,
1108 | "xn--mgba3a4f16a": true,
1109 | "xn--mgbaam7a8h": true,
1110 | "xn--mgbab2bd": true,
1111 | "xn--mgbah1a3hjkrd": true,
1112 | "xn--mgbai9azgqp6j": true,
1113 | "xn--mgbayh7gpa": true,
1114 | "xn--mgbbh1a": true,
1115 | "xn--mgbc0a9azcg": true,
1116 | "xn--mgbca7dzdo": true,
1117 | "xn--mgbcpq6gpa1a": true,
1118 | "xn--mgberp4a5d4ar": true,
1119 | "xn--mgbgu82a": true,
1120 | "xn--mgbpl2fh": true,
1121 | "xn--mgbtx2b": true,
1122 | "xn--mix891f": true,
1123 | "xn--mk1bu44c": true,
1124 | "xn--ngbc5azd": true,
1125 | "xn--ngbe9e0a": true,
1126 | "xn--node": true,
1127 | "xn--nqv7f": true,
1128 | "xn--nyqy26a": true,
1129 | "xn--o3cw4h": true,
1130 | "xn--ogbpf8fl": true,
1131 | "xn--otu796d": true,
1132 | "xn--p1acf": true,
1133 | "xn--p1ai": true,
1134 | "xn--pgbs0dh": true,
1135 | "xn--q7ce6a": true,
1136 | "xn--q9jyb4c": true,
1137 | "xn--qxa6a": true,
1138 | "xn--qxam": true,
1139 | "xn--rhqv96g": true,
1140 | "xn--rovu88b": true,
1141 | "xn--rvc1e0am3e": true,
1142 | "xn--s9brj9c": true,
1143 | "xn--ses554g": true,
1144 | "xn--t60b56a": true,
1145 | "xn--tckwe": true,
1146 | "xn--unup4y": true,
1147 | "xn--vermgensberatung-pwb": true,
1148 | "xn--vhquv": true,
1149 | "xn--vuq861b": true,
1150 | "xn--wgbh1c": true,
1151 | "xn--wgbl6a": true,
1152 | "xn--xhq521b": true,
1153 | "xn--xkc2al3hye2a": true,
1154 | "xn--xkc2dl3a5ee0h": true,
1155 | "xn--y9a3aq": true,
1156 | "xn--yfro4i67o": true,
1157 | "xn--ygbi2ammx": true,
1158 | "xn--zfr164b": true,
1159 | "xxx": true,
1160 | "xyz": true,
1161 | "yachts": true,
1162 | "yahoo": true,
1163 | "yandex": true,
1164 | "ye": true,
1165 | "yodobashi": true,
1166 | "yoga": true,
1167 | "yokohama": true,
1168 | "youtube": true,
1169 | "yt": true,
1170 | "za": true,
1171 | "zappos": true,
1172 | "zara": true,
1173 | "zip": true,
1174 | "zm": true,
1175 | "zone": true,
1176 | "zuerich": true,
1177 | "zw": true,
1178 | "セール": true,
1179 | "佛山": true,
1180 | "ಭಾರತ": true,
1181 | "集团": true,
1182 | "在线": true,
1183 | "한국": true,
1184 | "ଭାରତ": true,
1185 | "ভাৰত": true,
1186 | "ভারত": true,
1187 | "八卦": true,
1188 | "ישראל": true,
1189 | "موقع": true,
1190 | "বাংলা": true,
1191 | "公司": true,
1192 | "网站": true,
1193 | "移动": true,
1194 | "我爱你": true,
1195 | "москва": true,
1196 | "қаз": true,
1197 | "онлайн": true,
1198 | "сайт": true,
1199 | "联通": true,
1200 | "срб": true,
1201 | "бг": true,
1202 | "бел": true,
1203 | "קום": true,
1204 | "ファッション": true,
1205 | "орг": true,
1206 | "ストア": true,
1207 | "சிங்கப்பூர்": true,
1208 | "商标": true,
1209 | "商店": true,
1210 | "商城": true,
1211 | "дети": true,
1212 | "мкд": true,
1213 | "ею": true,
1214 | "家電": true,
1215 | "中文网": true,
1216 | "中信": true,
1217 | "中国": true,
1218 | "中國": true,
1219 | "娱乐": true,
1220 | "భారత్": true,
1221 | "ලංකා": true,
1222 | "购物": true,
1223 | "クラウド": true,
1224 | "ભારત": true,
1225 | "भारतम्": true,
1226 | "भारत": true,
1227 | "भारोत": true,
1228 | "网店": true,
1229 | "संगठन": true,
1230 | "餐厅": true,
1231 | "网络": true,
1232 | "укр": true,
1233 | "香港": true,
1234 | "食品": true,
1235 | "飞利浦": true,
1236 | "台湾": true,
1237 | "台灣": true,
1238 | "手机": true,
1239 | "мон": true,
1240 | "الجزائر": true,
1241 | "عمان": true,
1242 | "ایران": true,
1243 | "امارات": true,
1244 | "بازار": true,
1245 | "موريتانيا": true,
1246 | "پاکستان": true,
1247 | "الاردن": true,
1248 | "بارت": true,
1249 | "المغرب": true,
1250 | "ابوظبي": true,
1251 | "البحرين": true,
1252 | "السعودية": true,
1253 | "ڀارت": true,
1254 | "سودان": true,
1255 | "عراق": true,
1256 | "澳門": true,
1257 | "닷컴": true,
1258 | "شبكة": true,
1259 | "بيتك": true,
1260 | "გე": true,
1261 | "机构": true,
1262 | "健康": true,
1263 | "ไทย": true,
1264 | "سورية": true,
1265 | "招聘": true,
1266 | "рус": true,
1267 | "рф": true,
1268 | "تونس": true,
1269 | "ລາວ": true,
1270 | "みんな": true,
1271 | "ευ": true,
1272 | "ελ": true,
1273 | "世界": true,
1274 | "書籍": true,
1275 | "ഭാരതം": true,
1276 | "ਭਾਰਤ": true,
1277 | "网址": true,
1278 | "닷넷": true,
1279 | "コム": true,
1280 | "游戏": true,
1281 | "vermögensberatung": true,
1282 | "企业": true,
1283 | "信息": true,
1284 | "مصر": true,
1285 | "قطر": true,
1286 | "广东": true,
1287 | "இலங்கை": true,
1288 | "இந்தியா": true,
1289 | "հայ": true,
1290 | "新加坡": true,
1291 | "فلسطين": true,
1292 | "政务": true,
1293 | "onion": true
1294 | }
1295 | }
--------------------------------------------------------------------------------
/lib/url-matcher.js:
--------------------------------------------------------------------------------
1 | var tlds = require("./tlds.json"),
2 | RE = {
3 | PROTOCOL: "([a-z][-a-z*]+://)?",
4 | USER: "(?:([\\w:.+-]+)@)?",
5 | DOMAIN_UNI: `([a-z0-9-.\\u00A0-\\uFFFF]+\\.[a-z0-9-${tlds.chars}]{1,${tlds.maxLength}})`,
6 | DOMAIN: `([a-z0-9-.]+\\.[a-z0-9-]{1,${tlds.maxLength}})`,
7 | PORT: "(:\\d+\\b)?",
8 | PATH_UNI: "([/?#]\\S*)?",
9 | PATH: "([/?#][\\w-.~!$&*+;=:@%/?#(),'\\[\\]]*)?"
10 | },
11 | TLD_TABLE = tlds.table;
12 |
13 | function regexEscape(text) {
14 | return text.replace(/[[\]\\^-]/g, "\\$&");
15 | }
16 |
17 | function buildRegex({
18 | unicode = false, customRules = [], standalone = false,
19 | boundaryLeft, boundaryRight
20 | }) {
21 | var pattern = RE.PROTOCOL + RE.USER;
22 |
23 | if (unicode) {
24 | pattern += RE.DOMAIN_UNI + RE.PORT + RE.PATH_UNI;
25 | } else {
26 | pattern += RE.DOMAIN + RE.PORT + RE.PATH;
27 | }
28 |
29 | if (customRules.length) {
30 | pattern = "(?:(" + customRules.join("|") + ")|" + pattern + ")";
31 | } else {
32 | pattern = "()" + pattern;
33 | }
34 |
35 | var prefix, suffix, invalidSuffix;
36 | if (standalone) {
37 | if (boundaryLeft) {
38 | prefix = "((?:^|\\s)[" + regexEscape(boundaryLeft) + "]*?)";
39 | } else {
40 | prefix = "(^|\\s)";
41 | }
42 | if (boundaryRight) {
43 | suffix = "([" + regexEscape(boundaryRight) + "]*(?:$|\\s))";
44 | } else {
45 | suffix = "($|\\s)";
46 | }
47 | invalidSuffix = "[^\\s" + regexEscape(boundaryRight) + "]";
48 | } else {
49 | prefix = "(^|\\b|_)";
50 | suffix = "()";
51 | }
52 |
53 | pattern = prefix + pattern + suffix;
54 |
55 | return {
56 | url: new RegExp(pattern, "igm"),
57 | invalidSuffix: invalidSuffix && new RegExp(invalidSuffix),
58 | mustache: /\{\{[\s\S]+?\}\}/g
59 | };
60 | }
61 |
62 | function pathStrip(m, re, repl) {
63 | var s = m.path.replace(re, repl);
64 |
65 | if (s == m.path) return;
66 |
67 | m.end -= m.path.length - s.length;
68 | m.suffix = m.path.slice(s.length) + m.suffix;
69 | m.path = s;
70 | }
71 |
72 | function pathStripQuote(m, c) {
73 | var i = 0, s = m.path, end, pos = 0;
74 |
75 | if (!s.endsWith(c)) return;
76 |
77 | while ((pos = s.indexOf(c, pos)) >= 0) {
78 | if (i % 2) {
79 | end = null;
80 | } else {
81 | end = pos;
82 | }
83 | pos++;
84 | i++;
85 | }
86 |
87 | if (!end) return;
88 |
89 | m.end -= s.length - end;
90 | m.path = s.slice(0, end);
91 | m.suffix = s.slice(end) + m.suffix;
92 | }
93 |
94 | function pathStripBrace(m, left, right) {
95 | var str = m.path,
96 | re = new RegExp("[\\" + left + "\\" + right + "]", "g"),
97 | match, count = 0, end;
98 |
99 | // Match loop
100 | while ((match = re.exec(str))) {
101 | if (count % 2 == 0) {
102 | end = match.index;
103 | if (match[0] == right) {
104 | break;
105 | }
106 | } else {
107 | if (match[0] == left) {
108 | break;
109 | }
110 | }
111 | count++;
112 | }
113 |
114 | if (!match && count % 2 == 0) {
115 | return;
116 | }
117 |
118 | m.end -= m.path.length - end;
119 | m.path = str.slice(0, end);
120 | m.suffix = str.slice(end) + m.suffix;
121 | }
122 |
123 | function isIP(s) {
124 | var m, i;
125 | if (!(m = s.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/))) {
126 | return false;
127 | }
128 | for (i = 1; i < m.length; i++) {
129 | if (+m[i] > 255 || (m[i].length > 1 && m[i][0] == "0")) {
130 | return false;
131 | }
132 | }
133 | return true;
134 | }
135 |
136 | function inTLDS(domain) {
137 | var match = domain.match(/\.([^.]+)$/);
138 | if (!match) {
139 | return false;
140 | }
141 | var key = match[1].toLowerCase();
142 | // eslint-disable-next-line no-prototype-builtins
143 | return TLD_TABLE.hasOwnProperty(key);
144 | }
145 |
146 | class UrlMatcher {
147 | constructor(options = {}) {
148 | this.options = options;
149 | this.regex = buildRegex(options);
150 | }
151 |
152 | *match(text) {
153 | var {
154 | fuzzyIp = true,
155 | ignoreMustache = false,
156 | mail = true
157 | } = this.options,
158 | {
159 | url,
160 | invalidSuffix,
161 | mustache
162 | } = this.regex,
163 | urlLastIndex, mustacheLastIndex;
164 |
165 | mustache.lastIndex = 0;
166 | url.lastIndex = 0;
167 |
168 | var mustacheMatch, mustacheRange;
169 | if (ignoreMustache) {
170 | mustacheMatch = mustache.exec(text);
171 | if (mustacheMatch) {
172 | mustacheRange = {
173 | start: mustacheMatch.index,
174 | end: mustache.lastIndex
175 | };
176 | }
177 | }
178 |
179 | var urlMatch;
180 | while ((urlMatch = url.exec(text))) {
181 | const result = {
182 | start: 0,
183 | end: 0,
184 |
185 | text: "",
186 | url: "",
187 |
188 | prefix: urlMatch[1],
189 | custom: urlMatch[2],
190 | protocol: urlMatch[3],
191 | auth: urlMatch[4] || "",
192 | domain: urlMatch[5],
193 | port: urlMatch[6] || "",
194 | path: urlMatch[7] || "",
195 | suffix: urlMatch[8]
196 | };
197 |
198 | if (result.custom) {
199 | result.start = urlMatch.index;
200 | result.end = url.lastIndex;
201 | result.text = result.url = urlMatch[0];
202 | } else {
203 |
204 | result.start = urlMatch.index + result.prefix.length;
205 | result.end = url.lastIndex - result.suffix.length;
206 | }
207 |
208 | if (mustacheRange && mustacheRange.end <= result.start) {
209 | mustacheMatch = mustache.exec(text);
210 | if (mustacheMatch) {
211 | mustacheRange.start = mustacheMatch.index;
212 | mustacheRange.end = mustache.lastIndex;
213 | } else {
214 | mustacheRange = null;
215 | }
216 | }
217 |
218 | // ignore urls inside mustache pair
219 | if (mustacheRange && result.start < mustacheRange.end && result.end >= mustacheRange.start) {
220 | continue;
221 | }
222 |
223 | if (!result.custom) {
224 | // adjust path and suffix
225 | if (result.path) {
226 | // Strip BBCode
227 | pathStrip(result, /\[\/?(b|i|u|url|img|quote|code|size|color)\].*/i, "");
228 |
229 | // Strip braces
230 | pathStripBrace(result, "(", ")");
231 | pathStripBrace(result, "[", "]");
232 | pathStripBrace(result, "{", "}");
233 |
234 | // Strip quotes
235 | pathStripQuote(result, "'");
236 | pathStripQuote(result, '"');
237 |
238 | // Remove trailing ".,?"
239 | pathStrip(result, /(^|[^-_])[.,?]+$/, "$1");
240 | }
241 |
242 | // check suffix
243 | if (invalidSuffix && invalidSuffix.test(result.suffix)) {
244 | if (/\s$/.test(result.suffix)) {
245 | url.lastIndex--;
246 | }
247 | continue;
248 | }
249 |
250 | // ignore fuzzy ip
251 | if (!fuzzyIp && isIP(result.domain) &&
252 | !result.protocol && !result.auth && !result.path) {
253 | continue;
254 | }
255 |
256 | // mailto protocol
257 | if (!result.protocol && result.auth) {
258 | var matchMail = result.auth.match(/^mailto:(.+)/);
259 | if (matchMail) {
260 | result.protocol = "mailto:";
261 | result.auth = matchMail[1];
262 | }
263 | }
264 |
265 | // http alias
266 | if (result.protocol && result.protocol.match(/^(hxxp|h\*\*p|ttp)/)) {
267 | result.protocol = "http://";
268 | }
269 |
270 | // guess protocol
271 | if (!result.protocol) {
272 | var domainMatch;
273 | if ((domainMatch = result.domain.match(/^(ftp|irc)/))) {
274 | result.protocol = domainMatch[0] + "://";
275 | } else if (result.domain.match(/^(www|web)/)) {
276 | result.protocol = "http://";
277 | } else if (result.auth && result.auth.indexOf(":") < 0 && !result.path) {
278 | result.protocol = "mailto:";
279 | } else {
280 | result.protocol = "http://";
281 | }
282 | }
283 |
284 | // ignore mail
285 | if (!mail && result.protocol === "mailto:") {
286 | continue;
287 | }
288 |
289 | // verify domain
290 | if (!isIP(result.domain)) {
291 | if (/^(http|https|mailto)/.test(result.protocol) && !inTLDS(result.domain)) {
292 | continue;
293 | }
294 |
295 | const invalidLabel = getInvalidLabel(result.domain);
296 | if (invalidLabel) {
297 | url.lastIndex = urlMatch.index + invalidLabel.index + 1;
298 | continue;
299 | }
300 | }
301 |
302 | // Create URL
303 | result.url = result.protocol + (result.auth && result.auth + "@") + result.domain + result.port + result.path;
304 | result.text = text.slice(result.start, result.end);
305 | }
306 |
307 | // since regex is shared with other parse generators, cache lastIndex position and restore later
308 | mustacheLastIndex = mustache.lastIndex;
309 | urlLastIndex = url.lastIndex;
310 |
311 | yield result;
312 |
313 | url.lastIndex = urlLastIndex;
314 | mustache.lastIndex = mustacheLastIndex;
315 | }
316 | }
317 | }
318 |
319 | function getInvalidLabel(domain) {
320 | // https://tools.ietf.org/html/rfc1035
321 | // https://serverfault.com/questions/638260/is-it-valid-for-a-hostname-to-start-with-a-digit
322 | let index = 0;
323 | const parts = domain.split(".");
324 | for (const part of parts) {
325 | if (
326 | !part ||
327 | part.startsWith("-") ||
328 | part.endsWith("-")
329 | ) {
330 | return {
331 | index,
332 | value: part
333 | };
334 | }
335 | index += part.length + 1;
336 | }
337 | }
338 |
339 | module.exports = {
340 | UrlMatcher
341 | };
342 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "linkify-plus-plus-core",
3 | "version": "0.7.0",
4 | "description": "A JavaScript library for linkification stuff",
5 | "keywords": [
6 | "linkify"
7 | ],
8 | "homepage": "https://github.com/eight04/linkify-plus-plus-core",
9 | "bugs": {
10 | "url": "https://github.com/eight04/linkify-plus-plus-core/issues",
11 | "email": "eight04@gmail.com"
12 | },
13 | "license": "BSD-3-Clause",
14 | "author": "eight ",
15 | "main": "index.js",
16 | "repository": "eight04/linkify-plus-plus-core",
17 | "devDependencies": {
18 | "@open-wc/testing": "^4.0.0",
19 | "@rollup/plugin-json": "^6.1.0",
20 | "@rollup/plugin-node-resolve": "^16.0.0",
21 | "@rollup/plugin-terser": "^0.4.4",
22 | "@web/dev-server": "^0.4.6",
23 | "@web/dev-server-rollup": "^0.6.4",
24 | "@web/test-runner": "^0.20.0",
25 | "@web/test-runner-commands": "^0.9.0",
26 | "c8": "^10.1.3",
27 | "cheerio": "^1.0.0",
28 | "eslint": "^9.20.1",
29 | "eslint-plugin-compat": "^6.0.2",
30 | "rollup": "^4.34.8",
31 | "rollup-plugin-cjs-es": "^3.0.0"
32 | },
33 | "scripts": {
34 | "build-tlds": "node build-tlds.js > lib/tlds.json",
35 | "build": "rollup -c",
36 | "test": "eslint . && npm run build && web-test-runner test/*",
37 | "test-cover": "npm test -- --coverage",
38 | "preversion": "npm test",
39 | "version": "npm run build && git add .",
40 | "postversion": "git push --follow-tags && npm publish"
41 | },
42 | "dependencies": {
43 | "event-lite": "^1.0.0"
44 | },
45 | "browserslist": [
46 | "Firefox >= 56"
47 | ],
48 | "eslintIgnore": [
49 | "dist"
50 | ],
51 | "files": [
52 | "dist",
53 | "lib"
54 | ]
55 | }
56 |
--------------------------------------------------------------------------------
/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import cjs from "rollup-plugin-cjs-es";
2 | import resolve from "@rollup/plugin-node-resolve";
3 | import terser from "@rollup/plugin-terser";
4 | import json from "@rollup/plugin-json";
5 |
6 | export default [
7 | createConfig({
8 | output: {file: "dist/linkify-plus-plus-core.js"}
9 | }),
10 | createConfig({
11 | output: {file: "dist/linkify-plus-plus-core.esm.js", format: "es"}
12 | }),
13 | createConfig({
14 | output: {file: "dist/linkify-plus-plus-core.min.js"},
15 | plugins: [
16 | terser({
17 | compress: {
18 | passes: 3
19 | }
20 | })
21 | ]
22 | })
23 | ];
24 |
25 | function createConfig({output, plugins = []}) {
26 | return {
27 | input: "index.js",
28 | output: {
29 | format: "iife",
30 | name: "linkifyPlusPlusCore",
31 | sourcemap: true,
32 | ...output
33 | },
34 | plugins: [
35 | resolve(),
36 | json(),
37 | cjs({
38 | nested: true
39 | }),
40 | ...plugins
41 | ]
42 | };
43 | }
44 |
--------------------------------------------------------------------------------
/test/__snapshots__/test.snap.js:
--------------------------------------------------------------------------------
1 | /* @web/test-runner snapshot v1 */
2 | export const snapshots = {};
3 |
4 | snapshots["recursive off"] =
5 | `example.com example.com`;
6 | /* end snapshot recursive off */
7 |
8 | snapshots["basic"] =
9 | `example.com example.com`;
10 | /* end snapshot basic */
11 |
12 | snapshots["wbr"] =
13 | `example.com`;
14 | /* end snapshot wbr */
15 |
16 | snapshots["invalid tags"] =
17 | ``;
18 | /* end snapshot invalid tags */
19 |
20 |
--------------------------------------------------------------------------------
/test/test.mjs:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha browser */
2 | import {assert} from "@open-wc/testing";
3 | import {compareSnapshot} from "@web/test-runner-commands";
4 |
5 | import {UrlMatcher, linkify} from "../dist/linkify-plus-plus-core.esm.js";
6 |
7 | describe("UrlMatcher", () => {
8 |
9 | function prepare(options) {
10 | var matcher = new UrlMatcher(options),
11 | match = (text, start = 0, end = text.length) => {
12 | if (end <= 0) {
13 | end += text.length;
14 | }
15 | var [result] = matcher.match(text);
16 | assert.equal(result.start, start);
17 | assert.equal(result.end, end);
18 | return result;
19 | };
20 |
21 | match.no = (text) => {
22 | var [result] = matcher.match(text);
23 | assert.equal(result, undefined);
24 | };
25 |
26 | return match;
27 | }
28 |
29 | var match = prepare();
30 |
31 | it("basic", () => {
32 | match("http://example.com");
33 | match("http://example.com/");
34 | match("http://example.com/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-.~!$&*+;=:@%/?#(),'[]");
35 | match("test@google.com");
36 | });
37 |
38 | it("domain", () => {
39 | match("http://exa-mple.com");
40 | });
41 |
42 | it("braces", () => {
43 | match("(http://example.com)", 1, -1);
44 | match("http://example.com)", 0, -1);
45 | match("http://example.com/(foo)");
46 | match("http://example.com/(f o o)", 0, 19);
47 | });
48 |
49 | it("http alias", () => {
50 | assert.equal(match("ttp://example.com").protocol, "http://");
51 | assert.equal(match("h**p://example.com").protocol, "http://");
52 | assert.equal(match("hxxp://example.com").protocol, "http://");
53 | });
54 |
55 | it("IP address", () => {
56 | match("http://127.0.0.1");
57 | match.no("http://127.0.0.256");
58 | match.no("http://127.0.0.01");
59 | });
60 |
61 | it("protocol guessing", () => {
62 | assert.equal(match("example.com").protocol, "http://");
63 | assert.equal(match("user@example.com").protocol, "mailto:");
64 | assert.equal(match("user@www.example.com").protocol, "http://");
65 | assert.equal(match("user:pass@example.com").protocol, "http://");
66 | assert.equal(match("user@example.com/path/").protocol, "http://");
67 | assert.equal(match("ftp.example.com").protocol, "ftp://");
68 | assert.equal(match("irc.example.com").protocol, "irc://");
69 | });
70 |
71 | it("dots", () => {
72 | match("http://example.com.", 0, -1);
73 | match("http://example.com..", 0, -2);
74 | match("http://example.com...", 0, -3);
75 | match("http://example.com/.", 0, -1);
76 | match("http://example.com/..", 0, -2);
77 | match("http://example.com/...", 0, -3);
78 | });
79 |
80 | it("question mark", () => {
81 | match("http://example.com?", 0, -1);
82 | });
83 |
84 | it("comma", () => {
85 | match("http://example.com/path,", 0, -1);
86 | match("http://example.com/path,path-continue");
87 | });
88 |
89 | it("bad tlds", () => {
90 | // now .zip is more common
91 | // match.no("http://example.zip");
92 | match.no("http://example.free");
93 | match.no("http://example.call");
94 | match.no("http://example.constructor");
95 | });
96 |
97 | it("ignore bad tlds for unknown protocol", () => {
98 | match("macupdater://com.busymac.busycal3");
99 | });
100 |
101 | it("bbcode", () => {
102 | match("[img]http://example.com[/img]", 5, -6);
103 | match("http://example.com[b]something-else[/b]", 0, 18);
104 | });
105 |
106 | it("mustache", () => {
107 | var match = prepare({ignoreMustache: true});
108 | match.no("{{http://example.com}}");
109 | match.no("{{\nhttp://example.com\n}}");
110 | });
111 |
112 | it("custom rules", () => {
113 | const match = prepare({customRules: [
114 | "magnet:\\?\\S+"
115 | ]});
116 | match("magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a&dn");
117 | });
118 |
119 | it("custom rules should take priority", () => {
120 | const match = prepare({customRules: [
121 | "http://...example\\.com"
122 | ]});
123 | match("http://-.-example.com", 0);
124 | });
125 |
126 | it("no mail", () => {
127 | const match = prepare({mail: false});
128 | match.no("test@google.com");
129 | });
130 |
131 | it("domain with dash or dot", () => {
132 | match("-example.com", 1);
133 | match(".example.com", 1);
134 | match("-.example.com", 2);
135 | });
136 |
137 | it("infinite loop bug", () => {
138 | match("example com example.-invalid.com", 21);
139 | });
140 |
141 | it("match domains starting with numbers", () => {
142 | match("https://1fichier.com");
143 | match("https://9292.nl");
144 | });
145 |
146 | it("onion links", () => {
147 | match("http://example.onion");
148 | });
149 | });
150 |
151 | describe("Linkifier", () => {
152 | let matcher;
153 | let body;
154 | before(() => {
155 | matcher = new UrlMatcher();
156 | body = document.querySelector("body");
157 | });
158 |
159 | it("basic", async () => {
160 | body.innerHTML = "example.com example.com";
161 | await linkify(body, {matcher});
162 | await compareSnapshot({
163 | name: "basic",
164 | content: body.innerHTML
165 | });
166 | });
167 |
168 | it("recursive off", async () => {
169 | body.innerHTML = "example.com example.com";
170 | await linkify(body, {matcher, recursive: false});
171 | await compareSnapshot({
172 | name: "recursive off",
173 | content: body.innerHTML
174 | });
175 | });
176 |
177 | it("wbr", async () => {
178 | body.innerHTML = "example.com";
179 | await linkify(body, {matcher, recursive: false});
180 | await compareSnapshot({
181 | name: "wbr",
182 | content: body.innerHTML
183 | });
184 | });
185 |
186 | it("invalid tags", async () => {
187 | body.innerHTML = "";
188 | await linkify(body, {matcher, recursive: false});
189 | await compareSnapshot({
190 | name: "invalid tags",
191 | content: body.innerHTML
192 | });
193 | });
194 |
195 | });
196 |
--------------------------------------------------------------------------------
/web-test-runner.config.mjs:
--------------------------------------------------------------------------------
1 | // import { fromRollup } from '@web/dev-server-rollup';
2 | // import cjs from 'rollup-plugin-cjs-es';
3 |
4 | export default {
5 | nodeResolve: true,
6 | // FIXME: https://github.com/modernweb-dev/web/issues/2637
7 | // coverageConfig: {
8 | // exclude: [
9 | // "node_modules/**/*",
10 | // ]
11 | // }
12 | // FIXME: https://github.com/modernweb-dev/web/issues/2640
13 | // plugins: [
14 | // [cjs, { nested: true, cache: false, include: ["lib/**/*"]}]
15 | // ].map(([plugin, options]) => fromRollup(plugin)(options))
16 | };
17 |
18 |
--------------------------------------------------------------------------------