diff --git a/benchmark/benchmark.mjs b/benchmark/benchmark.mjs index ba99765..1ae07f8 100755 --- a/benchmark/benchmark.mjs +++ b/benchmark/benchmark.mjs @@ -1,11 +1,11 @@ #!/usr/bin/env node -/*eslint no-console:0*/ +/* eslint-disable no-console */ import { readFileSync, readdirSync } from 'fs' import util from 'node:util' import Benchmark from 'benchmark' import ansi from 'ansi' -const cursor = ansi(process.stdout) +const cursor = ansi(process.stdout) const IMPLS = [] @@ -25,16 +25,15 @@ readdirSync(new URL('./samples', import.meta.url)).sort().forEach(sample => { content.string = readFileSync(filepath, 'utf8') - const title = `(${content.string.length} bytes)` + const title = `(${content.string.length} bytes)` - function onComplete() { + function onComplete () { cursor.write('\n') } - const suite = new Benchmark.Suite(title, { - onStart: function onStart() { + onStart: function onStart () { console.log('\nSample: %s %s', sample, title) }, @@ -42,11 +41,10 @@ readdirSync(new URL('./samples', import.meta.url)).sort().forEach(sample => { }) - IMPLS.forEach(function (impl) { suite.add(impl.name, { - onCycle: function onCycle(event) { + onCycle: function onCycle (event) { cursor.horizontalAbsolute() cursor.eraseLine() cursor.write(' > ' + event.target) @@ -56,12 +54,10 @@ readdirSync(new URL('./samples', import.meta.url)).sort().forEach(sample => { fn: function () { impl.code.run(content.string) - return } }) }) - SAMPLES.push({ name: sample.split('.')[0], title: title, @@ -70,15 +66,14 @@ readdirSync(new URL('./samples', import.meta.url)).sort().forEach(sample => { }) }) - -function select(patterns) { +function select (patterns) { const result = [] if (!(patterns instanceof Array)) { - patterns = [ patterns ] + patterns = [patterns] } - function checkName(name) { + function checkName (name) { return patterns.length === 0 || patterns.some(function (regexp) { return regexp.test(name) }) @@ -93,8 +88,7 @@ function select(patterns) { return result } - -function run(files) { +function run (files) { const selected = select(files) if (selected.length > 0) { diff --git a/benchmark/implementations/current-match/index.mjs b/benchmark/implementations/current-match/index.mjs index caa5611..8a4ea51 100644 --- a/benchmark/implementations/current-match/index.mjs +++ b/benchmark/implementations/current-match/index.mjs @@ -3,6 +3,6 @@ const linkify = linkifyit() linkify.test('') -export function run(data) { +export function run (data) { return linkify.match(data) } diff --git a/benchmark/implementations/current-pretest/index.mjs b/benchmark/implementations/current-pretest/index.mjs index 0ec17d9..8c5b875 100644 --- a/benchmark/implementations/current-pretest/index.mjs +++ b/benchmark/implementations/current-pretest/index.mjs @@ -3,6 +3,6 @@ const linkify = linkifyit() linkify.test('') -export function run(data) { +export function run (data) { return linkify.pretest(data) } diff --git a/benchmark/implementations/current-test/index.mjs b/benchmark/implementations/current-test/index.mjs index d3d13b5..c4ca744 100644 --- a/benchmark/implementations/current-test/index.mjs +++ b/benchmark/implementations/current-test/index.mjs @@ -3,6 +3,6 @@ const linkify = linkifyit() linkify.test('') -export function run(data) { +export function run (data) { return linkify.test(data) } diff --git a/benchmark/profile.mjs b/benchmark/profile.mjs index 30b2a21..d05e18c 100755 --- a/benchmark/profile.mjs +++ b/benchmark/profile.mjs @@ -1,12 +1,12 @@ #!/usr/bin/env node -/*eslint-disable no-console*/ +/* eslint-disable no-console */ import { readFileSync } from 'fs' import linkifyit from '../index.mjs' const linkify = linkifyit() -// Forse compilation +// Force compilation linkify.test('') const data = readFileSync(new URL('/samples/lorem1.txt', import.meta.url), 'utf8') diff --git a/index.mjs b/index.mjs index d502ae4..233642b 100644 --- a/index.mjs +++ b/index.mjs @@ -1,12 +1,12 @@ import reFactory from './lib/re.mjs' - -//////////////////////////////////////////////////////////////////////////////// +// // Helpers +// // Merge objects // -function assign(obj /*from1, from2, from3, ...*/) { +function assign (obj /* from1, from2, from3, ... */) { const sources = Array.prototype.slice.call(arguments, 1) sources.forEach(function (source) { @@ -20,17 +20,15 @@ function assign(obj /*from1, from2, from3, ...*/) { return obj } -function _class(obj) { return Object.prototype.toString.call(obj) } -function isString(obj) { return _class(obj) === '[object String]' } -function isObject(obj) { return _class(obj) === '[object Object]' } -function isRegExp(obj) { return _class(obj) === '[object RegExp]' } -function isFunction(obj) { return _class(obj) === '[object Function]' } +function _class (obj) { return Object.prototype.toString.call(obj) } +function isString (obj) { return _class(obj) === '[object String]' } +function isObject (obj) { return _class(obj) === '[object Object]' } +function isRegExp (obj) { return _class(obj) === '[object RegExp]' } +function isFunction (obj) { return _class(obj) === '[object Function]' } +function escapeRE (str) { return str.replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&') } -function escapeRE(str) { return str.replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&') } - -//////////////////////////////////////////////////////////////////////////////// - +// const defaultOptions = { fuzzyLink: true, @@ -38,14 +36,13 @@ const defaultOptions = { fuzzyIP: false } - -function isOptionsObj(obj) { +function isOptionsObj (obj) { return Object.keys(obj || {}).reduce(function (acc, k) { + /* eslint-disable-next-line no-prototype-builtins */ return acc || defaultOptions.hasOwnProperty(k) }, false) } - const defaultSchemas = { 'http:': { validate: function (text, pos, self) { @@ -53,7 +50,7 @@ const defaultSchemas = { if (!self.re.http) { // compile lazily, because "host"-containing variables can change on tlds update. - self.re.http = new RegExp( + self.re.http = new RegExp( '^\\/\\/' + self.re.src_auth + self.re.src_host_port_strict + self.re.src_path, 'i' ) } @@ -63,15 +60,15 @@ const defaultSchemas = { return 0 } }, - 'https:': 'http:', - 'ftp:': 'http:', - '//': { + 'https:': 'http:', + 'ftp:': 'http:', + '//': { validate: function (text, pos, self) { const tail = text.slice(pos) if (!self.re.no_http) { // compile lazily, because "host"-containing variables can change on tlds update. - self.re.no_http = new RegExp( + self.re.no_http = new RegExp( '^' + self.re.src_auth + // Don't allow single-level domains, because of false positives like '//test' @@ -99,7 +96,7 @@ const defaultSchemas = { const tail = text.slice(pos) if (!self.re.mailto) { - self.re.mailto = new RegExp( + self.re.mailto = new RegExp( '^' + self.re.src_email_name + '@' + self.re.src_host_strict, 'i' ) } @@ -111,24 +108,19 @@ const defaultSchemas = { } } -/*eslint-disable max-len*/ - // RE pattern for 2-character tlds (autogenerated by ./support/tlds_2char_gen.js) +/* eslint-disable-next-line max-len */ const tlds_2ch_src_re = 'a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]' // DON'T try to make PRs with changes. Extend TLDs with LinkifyIt.tlds() instead const tlds_default = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|') -/*eslint-enable max-len*/ - -//////////////////////////////////////////////////////////////////////////////// - -function resetScanCache(self) { +function resetScanCache (self) { self.__index__ = -1 - self.__text_cache__ = '' + self.__text_cache__ = '' } -function createValidator(re) { +function createValidator (re) { return function (text, pos) { const tail = text.slice(pos) @@ -139,7 +131,7 @@ function createValidator(re) { } } -function createNormalizer() { +function createNormalizer () { return function (match, self) { self.normalize(match) } @@ -147,7 +139,7 @@ function createNormalizer() { // Schemas compiler. Build regexps. // -function compile(self) { +function compile (self) { // Load & clone RE patterns. const re = self.re = reFactory(self.__opts__) @@ -164,12 +156,12 @@ function compile(self) { re.src_tlds = tlds.join('|') - function untpl(tpl) { return tpl.replace('%TLDS%', re.src_tlds) } + function untpl (tpl) { return tpl.replace('%TLDS%', re.src_tlds) } - re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), 'i') - re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), 'i') + re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), 'i') + re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), 'i') re.link_no_ip_fuzzy = RegExp(untpl(re.tpl_link_no_ip_fuzzy), 'i') - re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), 'i') + re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), 'i') // // Compile each schema @@ -179,7 +171,7 @@ function compile(self) { self.__compiled__ = {} // Reset compiled data - function schemaError(name, val) { + function schemaError (name, val) { throw new Error('(LinkifyIt) Invalid schema "' + name + '": ' + val) } @@ -254,8 +246,8 @@ function compile(self) { .map(escapeRE) .join('|') // (?!_) cause 1.5x slowdown - self.re.schema_test = RegExp('(^|(?!_)(?:[><\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'i') - self.re.schema_search = RegExp('(^|(?!_)(?:[><\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'ig') + self.re.schema_test = RegExp('(^|(?!_)(?:[><\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'i') + self.re.schema_search = RegExp('(^|(?!_)(?:[><\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'ig') self.re.schema_at_start = RegExp('^' + self.re.schema_search.source, 'i') self.re.pretest = RegExp( @@ -275,23 +267,23 @@ function compile(self) { * * Match result. Single element of array, returned by [[LinkifyIt#match]] **/ -function Match(self, shift) { +function Match (self, shift) { const start = self.__index__ - const end = self.__last_index__ - const text = self.__text_cache__.slice(start, end) + const end = self.__last_index__ + const text = self.__text_cache__.slice(start, end) /** * Match#schema -> String * * Prefix (protocol) for matched string. **/ - this.schema = self.__schema__.toLowerCase() + this.schema = self.__schema__.toLowerCase() /** * Match#index -> Number * * First position of matched string. **/ - this.index = start + shift + this.index = start + shift /** * Match#lastIndex -> Number * @@ -303,22 +295,22 @@ function Match(self, shift) { * * Matched string. **/ - this.raw = text + this.raw = text /** * Match#text -> String * * Notmalized text of matched string. **/ - this.text = text + this.text = text /** * Match#url -> String * * Normalized url of matched string. **/ - this.url = text + this.url = text } -function createMatch(self, shift) { +function createMatch (self, shift) { const match = new Match(self, shift) self.__compiled__[match.schema].normalize(match, self) @@ -326,7 +318,6 @@ function createMatch(self, shift) { return match } - /** * class LinkifyIt **/ @@ -365,7 +356,7 @@ function createMatch(self, shift) { * - __fuzzyEmail__ - recognize emails without `mailto:` prefix. * **/ -function LinkifyIt(schemas, options) { +function LinkifyIt (schemas, options) { if (!(this instanceof LinkifyIt)) { return new LinkifyIt(schemas, options) } @@ -377,26 +368,25 @@ function LinkifyIt(schemas, options) { } } - this.__opts__ = assign({}, defaultOptions, options) + this.__opts__ = assign({}, defaultOptions, options) // Cache last tested result. Used to skip repeating steps on next `match` call. - this.__index__ = -1 - this.__last_index__ = -1 // Next scan position - this.__schema__ = '' - this.__text_cache__ = '' + this.__index__ = -1 + this.__last_index__ = -1 // Next scan position + this.__schema__ = '' + this.__text_cache__ = '' - this.__schemas__ = assign({}, defaultSchemas, schemas) - this.__compiled__ = {} + this.__schemas__ = assign({}, defaultSchemas, schemas) + this.__compiled__ = {} - this.__tlds__ = tlds_default - this.__tlds_replaced__ = false + this.__tlds__ = tlds_default + this.__tlds_replaced__ = false this.re = {} compile(this) } - /** chainable * LinkifyIt#add(schema, definition) * - schema (String): rule name (fixed pattern prefix) @@ -404,34 +394,32 @@ function LinkifyIt(schemas, options) { * * Add new rule definition. See constructor description for details. **/ -LinkifyIt.prototype.add = function add(schema, definition) { +LinkifyIt.prototype.add = function add (schema, definition) { this.__schemas__[schema] = definition compile(this) return this } - /** chainable * LinkifyIt#set(options) * - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false } * * Set recognition options for links without schema. **/ -LinkifyIt.prototype.set = function set(options) { +LinkifyIt.prototype.set = function set (options) { this.__opts__ = assign(this.__opts__, options) return this } - /** * LinkifyIt#test(text) -> Boolean * * Searches linkifiable pattern and returns `true` on success or `false` on fail. **/ -LinkifyIt.prototype.test = function test(text) { +LinkifyIt.prototype.test = function test (text) { // Reset scan cache this.__text_cache__ = text - this.__index__ = -1 + this.__index__ = -1 if (!text.length) { return false } @@ -444,8 +432,8 @@ LinkifyIt.prototype.test = function test(text) { while ((m = re.exec(text)) !== null) { len = this.testSchemaAt(text, m[2], re.lastIndex) if (len) { - this.__schema__ = m[2] - this.__index__ = m.index + m[1].length + this.__schema__ = m[2] + this.__index__ = m.index + m[1].length this.__last_index__ = m.index + m[0].length + len break } @@ -463,8 +451,8 @@ LinkifyIt.prototype.test = function test(text) { shift = ml.index + ml[1].length if (this.__index__ < 0 || shift < this.__index__) { - this.__schema__ = '' - this.__index__ = shift + this.__schema__ = '' + this.__index__ = shift this.__last_index__ = ml.index + ml[0].length } } @@ -481,12 +469,12 @@ LinkifyIt.prototype.test = function test(text) { if ((me = text.match(this.re.email_fuzzy)) !== null) { shift = me.index + me[1].length - next = me.index + me[0].length + next = me.index + me[0].length if (this.__index__ < 0 || shift < this.__index__ || (shift === this.__index__ && next > this.__last_index__)) { - this.__schema__ = 'mailto:' - this.__index__ = shift + this.__schema__ = 'mailto:' + this.__index__ = shift this.__last_index__ = next } } @@ -496,7 +484,6 @@ LinkifyIt.prototype.test = function test(text) { return this.__index__ >= 0 } - /** * LinkifyIt#pretest(text) -> Boolean * @@ -504,11 +491,10 @@ LinkifyIt.prototype.test = function test(text) { * can exists. Can be used for speed optimization, when you need to check that * link NOT exists. **/ -LinkifyIt.prototype.pretest = function pretest(text) { +LinkifyIt.prototype.pretest = function pretest (text) { return this.re.pretest.test(text) } - /** * LinkifyIt#testSchemaAt(text, name, position) -> Number * - text (String): text to scan @@ -518,7 +504,7 @@ LinkifyIt.prototype.pretest = function pretest(text) { * Similar to [[LinkifyIt#test]] but checks only specific protocol tail exactly * at given position. Returns length of found pattern (0 on fail). **/ -LinkifyIt.prototype.testSchemaAt = function testSchemaAt(text, schema, pos) { +LinkifyIt.prototype.testSchemaAt = function testSchemaAt (text, schema, pos) { // If not supported schema check requested - terminate if (!this.__compiled__[schema.toLowerCase()]) { return 0 @@ -526,7 +512,6 @@ LinkifyIt.prototype.testSchemaAt = function testSchemaAt(text, schema, pos) { return this.__compiled__[schema.toLowerCase()].validate(text, pos, this) } - /** * LinkifyIt#match(text) -> Array|null * @@ -543,7 +528,7 @@ LinkifyIt.prototype.testSchemaAt = function testSchemaAt(text, schema, pos) { * - __text__ - normalized text * - __url__ - link, generated from matched text **/ -LinkifyIt.prototype.match = function match(text) { +LinkifyIt.prototype.match = function match (text) { const result = [] let shift = 0 @@ -571,17 +556,16 @@ LinkifyIt.prototype.match = function match(text) { return null } - /** * LinkifyIt#matchAtStart(text) -> Match|null * * Returns fully-formed (not fuzzy) link if it starts at the beginning * of the string, and null otherwise. **/ -LinkifyIt.prototype.matchAtStart = function matchAtStart(text) { +LinkifyIt.prototype.matchAtStart = function matchAtStart (text) { // Reset scan cache this.__text_cache__ = text - this.__index__ = -1 + this.__index__ = -1 if (!text.length) return null @@ -591,14 +575,13 @@ LinkifyIt.prototype.matchAtStart = function matchAtStart(text) { const len = this.testSchemaAt(text, m[2], m[0].length) if (!len) return null - this.__schema__ = m[2] - this.__index__ = m.index + m[1].length + this.__schema__ = m[2] + this.__index__ = m.index + m[1].length this.__last_index__ = m.index + m[0].length + len return createMatch(this, 0) } - /** chainable * LinkifyIt#tlds(list [, keepOld]) -> this * - list (Array): list of tlds @@ -614,8 +597,8 @@ LinkifyIt.prototype.matchAtStart = function matchAtStart(text) { * * If list is replaced, then exact match for 2-chars root zones will be checked. **/ -LinkifyIt.prototype.tlds = function tlds(list, keepOld) { - list = Array.isArray(list) ? list : [ list ] +LinkifyIt.prototype.tlds = function tlds (list, keepOld) { + list = Array.isArray(list) ? list : [list] if (!keepOld) { this.__tlds__ = list.slice() @@ -640,7 +623,7 @@ LinkifyIt.prototype.tlds = function tlds(list, keepOld) { * * Default normalizer (if schema does not define it's own). **/ -LinkifyIt.prototype.normalize = function normalize(match) { +LinkifyIt.prototype.normalize = function normalize (match) { // Do minimal possible changes by default. Need to collect feedback prior // to move forward https://github.com/markdown-it/linkify-it/issues/1 @@ -652,14 +635,12 @@ LinkifyIt.prototype.normalize = function normalize(match) { } } - /** * LinkifyIt#onCompile() * * Override to modify basic RegExp-s. **/ -LinkifyIt.prototype.onCompile = function onCompile() { +LinkifyIt.prototype.onCompile = function onCompile () { } - export default LinkifyIt diff --git a/lib/re.mjs b/lib/re.mjs index 2309714..92d12da 100644 --- a/lib/re.mjs +++ b/lib/re.mjs @@ -4,17 +4,16 @@ export default function (opts) { const re = {} opts = opts || {} - // Use direct extract instead of `regenerate` to reduse browserified size re.src_Any = Any.source - re.src_Cc = Cc.source - re.src_Z = Z.source - re.src_P = P.source + re.src_Cc = Cc.source + re.src_Z = Z.source + re.src_P = P.source // \p{\Z\P\Cc\CF} (white spaces + control + format + punctuation) - re.src_ZPCc = [ re.src_Z, re.src_P, re.src_Cc ].join('|') + re.src_ZPCc = [re.src_Z, re.src_P, re.src_Cc].join('|') // \p{\Z\Cc} (white spaces + control) - re.src_ZCc = [ re.src_Z, re.src_Cc ].join('|') + re.src_ZCc = [re.src_Z, re.src_Cc].join('|') // Experimental. List of chars, completely prohibited in links // because can separate it from other part of text @@ -23,18 +22,16 @@ export default function (opts) { // All possible word characters (everything without punctuation, spaces & controls) // Defined via punctuation & spaces to save space // Should be something like \p{\L\N\S\M} (\w but without `_`) - re.src_pseudo_letter = '(?:(?!' + text_separators + '|' + re.src_ZPCc + ')' + re.src_Any + ')' + re.src_pseudo_letter = '(?:(?!' + text_separators + '|' + re.src_ZPCc + ')' + re.src_Any + ')' // The same as abothe but without [0-9] // var src_pseudo_letter_non_d = '(?:(?![0-9]|' + src_ZPCc + ')' + src_Any + ')'; - //////////////////////////////////////////////////////////////////////////////// - re.src_ip4 = '(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' // Prohibit any of "@/[]()" in user/pass to avoid wrong domain fetch. - re.src_auth = '(?:(?:(?!' + re.src_ZCc + '|[@/\\[\\]()]).)+@)?' + re.src_auth = '(?:(?:(?!' + re.src_ZCc + '|[@/\\[\\]()]).)+@)?' re.src_port = @@ -56,24 +53,34 @@ export default function (opts) { '\\{(?:(?!' + re.src_ZCc + '|[}]).)*\\}|' + '\\"(?:(?!' + re.src_ZCc + '|["]).)+\\"|' + "\\'(?:(?!" + re.src_ZCc + "|[']).)+\\'|" + - "\\'(?=" + re.src_pseudo_letter + '|[-])|' + // allow `I'm_king` if no pair found - '\\.{2,}[a-zA-Z0-9%/&]|' + // google has many dots in "google search" links (#66, #81). - // github has ... in commit range links, - // Restrict to - // - english - // - percent-encoded - // - parts of file path - // - params separator - // until more examples found. + + // allow `I'm_king` if no pair found + "\\'(?=" + re.src_pseudo_letter + '|[-])|' + + + // google has many dots in "google search" links (#66, #81). + // github has ... in commit range links, + // Restrict to + // - english + // - percent-encoded + // - parts of file path + // - params separator + // until more examples found. + '\\.{2,}[a-zA-Z0-9%/&]|' + + '\\.(?!' + re.src_ZCc + '|[.]|$)|' + - (opts['---'] ? - '\\-(?!--(?:[^-]|$))(?:-*)|' // `---` => long dash, terminate - : - '\\-+|' + (opts['---'] + ? '\\-(?!--(?:[^-]|$))(?:-*)|' // `---` => long dash, terminate + : '\\-+|' ) + - ',(?!' + re.src_ZCc + '|$)|' + // allow `,,,` in paths - ';(?!' + re.src_ZCc + '|$)|' + // allow `;` if not followed by space-like char - '\\!+(?!' + re.src_ZCc + '|[!]|$)|' + // allow `!!!` in paths, but not at the end + // allow `,,,` in paths + ',(?!' + re.src_ZCc + '|$)|' + + + // allow `;` if not followed by space-like char + ';(?!' + re.src_ZCc + '|$)|' + + + // allow `!!!` in paths, but not at the end + '\\!+(?!' + re.src_ZCc + '|[!]|$)|' + + '\\?(?!' + re.src_ZCc + '|[?]|$)' + ')+' + '|\\/' + @@ -117,7 +124,7 @@ export default function (opts) { // Don't need IP check, because digits are already allowed in normal domain names // src_ip4 + // '|' + - '(?:(?:(?:' + re.src_domain + ')\\.)*' + re.src_domain/*_root*/ + ')' + + '(?:(?:(?:' + re.src_domain + ')\\.)*' + re.src_domain/* _root */ + ')' + ')' re.tpl_host_fuzzy = @@ -152,9 +159,9 @@ export default function (opts) { re.tpl_host_no_ip_fuzzy + re.src_port + re.src_host_terminator - - //////////////////////////////////////////////////////////////////////////////// + // // Main rules + // // Rude test fuzzy links by host, for quick deny re.tpl_host_fuzzy_test = diff --git a/support/build_demo.mjs b/support/build_demo.mjs index ea18ac5..1720cfa 100644 --- a/support/build_demo.mjs +++ b/support/build_demo.mjs @@ -3,7 +3,7 @@ import shell from 'shelljs' import { readFileSync, writeFileSync } from 'fs' -function escape(input) { +function escape (input) { return input .replaceAll('&', '&') .replaceAll('<', '<') @@ -25,8 +25,8 @@ let sample_links = readFileSync('test/fixtures/links.txt', 'utf8') // Cleanup const lines = sample_links.split(/\r?\n/g) const result = [] -function isComment(str) { return /^%.*/.test(str) } -function isEmpty(str) { return !(str && str.trim()) } +function isComment (str) { return /^%.*/.test(str) } +function isEmpty (str) { return !(str && str.trim()) } for (let i = 0; i < lines.length; i++) { const line = lines[i] diff --git a/support/demo_template/index.mjs b/support/demo_template/index.mjs index 236050b..fd3c9b1 100644 --- a/support/demo_template/index.mjs +++ b/support/demo_template/index.mjs @@ -1,21 +1,21 @@ -/*eslint-env browser*/ -/*global $, _*/ +/* eslint-env browser */ +/* global $, _ */ import linkifyit from '../../index.mjs' import * as mdurl from 'mdurl' const linkify = linkifyit({ fuzzyIP: true }) let permalink -function escape(str) { +function escape (str) { return str.replace(/&/g, '&').replace(//g, '>') } -function setLinkifiedContent(selector, content) { +function setLinkifiedContent (selector, content) { let out = escape(content) const matches = linkify.match(content) if (matches) { - const result = [] + const result = [] let last = 0 matches.forEach(function (match) { if (last < match.index) { @@ -37,7 +37,7 @@ function setLinkifiedContent(selector, content) { $(selector).html(out) } -function updateResult() { +function updateResult () { const source = $('.source').val() setLinkifiedContent('.result-html', source) @@ -49,8 +49,7 @@ function updateResult() { } } - -////////////////////////////////////////////////////////////////////////////// +// // Init on page load // $(function () { diff --git a/support/demodata.mjs b/support/demodata.mjs index 5eff999..0c41059 100755 --- a/support/demodata.mjs +++ b/support/demodata.mjs @@ -2,12 +2,12 @@ // Build demo data for embedding into html -/*eslint no-console:0*/ +/* eslint no-console:0 */ import { readFileSync } from 'fs' -function isComment(str) { return /^%.*/.test(str) } -function isEmpty(str) { return !(str && str.trim()) } +function isComment (str) { return /^%.*/.test(str) } +function isEmpty (str) { return !(str && str.trim()) } let result = [] diff --git a/support/test.mjs b/support/test.mjs index 8dee44b..895fe0a 100755 --- a/support/test.mjs +++ b/support/test.mjs @@ -1,5 +1,5 @@ #!/usr/bin/env node -/*eslint-disable no-console*/ +/* eslint-disable no-console */ import linkifyit from '../index.mjs' import { inspect } from 'node:util' diff --git a/support/tlds_2char_gen.mjs b/support/tlds_2char_gen.mjs index eed4a65..a1d0b7b 100755 --- a/support/tlds_2char_gen.mjs +++ b/support/tlds_2char_gen.mjs @@ -5,14 +5,14 @@ // Code is dirty, i know, but it's needed only once // -/*eslint-disable no-console*/ +/* eslint-disable no-console */ import { createRequire } from 'node:module' const require = createRequire(import.meta.url) const tldList = require('tlds') -function toRanges(str) { +function toRanges (str) { const ranges = [] str = str.slice(1, -1) diff --git a/test/test.mjs b/test/test.mjs index 3d3e7ff..2b3d1d2 100644 --- a/test/test.mjs +++ b/test/test.mjs @@ -9,7 +9,6 @@ const tlds = require('tlds') let lines - describe('links', function () { const l = linkify({ fuzzyIP: true }) @@ -52,7 +51,6 @@ describe('links', function () { }) - describe('not links', function () { const l = linkify() @@ -93,7 +91,6 @@ describe('API', function () { assert.ok(!l.test('google.myroot')) }) - it('add rule as regexp, with default normalizer', function () { const l = linkify().add('my:', { validate: /^\/\/[a-z]+/ @@ -105,13 +102,12 @@ describe('API', function () { assert.strictEqual(match[1].text, 'my://asdf') }) - it('add rule with normalizer', function () { const l = linkify().add('my:', { validate: /^\/\/[a-z]+/, normalize: function (m) { m.text = m.text.replace(/^my:\/\//, '').toUpperCase() - m.url = m.url.toUpperCase() + m.url = m.url.toUpperCase() } }) @@ -121,7 +117,6 @@ describe('API', function () { assert.strictEqual(match[1].url, 'MY://ASDF') }) - it('disable rule', function () { const l = linkify() @@ -133,7 +128,6 @@ describe('API', function () { assert.ok(!l.test('foo@bar.com')) }) - it('add bad definition', function () { let l @@ -159,7 +153,6 @@ describe('API', function () { }) }) - it('test at position', function () { const l = linkify() @@ -170,7 +163,6 @@ describe('API', function () { assert.ok(!l.testSchemaAt('http://google.com', 'bad_schema:', 6)) }) - it('correct cache value', function () { const l = linkify() @@ -181,29 +173,27 @@ describe('API', function () { assert.strictEqual(match[2].text, 'ftp://google.com') }) - it('normalize', function () { const l = linkify() let m = l.match('mailto:foo@bar.com')[0] // assert.strictEqual(m.text, 'foo@bar.com'); - assert.strictEqual(m.url, 'mailto:foo@bar.com') + assert.strictEqual(m.url, 'mailto:foo@bar.com') m = l.match('foo@bar.com')[0] // assert.strictEqual(m.text, 'foo@bar.com'); - assert.strictEqual(m.url, 'mailto:foo@bar.com') + assert.strictEqual(m.url, 'mailto:foo@bar.com') }) - it('test @twitter rule', function () { const l = linkify().add('@', { validate: function (text, pos, self) { const tail = text.slice(pos) if (!self.re.twitter) { - self.re.twitter = new RegExp( + self.re.twitter = new RegExp( '^([a-zA-Z0-9_]){1,15}(?!_)(?=$|' + self.re.src_ZPCc + ')' ) } @@ -226,7 +216,6 @@ describe('API', function () { assert.ok(!l.test('@@invalid')) }) - it('set option: fuzzyLink', function () { const l = linkify({ fuzzyLink: false }) @@ -238,7 +227,6 @@ describe('API', function () { assert.strictEqual(l.match('google.com.')[0].text, 'google.com') }) - it('set option: fuzzyEmail', function () { const l = linkify({ fuzzyEmail: false }) @@ -250,7 +238,6 @@ describe('API', function () { assert.strictEqual(l.match('foo@bar.com.')[0].text, 'foo@bar.com') }) - it('set option: fuzzyIP', function () { const l = linkify() @@ -270,7 +257,6 @@ describe('API', function () { l.match('😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡😡 .com') }) - it('should accept `---` if enabled', function () { let l = linkify()