tooot/src/modules/autolinker/matcher/url-matcher.js.map

1 line
21 KiB
Plaintext

{"version":3,"sources":["../src/matcher/url-matcher.ts"],"names":[],"mappings":"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","file":"url-matcher.js","sourcesContent":["import { Matcher, MatcherConfig } from \"./matcher\";\nimport { alphaNumericCharsStr, alphaNumericAndMarksCharsStr, getDomainNameStr } from \"../regex-lib\";\nimport { StripPrefixConfigObj, UrlMatchTypeOptions } from \"../autolinker\";\nimport { tldRegex } from \"./tld-regex\";\nimport { UrlMatch } from \"../match/url-match\";\nimport { UrlMatchValidator } from \"./url-match-validator\";\nimport { Match } from \"../match/match\";\n\n// RegExp objects which are shared by all instances of UrlMatcher. These are\n// here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is\n// called multiple times, thus instantiating UrlMatcher and its RegExp \n// objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314). \n// See descriptions of the properties where they are used for details about them\nconst matcherRegex = (function() {\n\tlet schemeRegex = /(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\\/\\/)(?!\\d+\\/?)(?:\\/\\/)?)/, // match protocol, allow in format \"http://\" or \"mailto:\". However, do not match the first part of something like 'link:http://www.google.com' (i.e. don't match \"link:\"). Also, make sure we don't interpret 'google.com:8000' as if 'google.com' was a protocol here (i.e. ignore a trailing port number in this regex)\n\t\twwwRegex = /(?:www\\.)/, // starting with 'www.'\n\n\t\t// Allow optional path, query string, and hash anchor, not ending in the following characters: \"?!:,.;\"\n\t\t// http://blog.codinghorror.com/the-problem-with-urls/\n\t\turlSuffixRegex = new RegExp( '[/?#](?:[' + alphaNumericAndMarksCharsStr + '\\\\-+&@#/%=~_()|\\'$*\\\\[\\\\]{}?!:,.;^\\u2713]*[' + alphaNumericAndMarksCharsStr + '\\\\-+&@#/%=~_()|\\'$*\\\\[\\\\]{}\\u2713])?' );\n\n\treturn new RegExp( [\n\t\t'(?:', // parens to cover match for scheme (optional), and domain\n\t\t\t'(', // *** Capturing group $1, for a scheme-prefixed url (ex: http://google.com)\n\t\t\t\tschemeRegex.source,\n\t\t\t\tgetDomainNameStr( 2 ),\n\t\t\t')',\n\n\t\t\t'|',\n\n\t\t\t'(', // *** Capturing group $4 for a 'www.' prefixed url (ex: www.google.com)\n\t\t\t\t'(//)?', // *** Capturing group $5 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character (handled later)\n\t\t\t\twwwRegex.source,\n\t\t\t\tgetDomainNameStr(6),\n\t\t\t')',\n\n\t\t\t'|',\n\n\t\t\t'(', // *** Capturing group $8, for known a TLD url (ex: google.com)\n\t\t\t\t'(//)?', // *** Capturing group $9 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character (handled later)\n\t\t\t\tgetDomainNameStr(10) + '\\\\.',\n\t\t\t\ttldRegex.source,\n\t\t\t\t'(?![-' + alphaNumericCharsStr + '])', // TLD not followed by a letter, behaves like unicode-aware \\b\n\t\t\t')',\n\t\t')',\n\n\t\t'(?::[0-9]+)?', // port\n\n\t\t'(?:' + urlSuffixRegex.source + ')?' // match for path, query string, and/or hash anchor - optional\n\t].join( \"\" ), 'gi' );\n} )();\n\nconst wordCharRegExp = new RegExp( '[' + alphaNumericAndMarksCharsStr + ']' );\n\n/**\n * @class Autolinker.matcher.Url\n * @extends Autolinker.matcher.Matcher\n *\n * Matcher to find URL matches in an input string.\n *\n * See this class's superclass ({@link Autolinker.matcher.Matcher}) for more details.\n */\nexport class UrlMatcher extends Matcher {\n\n\t/**\n\t * @cfg {Object} stripPrefix (required)\n\t *\n\t * The Object form of {@link Autolinker#cfg-stripPrefix}.\n\t */\n\tprotected stripPrefix: Required<StripPrefixConfigObj> = { scheme: true, www: true }; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n\t/**\n\t * @cfg {Boolean} stripTrailingSlash (required)\n\t * @inheritdoc Autolinker#stripTrailingSlash\n\t */\n\tprotected stripTrailingSlash: boolean = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n\t/**\n\t * @cfg {Boolean} decodePercentEncoding (required)\n\t * @inheritdoc Autolinker#decodePercentEncoding\n\t */\n\tprotected decodePercentEncoding: boolean = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n\t/**\n\t * @protected\n\t * @property {RegExp} matcherRegex\n\t *\n\t * The regular expression to match URLs with an optional scheme, port\n\t * number, path, query string, and hash anchor.\n\t *\n\t * Example matches:\n\t *\n\t * http://google.com\n\t * www.google.com\n\t * google.com/path/to/file?q1=1&q2=2#myAnchor\n\t *\n\t *\n\t * This regular expression will have the following capturing groups:\n\t *\n\t * 1. Group that matches a scheme-prefixed URL (i.e. 'http://google.com').\n\t * This is used to match scheme URLs with just a single word, such as\n\t * 'http://localhost', where we won't double check that the domain name\n\t * has at least one dot ('.') in it.\n\t * 2. Group that matches a 'www.' prefixed URL. This is only matched if the\n\t * 'www.' text was not prefixed by a scheme (i.e.: not prefixed by\n\t * 'http://', 'ftp:', etc.)\n\t * 3. A protocol-relative ('//') match for the case of a 'www.' prefixed\n\t * URL. Will be an empty string if it is not a protocol-relative match.\n\t * We need to know the character before the '//' in order to determine\n\t * if it is a valid match or the // was in a string we don't want to\n\t * auto-link.\n\t * 4. Group that matches a known TLD (top level domain), when a scheme\n\t * or 'www.'-prefixed domain is not matched.\n\t * 5. A protocol-relative ('//') match for the case of a known TLD prefixed\n\t * URL. Will be an empty string if it is not a protocol-relative match.\n\t * See #3 for more info.\n\t */\n\tprotected matcherRegex = matcherRegex;\n\n\t/**\n\t * A regular expression to use to check the character before a protocol-relative\n\t * URL match. We don't want to match a protocol-relative URL if it is part\n\t * of another word.\n\t *\n\t * For example, we want to match something like \"Go to: //google.com\",\n\t * but we don't want to match something like \"abc//google.com\"\n\t *\n\t * This regular expression is used to test the character before the '//'.\n\t *\n\t * @protected\n\t * @type {RegExp} wordCharRegExp\n\t */\n\tprotected wordCharRegExp = wordCharRegExp;\n\n\n\t/**\n\t * @method constructor\n\t * @param {Object} cfg The configuration properties for the Match instance,\n\t * specified in an Object (map).\n\t */\n\tconstructor( cfg: UrlMatcherConfig ) {\n\t\tsuper( cfg );\n\n\t\tthis.stripPrefix = cfg.stripPrefix;\n\t\tthis.stripTrailingSlash = cfg.stripTrailingSlash;\n\t\tthis.decodePercentEncoding = cfg.decodePercentEncoding;\n\t}\n\n\n\t/**\n\t * @inheritdoc\n\t */\n\tparseMatches( text: string ) {\n\t\tlet matcherRegex = this.matcherRegex,\n\t\t stripPrefix = this.stripPrefix,\n\t\t stripTrailingSlash = this.stripTrailingSlash,\n\t\t decodePercentEncoding = this.decodePercentEncoding,\n\t\t tagBuilder = this.tagBuilder,\n\t\t matches: Match[] = [],\n\t\t match: RegExpExecArray | null;\n\n\t\twhile( ( match = matcherRegex.exec( text ) ) !== null ) {\n\t\t\tlet matchStr = match[ 0 ],\n\t\t\t schemeUrlMatch = match[ 1 ],\n\t\t\t wwwUrlMatch = match[ 4 ],\n\t\t\t wwwProtocolRelativeMatch = match[ 5 ],\n\t\t\t //tldUrlMatch = match[ 8 ], -- not needed at the moment\n\t\t\t tldProtocolRelativeMatch = match[ 9 ],\n\t\t\t offset = match.index,\n\t\t\t protocolRelativeMatch = wwwProtocolRelativeMatch || tldProtocolRelativeMatch,\n\t\t\t\tprevChar = text.charAt( offset - 1 );\n\n\t\t\tif( !UrlMatchValidator.isValid( matchStr, schemeUrlMatch ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If the match is preceded by an '@' character, then it is either\n\t\t\t// an email address or a username. Skip these types of matches.\n\t\t\tif( offset > 0 && prevChar === '@' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If it's a protocol-relative '//' match, but the character before the '//'\n\t\t\t// was a word character (i.e. a letter/number), then we found the '//' in the\n\t\t\t// middle of another word (such as \"asdf//asdf.com\"). In this case, skip the\n\t\t\t// match.\n\t\t\tif( offset > 0 && protocolRelativeMatch && this.wordCharRegExp.test( prevChar ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If the URL ends with a question mark, don't include the question\n\t\t\t// mark as part of the URL. We'll assume the question mark was the\n\t\t\t// end of a sentence, such as: \"Going to google.com?\"\n\t\t\tif( /\\?$/.test( matchStr ) ) {\n\t\t\t\tmatchStr = matchStr.substr( 0, matchStr.length-1 );\n\t\t\t}\n\n\t\t\t// Handle a closing parenthesis or square bracket at the end of the \n\t\t\t// match, and exclude it if there is not a matching open parenthesis \n\t\t\t// or square bracket in the match itself.\n\t\t\tif( this.matchHasUnbalancedClosingParen( matchStr ) ) {\n\t\t\t\tmatchStr = matchStr.substr( 0, matchStr.length - 1 ); // remove the trailing \")\"\n\t\t\t} else {\n\t\t\t\t// Handle an invalid character after the TLD\n\t\t\t\tlet pos = this.matchHasInvalidCharAfterTld( matchStr, schemeUrlMatch );\n\t\t\t\tif( pos > -1 ) {\n\t\t\t\t\tmatchStr = matchStr.substr( 0, pos ); // remove the trailing invalid chars\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The autolinker accepts many characters in a url's scheme (like `fake://test.com`).\n\t\t\t// However, in cases where a URL is missing whitespace before an obvious link,\n\t\t\t// (for example: `nowhitespacehttp://www.test.com`), we only want the match to start\n\t\t\t// at the http:// part. We will check if the match contains a common scheme and then \n\t\t\t// shift the match to start from there. \t\t\n\t\t\tconst foundCommonScheme = [ 'http://', 'https://' ].find(\n\t\t\t\t(commonScheme) => !!schemeUrlMatch && schemeUrlMatch.indexOf( commonScheme ) !== -1\n\t\t\t);\n\t\t\tif ( foundCommonScheme ) {\n\t\t\t\t// If we found an overmatched URL, we want to find the index\n\t\t\t\t// of where the match should start and shift the match to\n\t\t\t\t// start from the beginning of the common scheme\n\t\t\t\tconst indexOfSchemeStart = matchStr.indexOf( foundCommonScheme );\n\n\t\t\t\tmatchStr = matchStr.substr( indexOfSchemeStart );\n\t\t\t\tschemeUrlMatch = schemeUrlMatch.substr( indexOfSchemeStart );\n\t\t\t\toffset = offset + indexOfSchemeStart;\n\t\t\t}\n\n\t\t\tlet urlMatchType: UrlMatchTypeOptions = schemeUrlMatch ? 'scheme' : ( wwwUrlMatch ? 'www' : 'tld' ),\n\t\t\t protocolUrlMatch = !!schemeUrlMatch;\n\n\t\t\tmatches.push( new UrlMatch( {\n\t\t\t\ttagBuilder : tagBuilder,\n\t\t\t\tmatchedText : matchStr,\n\t\t\t\toffset : offset,\n\t\t\t\turlMatchType : urlMatchType,\n\t\t\t\turl : matchStr,\n\t\t\t\tprotocolUrlMatch : protocolUrlMatch,\n\t\t\t\tprotocolRelativeMatch : !!protocolRelativeMatch,\n\t\t\t\tstripPrefix : stripPrefix,\n\t\t\t\tstripTrailingSlash : stripTrailingSlash,\n\t\t\t\tdecodePercentEncoding : decodePercentEncoding,\n\t\t\t} ) );\n\t\t}\n\n\t\treturn matches;\n\t}\n\n\n\t/**\n\t * Determines if a match found has an unmatched closing parenthesis,\n\t * square bracket or curly bracket. If so, the symbol will be removed\n\t * from the match itself, and appended after the generated anchor tag.\n\t *\n\t * A match may have an extra closing parenthesis at the end of the match\n\t * because the regular expression must include parenthesis for URLs such as\n\t * \"wikipedia.com/something_(disambiguation)\", which should be auto-linked.\n\t *\n\t * However, an extra parenthesis *will* be included when the URL itself is\n\t * wrapped in parenthesis, such as in the case of: \n\t * \"(wikipedia.com/something_(disambiguation))\"\n\t * In this case, the last closing parenthesis should *not* be part of the\n\t * URL itself, and this method will return `true`. \n\t * \n\t * For square brackets in URLs such as in PHP arrays, the same behavior as \n\t * parenthesis discussed above should happen:\n\t * \"[http://www.example.com/foo.php?bar[]=1&bar[]=2&bar[]=3]\"\n\t * The closing square bracket should not be part of the URL itself, and this\n\t * method will return `true`.\n\t *\n\t * @protected\n\t * @param {String} matchStr The full match string from the {@link #matcherRegex}.\n\t * @return {Boolean} `true` if there is an unbalanced closing parenthesis or\n\t * square bracket at the end of the `matchStr`, `false` otherwise.\n\t */\n\tprotected matchHasUnbalancedClosingParen( matchStr: string ): boolean {\n\t\tlet endChar = matchStr.charAt( matchStr.length - 1 );\n\t\tlet startChar: string;\n\n\t\tif( endChar === ')' ) {\n\t\t\tstartChar = '(';\n\t\t} else if( endChar === ']' ) {\n\t\t\tstartChar = '[';\n\t\t} else if ( endChar === '}' ) {\n\t\t\tstartChar = '{';\n\t\t} else {\n\t\t\treturn false; // not a close parenthesis or square bracket\n\t\t}\n\n\t\t// Find if there are the same number of open braces as close braces in\n\t\t// the URL string, minus the last character (which we have already \n\t\t// determined to be either ')', ']' or '}'\n\t\tlet numOpenBraces = 0;\n\t\tfor( let i = 0, len = matchStr.length - 1; i < len; i++ ) {\n\t\t\tconst char = matchStr.charAt( i );\n\n\t\t\tif( char === startChar ) {\n\t\t\t\tnumOpenBraces++;\n\t\t\t} else if( char === endChar ) {\n\t\t\t\tnumOpenBraces = Math.max( numOpenBraces - 1, 0 );\n\t\t\t}\n\t\t}\n\n\t\t// If the number of open braces matches the number of close braces in\n\t\t// the URL minus the last character, then the match has *unbalanced*\n\t\t// braces because of the last character. Example of unbalanced braces\n\t\t// from the regex match:\n\t\t// \"http://example.com?a[]=1]\"\n\t\tif( numOpenBraces === 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\n\t/**\n\t * Determine if there's an invalid character after the TLD in a URL. Valid\n\t * characters after TLD are ':/?#'. Exclude scheme matched URLs from this\n\t * check.\n\t *\n\t * @protected\n\t * @param {String} urlMatch The matched URL, if there was one. Will be an\n\t * empty string if the match is not a URL match.\n\t * @param {String} schemeUrlMatch The match URL string for a scheme\n\t * match. Ex: 'http://yahoo.com'. This is used to match something like\n\t * 'http://localhost', where we won't double check that the domain name\n\t * has at least one '.' in it.\n\t * @return {Number} the position where the invalid character was found. If\n\t * no such character was found, returns -1\n\t */\n\tprotected matchHasInvalidCharAfterTld( urlMatch: string, schemeUrlMatch: string ) {\n\t\tif( !urlMatch ) {\n\t\t\treturn -1;\n\t\t}\n\n\t\tlet offset = 0;\n\t\tif ( schemeUrlMatch ) {\n\t\t\toffset = urlMatch.indexOf(':');\n\t\t\turlMatch = urlMatch.slice(offset);\n\t\t}\n\n\t\tlet re = new RegExp( \"^((.?\\/\\/)?[-.\" + alphaNumericAndMarksCharsStr + \"]*[-\" + alphaNumericAndMarksCharsStr + \"]\\\\.[-\" + alphaNumericAndMarksCharsStr + \"]+)\" );\n\t\tlet res = re.exec( urlMatch );\n\t\tif ( res === null ) {\n\t\t\treturn -1;\n\t\t}\n\n\t\toffset += res[1].length;\n\t\turlMatch = urlMatch.slice(res[1].length);\n\t\tif (/^[^-.A-Za-z0-9:\\/?#]/.test(urlMatch)) {\n\t\t\treturn offset;\n\t\t}\n\n\t\treturn -1;\n\t}\n\n}\n\nexport interface UrlMatcherConfig extends MatcherConfig {\n\tstripPrefix: Required<StripPrefixConfigObj>;\n\tstripTrailingSlash: boolean;\n\tdecodePercentEncoding: boolean;\n}"]}