diff --git a/package.json b/package.json
index 145d2f02..fb595589 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
"@react-navigation/native": "^5.8.6",
"@react-navigation/stack": "^5.12.3",
"@reduxjs/toolkit": "^1.4.0",
- "autolinker": "^3.14.2",
+ "autolinker": "./src/modules/autolinker",
"expo": "~39.0.4",
"expo-app-auth": "~9.2.0",
"expo-av": "~8.6.0",
@@ -59,4 +59,4 @@
"typescript": "~3.9.2"
},
"private": true
-}
\ No newline at end of file
+}
diff --git a/src/modules/autolinker/anchor-tag-builder.d.ts b/src/modules/autolinker/anchor-tag-builder.d.ts
new file mode 100644
index 00000000..09a5965d
--- /dev/null
+++ b/src/modules/autolinker/anchor-tag-builder.d.ts
@@ -0,0 +1,120 @@
+import { Match } from "./match/match";
+import { HtmlTag } from "./html-tag";
+import { TruncateConfigObj } from "./autolinker";
+/**
+ * @protected
+ * @class Autolinker.AnchorTagBuilder
+ * @extends Object
+ *
+ * Builds anchor (<a>) tags for the Autolinker utility when a match is
+ * found.
+ *
+ * Normally this class is instantiated, configured, and used internally by an
+ * {@link Autolinker} instance, but may actually be used indirectly in a
+ * {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag}
+ * instances which may be modified before returning from the
+ * {@link Autolinker#replaceFn replaceFn}. For example:
+ *
+ * var html = Autolinker.link( "Test google.com", {
+ * replaceFn : function( match ) {
+ * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance
+ * tag.setAttr( 'rel', 'nofollow' );
+ *
+ * return tag;
+ * }
+ * } );
+ *
+ * // generated html:
+ * // Test google.com
+ */
+export declare class AnchorTagBuilder {
+ /**
+ * @cfg {Boolean} newWindow
+ * @inheritdoc Autolinker#newWindow
+ */
+ private readonly newWindow;
+ /**
+ * @cfg {Object} truncate
+ * @inheritdoc Autolinker#truncate
+ */
+ private readonly truncate;
+ /**
+ * @cfg {String} className
+ * @inheritdoc Autolinker#className
+ */
+ private readonly className;
+ /**
+ * @method constructor
+ * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map).
+ */
+ constructor(cfg?: AnchorTagBuilderCfg);
+ /**
+ * Generates the actual anchor (<a>) tag to use in place of the
+ * matched text, via its `match` object.
+ *
+ * @param {Autolinker.match.Match} match The Match instance to generate an
+ * anchor tag from.
+ * @return {Autolinker.HtmlTag} The HtmlTag instance for the anchor tag.
+ */
+ build(match: Match): HtmlTag;
+ /**
+ * Creates the Object (map) of the HTML attributes for the anchor (<a>)
+ * tag being generated.
+ *
+ * @protected
+ * @param {Autolinker.match.Match} match The Match instance to generate an
+ * anchor tag from.
+ * @return {Object} A key/value Object (map) of the anchor tag's attributes.
+ */
+ protected createAttrs(match: Match): {
+ [attrName: string]: string;
+ };
+ /**
+ * Creates the CSS class that will be used for a given anchor tag, based on
+ * the `matchType` and the {@link #className} config.
+ *
+ * Example returns:
+ *
+ * - "" // no {@link #className}
+ * - "myLink myLink-url" // url match
+ * - "myLink myLink-email" // email match
+ * - "myLink myLink-phone" // phone match
+ * - "myLink myLink-hashtag" // hashtag match
+ * - "myLink myLink-mention myLink-twitter" // mention match with Twitter service
+ *
+ * @protected
+ * @param {Autolinker.match.Match} match The Match instance to generate an
+ * anchor tag from.
+ * @return {String} The CSS class string for the link. Example return:
+ * "myLink myLink-url". If no {@link #className} was configured, returns
+ * an empty string.
+ */
+ protected createCssClass(match: Match): string;
+ /**
+ * Processes the `anchorText` by truncating the text according to the
+ * {@link #truncate} config.
+ *
+ * @private
+ * @param {String} anchorText The anchor tag's text (i.e. what will be
+ * displayed).
+ * @return {String} The processed `anchorText`.
+ */
+ private processAnchorText;
+ /**
+ * Performs the truncation of the `anchorText` based on the {@link #truncate}
+ * option. If the `anchorText` is longer than the length specified by the
+ * {@link #truncate} option, the truncation is performed based on the
+ * `location` property. See {@link #truncate} for details.
+ *
+ * @private
+ * @param {String} anchorText The anchor tag's text (i.e. what will be
+ * displayed).
+ * @return {String} The truncated anchor text.
+ */
+ private doTruncate;
+}
+export interface AnchorTagBuilderCfg {
+ newWindow?: boolean;
+ truncate?: TruncateConfigObj;
+ className?: string;
+}
diff --git a/src/modules/autolinker/anchor-tag-builder.js b/src/modules/autolinker/anchor-tag-builder.js
new file mode 100644
index 00000000..b44caaab
--- /dev/null
+++ b/src/modules/autolinker/anchor-tag-builder.js
@@ -0,0 +1,176 @@
+import { HtmlTag } from "./html-tag";
+import { truncateSmart } from "./truncate/truncate-smart";
+import { truncateMiddle } from "./truncate/truncate-middle";
+import { truncateEnd } from "./truncate/truncate-end";
+/**
+ * @protected
+ * @class Autolinker.AnchorTagBuilder
+ * @extends Object
+ *
+ * Builds anchor (<a>) tags for the Autolinker utility when a match is
+ * found.
+ *
+ * Normally this class is instantiated, configured, and used internally by an
+ * {@link Autolinker} instance, but may actually be used indirectly in a
+ * {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag}
+ * instances which may be modified before returning from the
+ * {@link Autolinker#replaceFn replaceFn}. For example:
+ *
+ * var html = Autolinker.link( "Test google.com", {
+ * replaceFn : function( match ) {
+ * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance
+ * tag.setAttr( 'rel', 'nofollow' );
+ *
+ * return tag;
+ * }
+ * } );
+ *
+ * // generated html:
+ * // Test google.com
+ */
+var AnchorTagBuilder = /** @class */ (function () {
+ /**
+ * @method constructor
+ * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map).
+ */
+ function AnchorTagBuilder(cfg) {
+ if (cfg === void 0) { cfg = {}; }
+ /**
+ * @cfg {Boolean} newWindow
+ * @inheritdoc Autolinker#newWindow
+ */
+ this.newWindow = false; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Object} truncate
+ * @inheritdoc Autolinker#truncate
+ */
+ this.truncate = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {String} className
+ * @inheritdoc Autolinker#className
+ */
+ this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
+ this.newWindow = cfg.newWindow || false;
+ this.truncate = cfg.truncate || {};
+ this.className = cfg.className || '';
+ }
+ /**
+ * Generates the actual anchor (<a>) tag to use in place of the
+ * matched text, via its `match` object.
+ *
+ * @param {Autolinker.match.Match} match The Match instance to generate an
+ * anchor tag from.
+ * @return {Autolinker.HtmlTag} The HtmlTag instance for the anchor tag.
+ */
+ AnchorTagBuilder.prototype.build = function (match) {
+ return new HtmlTag({
+ tagName: 'a',
+ attrs: this.createAttrs(match),
+ innerHtml: this.processAnchorText(match.getAnchorText())
+ });
+ };
+ /**
+ * Creates the Object (map) of the HTML attributes for the anchor (<a>)
+ * tag being generated.
+ *
+ * @protected
+ * @param {Autolinker.match.Match} match The Match instance to generate an
+ * anchor tag from.
+ * @return {Object} A key/value Object (map) of the anchor tag's attributes.
+ */
+ AnchorTagBuilder.prototype.createAttrs = function (match) {
+ var attrs = {
+ 'href': match.getAnchorHref() // we'll always have the `href` attribute
+ };
+ var cssClass = this.createCssClass(match);
+ if (cssClass) {
+ attrs['class'] = cssClass;
+ }
+ if (this.newWindow) {
+ attrs['target'] = "_blank";
+ attrs['rel'] = "noopener noreferrer"; // Issue #149. See https://mathiasbynens.github.io/rel-noopener/
+ }
+ if (this.truncate) {
+ if (this.truncate.length && this.truncate.length < match.getAnchorText().length) {
+ attrs['title'] = match.getAnchorHref();
+ }
+ }
+ return attrs;
+ };
+ /**
+ * Creates the CSS class that will be used for a given anchor tag, based on
+ * the `matchType` and the {@link #className} config.
+ *
+ * Example returns:
+ *
+ * - "" // no {@link #className}
+ * - "myLink myLink-url" // url match
+ * - "myLink myLink-email" // email match
+ * - "myLink myLink-phone" // phone match
+ * - "myLink myLink-hashtag" // hashtag match
+ * - "myLink myLink-mention myLink-twitter" // mention match with Twitter service
+ *
+ * @protected
+ * @param {Autolinker.match.Match} match The Match instance to generate an
+ * anchor tag from.
+ * @return {String} The CSS class string for the link. Example return:
+ * "myLink myLink-url". If no {@link #className} was configured, returns
+ * an empty string.
+ */
+ AnchorTagBuilder.prototype.createCssClass = function (match) {
+ var className = this.className;
+ if (!className) {
+ return "";
+ }
+ else {
+ var returnClasses = [className], cssClassSuffixes = match.getCssClassSuffixes();
+ for (var i = 0, len = cssClassSuffixes.length; i < len; i++) {
+ returnClasses.push(className + '-' + cssClassSuffixes[i]);
+ }
+ return returnClasses.join(' ');
+ }
+ };
+ /**
+ * Processes the `anchorText` by truncating the text according to the
+ * {@link #truncate} config.
+ *
+ * @private
+ * @param {String} anchorText The anchor tag's text (i.e. what will be
+ * displayed).
+ * @return {String} The processed `anchorText`.
+ */
+ AnchorTagBuilder.prototype.processAnchorText = function (anchorText) {
+ anchorText = this.doTruncate(anchorText);
+ return anchorText;
+ };
+ /**
+ * Performs the truncation of the `anchorText` based on the {@link #truncate}
+ * option. If the `anchorText` is longer than the length specified by the
+ * {@link #truncate} option, the truncation is performed based on the
+ * `location` property. See {@link #truncate} for details.
+ *
+ * @private
+ * @param {String} anchorText The anchor tag's text (i.e. what will be
+ * displayed).
+ * @return {String} The truncated anchor text.
+ */
+ AnchorTagBuilder.prototype.doTruncate = function (anchorText) {
+ var truncate = this.truncate;
+ if (!truncate || !truncate.length)
+ return anchorText;
+ var truncateLength = truncate.length, truncateLocation = truncate.location;
+ if (truncateLocation === 'smart') {
+ return truncateSmart(anchorText, truncateLength);
+ }
+ else if (truncateLocation === 'middle') {
+ return truncateMiddle(anchorText, truncateLength);
+ }
+ else {
+ return truncateEnd(anchorText, truncateLength);
+ }
+ };
+ return AnchorTagBuilder;
+}());
+export { AnchorTagBuilder };
+
+//# sourceMappingURL=anchor-tag-builder.js.map
diff --git a/src/modules/autolinker/anchor-tag-builder.js.map b/src/modules/autolinker/anchor-tag-builder.js.map
new file mode 100644
index 00000000..45b7327f
--- /dev/null
+++ b/src/modules/autolinker/anchor-tag-builder.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/anchor-tag-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH;IAqBC;;;OAGG;IACH,0BAAa,GAA6B;QAA7B,oBAAA,EAAA,QAA6B;QAvB1C;;;WAGG;QACc,cAAS,GAAY,KAAK,CAAC,CAAE,gGAAgG;QAE9I;;;WAGG;QACc,aAAQ,GAAsB,EAAE,CAAC,CAAE,gGAAgG;QAEpJ;;;WAGG;QACc,cAAS,GAAW,EAAE,CAAC,CAAE,gGAAgG;QAQzI,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,KAAK,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;IACtC,CAAC;IAGD;;;;;;;OAOG;IACH,gCAAK,GAAL,UAAO,KAAY;QAClB,OAAO,IAAI,OAAO,CAAE;YACnB,OAAO,EAAK,GAAG;YACf,KAAK,EAAO,IAAI,CAAC,WAAW,CAAE,KAAK,CAAE;YACrC,SAAS,EAAG,IAAI,CAAC,iBAAiB,CAAE,KAAK,CAAC,aAAa,EAAE,CAAE;SAC3D,CAAE,CAAC;IACL,CAAC;IAGD;;;;;;;;OAQG;IACO,sCAAW,GAArB,UAAuB,KAAY;QAClC,IAAI,KAAK,GAAiC;YACzC,MAAM,EAAG,KAAK,CAAC,aAAa,EAAE,CAAE,yCAAyC;SACzE,CAAC;QAEF,IAAI,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAE,KAAK,CAAE,CAAC;QAC5C,IAAI,QAAQ,EAAG;YACd,KAAK,CAAE,OAAO,CAAE,GAAG,QAAQ,CAAC;SAC5B;QACD,IAAI,IAAI,CAAC,SAAS,EAAG;YACpB,KAAK,CAAE,QAAQ,CAAE,GAAG,QAAQ,CAAC;YAC7B,KAAK,CAAE,KAAK,CAAE,GAAG,qBAAqB,CAAC,CAAE,gEAAgE;SACzG;QAED,IAAI,IAAI,CAAC,QAAQ,EAAG;YACnB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC,MAAM,EAAG;gBACjF,KAAK,CAAE,OAAO,CAAE,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;aACzC;SACD;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAGD;;;;;;;;;;;;;;;;;;;OAmBG;IACO,yCAAc,GAAxB,UAA0B,KAAY;QACrC,IAAI,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAE/B,IAAI,CAAC,SAAS,EAAG;YAChB,OAAO,EAAE,CAAC;SAEV;aAAM;YACN,IAAI,aAAa,GAAG,CAAE,SAAS,CAAE,EAChC,gBAAgB,GAAG,KAAK,CAAC,mBAAmB,EAAE,CAAC;YAEhD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAG;gBAC7D,aAAa,CAAC,IAAI,CAAE,SAAS,GAAG,GAAG,GAAG,gBAAgB,CAAE,CAAC,CAAE,CAAE,CAAC;aAC9D;YACD,OAAO,aAAa,CAAC,IAAI,CAAE,GAAG,CAAE,CAAC;SACjC;IACF,CAAC;IAGD;;;;;;;;OAQG;IACK,4CAAiB,GAAzB,UAA2B,UAAkB;QAC5C,UAAU,GAAG,IAAI,CAAC,UAAU,CAAE,UAAU,CAAE,CAAC;QAE3C,OAAO,UAAU,CAAC;IACnB,CAAC;IAGD;;;;;;;;;;OAUG;IACK,qCAAU,GAAlB,UAAoB,UAAkB;QACrC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7B,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAG,OAAO,UAAU,CAAC;QAEtD,IAAI,cAAc,GAAG,QAAQ,CAAC,MAAM,EACnC,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,CAAC;QAEtC,IAAI,gBAAgB,KAAK,OAAO,EAAG;YAClC,OAAO,aAAa,CAAE,UAAU,EAAE,cAAc,CAAE,CAAC;SAEnD;aAAM,IAAI,gBAAgB,KAAK,QAAQ,EAAG;YAC1C,OAAO,cAAc,CAAE,UAAU,EAAE,cAAc,CAAE,CAAC;SAEpD;aAAM;YACN,OAAO,WAAW,CAAE,UAAU,EAAE,cAAc,CAAE,CAAC;SACjD;IACF,CAAC;IACF,uBAAC;AAAD,CApKA,AAoKC,IAAA","file":"anchor-tag-builder.js","sourcesContent":["import { Match } from \"./match/match\";\nimport { HtmlTag } from \"./html-tag\";\nimport { TruncateConfigObj } from \"./autolinker\";\nimport { truncateSmart } from \"./truncate/truncate-smart\";\nimport { truncateMiddle } from \"./truncate/truncate-middle\";\nimport { truncateEnd } from \"./truncate/truncate-end\";\n\n/**\n * @protected\n * @class Autolinker.AnchorTagBuilder\n * @extends Object\n *\n * Builds anchor (<a>) tags for the Autolinker utility when a match is\n * found.\n *\n * Normally this class is instantiated, configured, and used internally by an\n * {@link Autolinker} instance, but may actually be used indirectly in a\n * {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag}\n * instances which may be modified before returning from the\n * {@link Autolinker#replaceFn replaceFn}. For example:\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance\n * tag.setAttr( 'rel', 'nofollow' );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test google.com\n */\nexport class AnchorTagBuilder {\n\n\t/**\n\t * @cfg {Boolean} newWindow\n\t * @inheritdoc Autolinker#newWindow\n\t */\n\tprivate readonly newWindow: boolean = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n\t/**\n\t * @cfg {Object} truncate\n\t * @inheritdoc Autolinker#truncate\n\t */\n\tprivate readonly truncate: TruncateConfigObj = {}; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n\t/**\n\t * @cfg {String} className\n\t * @inheritdoc Autolinker#className\n\t */\n\tprivate readonly className: string = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n\n\n\t/**\n\t * @method constructor\n\t * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map).\n\t */\n\tconstructor( cfg: AnchorTagBuilderCfg = {} ) {\n\t\tthis.newWindow = cfg.newWindow || false;\n\t\tthis.truncate = cfg.truncate || {};\n\t\tthis.className = cfg.className || '';\n\t}\n\n\n\t/**\n\t * Generates the actual anchor (<a>) tag to use in place of the\n\t * matched text, via its `match` object.\n\t *\n\t * @param {Autolinker.match.Match} match The Match instance to generate an\n\t * anchor tag from.\n\t * @return {Autolinker.HtmlTag} The HtmlTag instance for the anchor tag.\n\t */\n\tbuild( match: Match ) {\n\t\treturn new HtmlTag( {\n\t\t\ttagName : 'a',\n\t\t\tattrs : this.createAttrs( match ),\n\t\t\tinnerHtml : this.processAnchorText( match.getAnchorText() )\n\t\t} );\n\t}\n\n\n\t/**\n\t * Creates the Object (map) of the HTML attributes for the anchor (<a>)\n\t * tag being generated.\n\t *\n\t * @protected\n\t * @param {Autolinker.match.Match} match The Match instance to generate an\n\t * anchor tag from.\n\t * @return {Object} A key/value Object (map) of the anchor tag's attributes.\n\t */\n\tprotected createAttrs( match: Match ) {\n\t\tlet attrs: {[attrName: string]: string} = {\n\t\t\t'href' : match.getAnchorHref() // we'll always have the `href` attribute\n\t\t};\n\n\t\tlet cssClass = this.createCssClass( match );\n\t\tif( cssClass ) {\n\t\t\tattrs[ 'class' ] = cssClass;\n\t\t}\n\t\tif( this.newWindow ) {\n\t\t\tattrs[ 'target' ] = \"_blank\";\n\t\t\tattrs[ 'rel' ] = \"noopener noreferrer\"; // Issue #149. See https://mathiasbynens.github.io/rel-noopener/\n\t\t}\n\n\t\tif( this.truncate ) {\n\t\t\tif( this.truncate.length && this.truncate.length < match.getAnchorText().length ) {\n\t\t\t\tattrs[ 'title' ] = match.getAnchorHref();\n\t\t\t}\n\t\t}\n\n\t\treturn attrs;\n\t}\n\n\n\t/**\n\t * Creates the CSS class that will be used for a given anchor tag, based on\n\t * the `matchType` and the {@link #className} config.\n\t *\n\t * Example returns:\n\t *\n\t * - \"\" // no {@link #className}\n\t * - \"myLink myLink-url\" // url match\n\t * - \"myLink myLink-email\" // email match\n\t * - \"myLink myLink-phone\" // phone match\n\t * - \"myLink myLink-hashtag\" // hashtag match\n\t * - \"myLink myLink-mention myLink-twitter\" // mention match with Twitter service\n\t *\n\t * @protected\n\t * @param {Autolinker.match.Match} match The Match instance to generate an\n\t * anchor tag from.\n\t * @return {String} The CSS class string for the link. Example return:\n\t * \"myLink myLink-url\". If no {@link #className} was configured, returns\n\t * an empty string.\n\t */\n\tprotected createCssClass( match: Match ) {\n\t\tlet className = this.className;\n\n\t\tif( !className ) {\n\t\t\treturn \"\";\n\n\t\t} else {\n\t\t\tlet returnClasses = [ className ],\n\t\t\t\tcssClassSuffixes = match.getCssClassSuffixes();\n\n\t\t\tfor( let i = 0, len = cssClassSuffixes.length; i < len; i++ ) {\n\t\t\t\treturnClasses.push( className + '-' + cssClassSuffixes[ i ] );\n\t\t\t}\n\t\t\treturn returnClasses.join( ' ' );\n\t\t}\n\t}\n\n\n\t/**\n\t * Processes the `anchorText` by truncating the text according to the\n\t * {@link #truncate} config.\n\t *\n\t * @private\n\t * @param {String} anchorText The anchor tag's text (i.e. what will be\n\t * displayed).\n\t * @return {String} The processed `anchorText`.\n\t */\n\tprivate processAnchorText( anchorText: string ) {\n\t\tanchorText = this.doTruncate( anchorText );\n\n\t\treturn anchorText;\n\t}\n\n\n\t/**\n\t * Performs the truncation of the `anchorText` based on the {@link #truncate}\n\t * option. If the `anchorText` is longer than the length specified by the\n\t * {@link #truncate} option, the truncation is performed based on the\n\t * `location` property. See {@link #truncate} for details.\n\t *\n\t * @private\n\t * @param {String} anchorText The anchor tag's text (i.e. what will be\n\t * displayed).\n\t * @return {String} The truncated anchor text.\n\t */\n\tprivate doTruncate( anchorText: string ) {\n\t\tlet truncate = this.truncate;\n\t\tif( !truncate || !truncate.length ) return anchorText;\n\n\t\tlet truncateLength = truncate.length,\n\t\t\ttruncateLocation = truncate.location;\n\n\t\tif( truncateLocation === 'smart' ) {\n\t\t\treturn truncateSmart( anchorText, truncateLength );\n\n\t\t} else if( truncateLocation === 'middle' ) {\n\t\t\treturn truncateMiddle( anchorText, truncateLength );\n\n\t\t} else {\n\t\t\treturn truncateEnd( anchorText, truncateLength );\n\t\t}\n\t}\n}\n\n\nexport interface AnchorTagBuilderCfg {\n\tnewWindow?: boolean;\n\ttruncate?: TruncateConfigObj;\n\tclassName?: string\n}"]}
\ No newline at end of file
diff --git a/src/modules/autolinker/autolinker.d.ts b/src/modules/autolinker/autolinker.d.ts
new file mode 100644
index 00000000..979a7356
--- /dev/null
+++ b/src/modules/autolinker/autolinker.d.ts
@@ -0,0 +1,699 @@
+import { AnchorTagBuilder } from "./anchor-tag-builder";
+import { Match } from "./match/match";
+import { EmailMatch } from "./match/email-match";
+import { HashtagMatch } from "./match/hashtag-match";
+import { MentionMatch } from "./match/mention-match";
+import { PhoneMatch } from "./match/phone-match";
+import { UrlMatch } from "./match/url-match";
+import { Matcher } from "./matcher/matcher";
+import { HtmlTag } from "./html-tag";
+import { EmailMatcher } from "./matcher/email-matcher";
+import { UrlMatcher } from "./matcher/url-matcher";
+import { HashtagMatcher } from "./matcher/hashtag-matcher";
+import { PhoneMatcher } from "./matcher/phone-matcher";
+import { MentionMatcher } from "./matcher/mention-matcher";
+/**
+ * @class Autolinker
+ * @extends Object
+ *
+ * Utility class used to process a given string of text, and wrap the matches in
+ * the appropriate anchor (<a>) tags to turn them into links.
+ *
+ * Any of the configuration options may be provided in an Object provided
+ * to the Autolinker constructor, which will configure how the {@link #link link()}
+ * method will process the links.
+ *
+ * For example:
+ *
+ * var autolinker = new Autolinker( {
+ * newWindow : false,
+ * truncate : 30
+ * } );
+ *
+ * var html = autolinker.link( "Joe went to www.yahoo.com" );
+ * // produces: 'Joe went to yahoo.com'
+ *
+ *
+ * The {@link #static-link static link()} method may also be used to inline
+ * options into a single call, which may be more convenient for one-off uses.
+ * For example:
+ *
+ * var html = Autolinker.link( "Joe went to www.yahoo.com", {
+ * newWindow : false,
+ * truncate : 30
+ * } );
+ * // produces: 'Joe went to yahoo.com'
+ *
+ *
+ * ## Custom Replacements of Links
+ *
+ * If the configuration options do not provide enough flexibility, a {@link #replaceFn}
+ * may be provided to fully customize the output of Autolinker. This function is
+ * called once for each URL/Email/Phone#/Hashtag/Mention (Twitter, Instagram, Soundcloud)
+ * match that is encountered.
+ *
+ * For example:
+ *
+ * var input = "..."; // string with URLs, Email Addresses, Phone #s, Hashtags, and Mentions (Twitter, Instagram, Soundcloud)
+ *
+ * var linkedText = Autolinker.link( input, {
+ * replaceFn : function( match ) {
+ * console.log( "href = ", match.getAnchorHref() );
+ * console.log( "text = ", match.getAnchorText() );
+ *
+ * switch( match.getType() ) {
+ * case 'url' :
+ * console.log( "url: ", match.getUrl() );
+ *
+ * if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) {
+ * var tag = match.buildTag(); // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes
+ * tag.setAttr( 'rel', 'nofollow' );
+ * tag.addClass( 'external-link' );
+ *
+ * return tag;
+ *
+ * } else {
+ * return true; // let Autolinker perform its normal anchor tag replacement
+ * }
+ *
+ * case 'email' :
+ * var email = match.getEmail();
+ * console.log( "email: ", email );
+ *
+ * if( email === "my@own.address" ) {
+ * return false; // don't auto-link this particular email address; leave as-is
+ * } else {
+ * return; // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`)
+ * }
+ *
+ * case 'phone' :
+ * var phoneNumber = match.getPhoneNumber();
+ * console.log( phoneNumber );
+ *
+ * return '' + phoneNumber + '';
+ *
+ * case 'hashtag' :
+ * var hashtag = match.getHashtag();
+ * console.log( hashtag );
+ *
+ * return '' + hashtag + '';
+ *
+ * case 'mention' :
+ * var mention = match.getMention();
+ * console.log( mention );
+ *
+ * return '' + mention + '';
+ * }
+ * }
+ * } );
+ *
+ *
+ * The function may return the following values:
+ *
+ * - `true` (Boolean): Allow Autolinker to replace the match as it normally
+ * would.
+ * - `false` (Boolean): Do not replace the current match at all - leave as-is.
+ * - Any String: If a string is returned from the function, the string will be
+ * used directly as the replacement HTML for the match.
+ * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify
+ * an HTML tag before writing out its HTML text.
+ */
+export default class Autolinker {
+ /**
+ * @static
+ * @property {String} version
+ *
+ * The Autolinker version number in the form major.minor.patch
+ *
+ * Ex: 0.25.1
+ */
+ static readonly version = "3.14.1";
+ /**
+ * For backwards compatibility with Autolinker 1.x, the AnchorTagBuilder
+ * class is provided as a static on the Autolinker class.
+ */
+ static readonly AnchorTagBuilder: typeof AnchorTagBuilder;
+ /**
+ * For backwards compatibility with Autolinker 1.x, the HtmlTag class is
+ * provided as a static on the Autolinker class.
+ */
+ static readonly HtmlTag: typeof HtmlTag;
+ /**
+ * For backwards compatibility with Autolinker 1.x, the Matcher classes are
+ * provided as statics on the Autolinker class.
+ */
+ static readonly matcher: {
+ Email: typeof EmailMatcher;
+ Hashtag: typeof HashtagMatcher;
+ Matcher: typeof Matcher;
+ Mention: typeof MentionMatcher;
+ Phone: typeof PhoneMatcher;
+ Url: typeof UrlMatcher;
+ };
+ /**
+ * For backwards compatibility with Autolinker 1.x, the Match classes are
+ * provided as statics on the Autolinker class.
+ */
+ static readonly match: {
+ Email: typeof EmailMatch;
+ Hashtag: typeof HashtagMatch;
+ Match: typeof Match;
+ Mention: typeof MentionMatch;
+ Phone: typeof PhoneMatch;
+ Url: typeof UrlMatch;
+ };
+ /**
+ * Automatically links URLs, Email addresses, Phone Numbers, Twitter handles,
+ * Hashtags, and Mentions found in the given chunk of HTML. Does not link URLs
+ * found within HTML tags.
+ *
+ * For instance, if given the text: `You should go to http://www.yahoo.com`,
+ * then the result will be `You should go to <a href="http://www.yahoo.com">http://www.yahoo.com</a>`
+ *
+ * Example:
+ *
+ * var linkedText = Autolinker.link( "Go to google.com", { newWindow: false } );
+ * // Produces: "Go to google.com"
+ *
+ * @static
+ * @param {String} textOrHtml The HTML or text to find matches within (depending
+ * on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #mention},
+ * {@link #hashtag}, and {@link #mention} options are enabled).
+ * @param {Object} [options] Any of the configuration options for the Autolinker
+ * class, specified in an Object (map). See the class description for an
+ * example call.
+ * @return {String} The HTML text, with matches automatically linked.
+ */
+ static link(textOrHtml: string, options?: AutolinkerConfig): string;
+ /**
+ * Parses the input `textOrHtml` looking for URLs, email addresses, phone
+ * numbers, username handles, and hashtags (depending on the configuration
+ * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
+ * objects describing those matches (without making any replacements).
+ *
+ * Note that if parsing multiple pieces of text, it is slightly more efficient
+ * to create an Autolinker instance, and use the instance-level {@link #parse}
+ * method.
+ *
+ * Example:
+ *
+ * var matches = Autolinker.parse( "Hello google.com, I am asdf@asdf.com", {
+ * urls: true,
+ * email: true
+ * } );
+ *
+ * console.log( matches.length ); // 2
+ * console.log( matches[ 0 ].getType() ); // 'url'
+ * console.log( matches[ 0 ].getUrl() ); // 'google.com'
+ * console.log( matches[ 1 ].getType() ); // 'email'
+ * console.log( matches[ 1 ].getEmail() ); // 'asdf@asdf.com'
+ *
+ * @static
+ * @param {String} textOrHtml The HTML or text to find matches within
+ * (depending on if the {@link #urls}, {@link #email}, {@link #phone},
+ * {@link #hashtag}, and {@link #mention} options are enabled).
+ * @param {Object} [options] Any of the configuration options for the Autolinker
+ * class, specified in an Object (map). See the class description for an
+ * example call.
+ * @return {Autolinker.match.Match[]} The array of Matches found in the
+ * given input `textOrHtml`.
+ */
+ static parse(textOrHtml: string, options: AutolinkerConfig): Match[];
+ /**
+ * The Autolinker version number exposed on the instance itself.
+ *
+ * Ex: 0.25.1
+ */
+ readonly version = "3.14.1";
+ /**
+ * @cfg {Boolean/Object} [urls]
+ *
+ * `true` if URLs should be automatically linked, `false` if they should not
+ * be. Defaults to `true`.
+ *
+ * Examples:
+ *
+ * urls: true
+ *
+ * // or
+ *
+ * urls: {
+ * schemeMatches : true,
+ * wwwMatches : true,
+ * tldMatches : true
+ * }
+ *
+ * As shown above, this option also accepts an Object form with 3 properties
+ * to allow for more customization of what exactly gets linked. All default
+ * to `true`:
+ *
+ * @cfg {Boolean} [urls.schemeMatches] `true` to match URLs found prefixed
+ * with a scheme, i.e. `http://google.com`, or `other+scheme://google.com`,
+ * `false` to prevent these types of matches.
+ * @cfg {Boolean} [urls.wwwMatches] `true` to match urls found prefixed with
+ * `'www.'`, i.e. `www.google.com`. `false` to prevent these types of
+ * matches. Note that if the URL had a prefixed scheme, and
+ * `schemeMatches` is true, it will still be linked.
+ * @cfg {Boolean} [urls.tldMatches] `true` to match URLs with known top
+ * level domains (.com, .net, etc.) that are not prefixed with a scheme or
+ * `'www.'`. This option attempts to match anything that looks like a URL
+ * in the given text. Ex: `google.com`, `asdf.org/?page=1`, etc. `false`
+ * to prevent these types of matches.
+ */
+ private readonly urls;
+ /**
+ * @cfg {Boolean} [email=true]
+ *
+ * `true` if email addresses should be automatically linked, `false` if they
+ * should not be.
+ */
+ private readonly email;
+ /**
+ * @cfg {Boolean} [phone=true]
+ *
+ * `true` if Phone numbers ("(555)555-5555") should be automatically linked,
+ * `false` if they should not be.
+ */
+ private readonly phone;
+ /**
+ * @cfg {Boolean/String} [hashtag=false]
+ *
+ * A string for the service name to have hashtags (ex: "#myHashtag")
+ * auto-linked to. The currently-supported values are:
+ *
+ * - 'twitter'
+ * - 'facebook'
+ * - 'instagram'
+ *
+ * Pass `false` to skip auto-linking of hashtags.
+ */
+ private readonly hashtag;
+ /**
+ * @cfg {String/Boolean} [mention=false]
+ *
+ * A string for the service name to have mentions (ex: "@myuser")
+ * auto-linked to. The currently supported values are:
+ *
+ * - 'twitter'
+ * - 'instagram'
+ * - 'soundcloud'
+ *
+ * Defaults to `false` to skip auto-linking of mentions.
+ */
+ private readonly mention;
+ /**
+ * @cfg {Boolean} [newWindow=true]
+ *
+ * `true` if the links should open in a new window, `false` otherwise.
+ */
+ private readonly newWindow;
+ /**
+ * @cfg {Boolean/Object} [stripPrefix=true]
+ *
+ * `true` if 'http://' (or 'https://') and/or the 'www.' should be stripped
+ * from the beginning of URL links' text, `false` otherwise. Defaults to
+ * `true`.
+ *
+ * Examples:
+ *
+ * stripPrefix: true
+ *
+ * // or
+ *
+ * stripPrefix: {
+ * scheme : true,
+ * www : true
+ * }
+ *
+ * As shown above, this option also accepts an Object form with 2 properties
+ * to allow for more customization of what exactly is prevented from being
+ * displayed. Both default to `true`:
+ *
+ * @cfg {Boolean} [stripPrefix.scheme] `true` to prevent the scheme part of
+ * a URL match from being displayed to the user. Example:
+ * `'http://google.com'` will be displayed as `'google.com'`. `false` to
+ * not strip the scheme. NOTE: Only an `'http://'` or `'https://'` scheme
+ * will be removed, so as not to remove a potentially dangerous scheme
+ * (such as `'file://'` or `'javascript:'`)
+ * @cfg {Boolean} [stripPrefix.www] www (Boolean): `true` to prevent the
+ * `'www.'` part of a URL match from being displayed to the user. Ex:
+ * `'www.google.com'` will be displayed as `'google.com'`. `false` to not
+ * strip the `'www'`.
+ */
+ private readonly stripPrefix;
+ /**
+ * @cfg {Boolean} [stripTrailingSlash=true]
+ *
+ * `true` to remove the trailing slash from URL matches, `false` to keep
+ * the trailing slash.
+ *
+ * Example when `true`: `http://google.com/` will be displayed as
+ * `http://google.com`.
+ */
+ private readonly stripTrailingSlash;
+ /**
+ * @cfg {Boolean} [decodePercentEncoding=true]
+ *
+ * `true` to decode percent-encoded characters in URL matches, `false` to keep
+ * the percent-encoded characters.
+ *
+ * Example when `true`: `https://en.wikipedia.org/wiki/San_Jos%C3%A9` will
+ * be displayed as `https://en.wikipedia.org/wiki/San_José`.
+ */
+ private readonly decodePercentEncoding;
+ /**
+ * @cfg {Number/Object} [truncate=0]
+ *
+ * ## Number Form
+ *
+ * A number for how many characters matched text should be truncated to
+ * inside the text of a link. If the matched text is over this number of
+ * characters, it will be truncated to this length by adding a two period
+ * ellipsis ('..') to the end of the string.
+ *
+ * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file'
+ * truncated to 25 characters might look something like this:
+ * 'yahoo.com/some/long/pat..'
+ *
+ * Example Usage:
+ *
+ * truncate: 25
+ *
+ *
+ * Defaults to `0` for "no truncation."
+ *
+ *
+ * ## Object Form
+ *
+ * An Object may also be provided with two properties: `length` (Number) and
+ * `location` (String). `location` may be one of the following: 'end'
+ * (default), 'middle', or 'smart'.
+ *
+ * Example Usage:
+ *
+ * truncate: { length: 25, location: 'middle' }
+ *
+ * @cfg {Number} [truncate.length=0] How many characters to allow before
+ * truncation will occur. Defaults to `0` for "no truncation."
+ * @cfg {"end"/"middle"/"smart"} [truncate.location="end"]
+ *
+ * - 'end' (default): will truncate up to the number of characters, and then
+ * add an ellipsis at the end. Ex: 'yahoo.com/some/long/pat..'
+ * - 'middle': will truncate and add the ellipsis in the middle. Ex:
+ * 'yahoo.com/s..th/to/a/file'
+ * - 'smart': for URLs where the algorithm attempts to strip out unnecessary
+ * parts first (such as the 'www.', then URL scheme, hash, etc.),
+ * attempting to make the URL human-readable before looking for a good
+ * point to insert the ellipsis if it is still too long. Ex:
+ * 'yahoo.com/some..to/a/file'. For more details, see
+ * {@link Autolinker.truncate.TruncateSmart}.
+ */
+ private readonly truncate;
+ /**
+ * @cfg {String} className
+ *
+ * A CSS class name to add to the generated links. This class will be added
+ * to all links, as well as this class plus match suffixes for styling
+ * url/email/phone/hashtag/mention links differently.
+ *
+ * For example, if this config is provided as "myLink", then:
+ *
+ * - URL links will have the CSS classes: "myLink myLink-url"
+ * - Email links will have the CSS classes: "myLink myLink-email", and
+ * - Phone links will have the CSS classes: "myLink myLink-phone"
+ * - Hashtag links will have the CSS classes: "myLink myLink-hashtag"
+ * - Mention links will have the CSS classes: "myLink myLink-mention myLink-[type]"
+ * where [type] is either "instagram", "twitter" or "soundcloud"
+ */
+ private readonly className;
+ /**
+ * @cfg {Function} replaceFn
+ *
+ * A function to individually process each match found in the input string.
+ *
+ * See the class's description for usage.
+ *
+ * The `replaceFn` can be called with a different context object (`this`
+ * reference) using the {@link #context} cfg.
+ *
+ * This function is called with the following parameter:
+ *
+ * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which
+ * can be used to retrieve information about the match that the `replaceFn`
+ * is currently processing. See {@link Autolinker.match.Match} subclasses
+ * for details.
+ */
+ private readonly replaceFn;
+ /**
+ * @cfg {Object} context
+ *
+ * The context object (`this` reference) to call the `replaceFn` with.
+ *
+ * Defaults to this Autolinker instance.
+ */
+ private readonly context;
+ /**
+ * @cfg {Boolean} [sanitizeHtml=false]
+ *
+ * `true` to HTML-encode the start and end brackets of existing HTML tags found
+ * in the input string. This will escape `<` and `>` characters to `<` and
+ * `>`, respectively.
+ *
+ * Setting this to `true` will prevent XSS (Cross-site Scripting) attacks,
+ * but will remove the significance of existing HTML tags in the input string. If
+ * you would like to maintain the significance of existing HTML tags while also
+ * making the output HTML string safe, leave this option as `false` and use a
+ * tool like https://github.com/cure53/DOMPurify (or others) on the input string
+ * before running Autolinker.
+ */
+ private readonly sanitizeHtml;
+ /**
+ * @private
+ * @property {Autolinker.matcher.Matcher[]} matchers
+ *
+ * The {@link Autolinker.matcher.Matcher} instances for this Autolinker
+ * instance.
+ *
+ * This is lazily created in {@link #getMatchers}.
+ */
+ private matchers;
+ /**
+ * @private
+ * @property {Autolinker.AnchorTagBuilder} tagBuilder
+ *
+ * The AnchorTagBuilder instance used to build match replacement anchor tags.
+ * Note: this is lazily instantiated in the {@link #getTagBuilder} method.
+ */
+ private tagBuilder;
+ /**
+ * @method constructor
+ * @param {Object} [cfg] The configuration options for the Autolinker instance,
+ * specified in an Object (map).
+ */
+ constructor(cfg?: AutolinkerConfig);
+ /**
+ * Normalizes the {@link #urls} config into an Object with 3 properties:
+ * `schemeMatches`, `wwwMatches`, and `tldMatches`, all Booleans.
+ *
+ * See {@link #urls} config for details.
+ *
+ * @private
+ * @param {Boolean/Object} urls
+ * @return {Object}
+ */
+ private normalizeUrlsCfg;
+ /**
+ * Normalizes the {@link #stripPrefix} config into an Object with 2
+ * properties: `scheme`, and `www` - both Booleans.
+ *
+ * See {@link #stripPrefix} config for details.
+ *
+ * @private
+ * @param {Boolean/Object} stripPrefix
+ * @return {Object}
+ */
+ private normalizeStripPrefixCfg;
+ /**
+ * Normalizes the {@link #truncate} config into an Object with 2 properties:
+ * `length` (Number), and `location` (String).
+ *
+ * See {@link #truncate} config for details.
+ *
+ * @private
+ * @param {Number/Object} truncate
+ * @return {Object}
+ */
+ private normalizeTruncateCfg;
+ /**
+ * Parses the input `textOrHtml` looking for URLs, email addresses, phone
+ * numbers, username handles, and hashtags (depending on the configuration
+ * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
+ * objects describing those matches (without making any replacements).
+ *
+ * This method is used by the {@link #link} method, but can also be used to
+ * simply do parsing of the input in order to discover what kinds of links
+ * there are and how many.
+ *
+ * Example usage:
+ *
+ * var autolinker = new Autolinker( {
+ * urls: true,
+ * email: true
+ * } );
+ *
+ * var matches = autolinker.parse( "Hello google.com, I am asdf@asdf.com" );
+ *
+ * console.log( matches.length ); // 2
+ * console.log( matches[ 0 ].getType() ); // 'url'
+ * console.log( matches[ 0 ].getUrl() ); // 'google.com'
+ * console.log( matches[ 1 ].getType() ); // 'email'
+ * console.log( matches[ 1 ].getEmail() ); // 'asdf@asdf.com'
+ *
+ * @param {String} textOrHtml The HTML or text to find matches within
+ * (depending on if the {@link #urls}, {@link #email}, {@link #phone},
+ * {@link #hashtag}, and {@link #mention} options are enabled).
+ * @return {Autolinker.match.Match[]} The array of Matches found in the
+ * given input `textOrHtml`.
+ */
+ parse(textOrHtml: string): Match[];
+ /**
+ * After we have found all matches, we need to remove matches that overlap
+ * with a previous match. This can happen for instance with URLs, where the
+ * url 'google.com/#link' would match '#link' as a hashtag. Because the
+ * '#link' part is contained in a larger match that comes before the HashTag
+ * match, we'll remove the HashTag match.
+ *
+ * @private
+ * @param {Autolinker.match.Match[]} matches
+ * @return {Autolinker.match.Match[]}
+ */
+ private compactMatches;
+ /**
+ * Removes matches for matchers that were turned off in the options. For
+ * example, if {@link #hashtag hashtags} were not to be matched, we'll
+ * remove them from the `matches` array here.
+ *
+ * Note: we *must* use all Matchers on the input string, and then filter
+ * them out later. For example, if the options were `{ url: false, hashtag: true }`,
+ * we wouldn't want to match the text '#link' as a HashTag inside of the text
+ * 'google.com/#link'. The way the algorithm works is that we match the full
+ * URL first (which prevents the accidental HashTag match), and then we'll
+ * simply throw away the URL match.
+ *
+ * @private
+ * @param {Autolinker.match.Match[]} matches The array of matches to remove
+ * the unwanted matches from. Note: this array is mutated for the
+ * removals.
+ * @return {Autolinker.match.Match[]} The mutated input `matches` array.
+ */
+ private removeUnwantedMatches;
+ /**
+ * Parses the input `text` looking for URLs, email addresses, phone
+ * numbers, username handles, and hashtags (depending on the configuration
+ * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
+ * objects describing those matches.
+ *
+ * This method processes a **non-HTML string**, and is used to parse and
+ * match within the text nodes of an HTML string. This method is used
+ * internally by {@link #parse}.
+ *
+ * @private
+ * @param {String} text The text to find matches within (depending on if the
+ * {@link #urls}, {@link #email}, {@link #phone},
+ * {@link #hashtag}, and {@link #mention} options are enabled). This must be a non-HTML string.
+ * @param {Number} [offset=0] The offset of the text node within the
+ * original string. This is used when parsing with the {@link #parse}
+ * method to generate correct offsets within the {@link Autolinker.match.Match}
+ * instances, but may be omitted if calling this method publicly.
+ * @return {Autolinker.match.Match[]} The array of Matches found in the
+ * given input `text`.
+ */
+ private parseText;
+ /**
+ * Automatically links URLs, Email addresses, Phone numbers, Hashtags,
+ * and Mentions (Twitter, Instagram, Soundcloud) found in the given chunk of HTML. Does not link
+ * URLs found within HTML tags.
+ *
+ * For instance, if given the text: `You should go to http://www.yahoo.com`,
+ * then the result will be `You should go to
+ * <a href="http://www.yahoo.com">http://www.yahoo.com</a>`
+ *
+ * This method finds the text around any HTML elements in the input
+ * `textOrHtml`, which will be the text that is processed. Any original HTML
+ * elements will be left as-is, as well as the text that is already wrapped
+ * in anchor (<a>) tags.
+ *
+ * @param {String} textOrHtml The HTML or text to autolink matches within
+ * (depending on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #hashtag}, and {@link #mention} options are enabled).
+ * @return {String} The HTML, with matches automatically linked.
+ */
+ link(textOrHtml: string): string;
+ /**
+ * Creates the return string value for a given match in the input string.
+ *
+ * This method handles the {@link #replaceFn}, if one was provided.
+ *
+ * @private
+ * @param {Autolinker.match.Match} match The Match object that represents
+ * the match.
+ * @return {String} The string that the `match` should be replaced with.
+ * This is usually the anchor tag string, but may be the `matchStr` itself
+ * if the match is not to be replaced.
+ */
+ private createMatchReturnVal;
+ /**
+ * Lazily instantiates and returns the {@link Autolinker.matcher.Matcher}
+ * instances for this Autolinker instance.
+ *
+ * @private
+ * @return {Autolinker.matcher.Matcher[]}
+ */
+ private getMatchers;
+ /**
+ * Returns the {@link #tagBuilder} instance for this Autolinker instance,
+ * lazily instantiating it if it does not yet exist.
+ *
+ * @private
+ * @return {Autolinker.AnchorTagBuilder}
+ */
+ private getTagBuilder;
+}
+export interface AutolinkerConfig {
+ urls?: UrlsConfig;
+ email?: boolean;
+ phone?: boolean;
+ hashtag?: HashtagConfig;
+ mention?: MentionConfig;
+ newWindow?: boolean;
+ stripPrefix?: StripPrefixConfig;
+ stripTrailingSlash?: boolean;
+ truncate?: TruncateConfig;
+ className?: string;
+ replaceFn?: ReplaceFn | null;
+ context?: any;
+ sanitizeHtml?: boolean;
+ decodePercentEncoding?: boolean;
+}
+export declare type UrlsConfig = boolean | UrlsConfigObj;
+export interface UrlsConfigObj {
+ schemeMatches?: boolean;
+ wwwMatches?: boolean;
+ tldMatches?: boolean;
+}
+export declare type UrlMatchTypeOptions = 'scheme' | 'www' | 'tld';
+export declare type StripPrefixConfig = boolean | StripPrefixConfigObj;
+export interface StripPrefixConfigObj {
+ scheme?: boolean;
+ www?: boolean;
+}
+export declare type TruncateConfig = number | TruncateConfigObj;
+export interface TruncateConfigObj {
+ length?: number;
+ location?: "end" | "middle" | "smart";
+}
+export declare type HashtagConfig = false | HashtagServices;
+export declare type HashtagServices = 'twitter' | 'facebook' | 'instagram';
+export declare type MentionConfig = false | MentionServices;
+export declare type MentionServices = 'mastodon' | 'twitter' | 'instagram' | 'soundcloud';
+export declare type ReplaceFn = (match: Match) => ReplaceFnReturn;
+export declare type ReplaceFnReturn = boolean | string | HtmlTag | null | undefined | void;
diff --git a/src/modules/autolinker/autolinker.js b/src/modules/autolinker/autolinker.js
new file mode 100644
index 00000000..86ceb9f3
--- /dev/null
+++ b/src/modules/autolinker/autolinker.js
@@ -0,0 +1,907 @@
+import { defaults, remove, splitAndCapture } from "./utils";
+import { AnchorTagBuilder } from "./anchor-tag-builder";
+import { Match } from "./match/match";
+import { EmailMatch } from "./match/email-match";
+import { HashtagMatch } from "./match/hashtag-match";
+import { MentionMatch } from "./match/mention-match";
+import { PhoneMatch } from "./match/phone-match";
+import { UrlMatch } from "./match/url-match";
+import { Matcher } from "./matcher/matcher";
+import { HtmlTag } from "./html-tag";
+import { EmailMatcher } from "./matcher/email-matcher";
+import { UrlMatcher } from "./matcher/url-matcher";
+import { HashtagMatcher } from "./matcher/hashtag-matcher";
+import { PhoneMatcher } from "./matcher/phone-matcher";
+import { MentionMatcher } from "./matcher/mention-matcher";
+import { parseHtml } from './htmlParser/parse-html';
+/**
+ * @class Autolinker
+ * @extends Object
+ *
+ * Utility class used to process a given string of text, and wrap the matches in
+ * the appropriate anchor (<a>) tags to turn them into links.
+ *
+ * Any of the configuration options may be provided in an Object provided
+ * to the Autolinker constructor, which will configure how the {@link #link link()}
+ * method will process the links.
+ *
+ * For example:
+ *
+ * var autolinker = new Autolinker( {
+ * newWindow : false,
+ * truncate : 30
+ * } );
+ *
+ * var html = autolinker.link( "Joe went to www.yahoo.com" );
+ * // produces: 'Joe went to yahoo.com'
+ *
+ *
+ * The {@link #static-link static link()} method may also be used to inline
+ * options into a single call, which may be more convenient for one-off uses.
+ * For example:
+ *
+ * var html = Autolinker.link( "Joe went to www.yahoo.com", {
+ * newWindow : false,
+ * truncate : 30
+ * } );
+ * // produces: 'Joe went to yahoo.com'
+ *
+ *
+ * ## Custom Replacements of Links
+ *
+ * If the configuration options do not provide enough flexibility, a {@link #replaceFn}
+ * may be provided to fully customize the output of Autolinker. This function is
+ * called once for each URL/Email/Phone#/Hashtag/Mention (Twitter, Instagram, Soundcloud)
+ * match that is encountered.
+ *
+ * For example:
+ *
+ * var input = "..."; // string with URLs, Email Addresses, Phone #s, Hashtags, and Mentions (Twitter, Instagram, Soundcloud)
+ *
+ * var linkedText = Autolinker.link( input, {
+ * replaceFn : function( match ) {
+ * console.log( "href = ", match.getAnchorHref() );
+ * console.log( "text = ", match.getAnchorText() );
+ *
+ * switch( match.getType() ) {
+ * case 'url' :
+ * console.log( "url: ", match.getUrl() );
+ *
+ * if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) {
+ * var tag = match.buildTag(); // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes
+ * tag.setAttr( 'rel', 'nofollow' );
+ * tag.addClass( 'external-link' );
+ *
+ * return tag;
+ *
+ * } else {
+ * return true; // let Autolinker perform its normal anchor tag replacement
+ * }
+ *
+ * case 'email' :
+ * var email = match.getEmail();
+ * console.log( "email: ", email );
+ *
+ * if( email === "my@own.address" ) {
+ * return false; // don't auto-link this particular email address; leave as-is
+ * } else {
+ * return; // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`)
+ * }
+ *
+ * case 'phone' :
+ * var phoneNumber = match.getPhoneNumber();
+ * console.log( phoneNumber );
+ *
+ * return '' + phoneNumber + '';
+ *
+ * case 'hashtag' :
+ * var hashtag = match.getHashtag();
+ * console.log( hashtag );
+ *
+ * return '' + hashtag + '';
+ *
+ * case 'mention' :
+ * var mention = match.getMention();
+ * console.log( mention );
+ *
+ * return '' + mention + '';
+ * }
+ * }
+ * } );
+ *
+ *
+ * The function may return the following values:
+ *
+ * - `true` (Boolean): Allow Autolinker to replace the match as it normally
+ * would.
+ * - `false` (Boolean): Do not replace the current match at all - leave as-is.
+ * - Any String: If a string is returned from the function, the string will be
+ * used directly as the replacement HTML for the match.
+ * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify
+ * an HTML tag before writing out its HTML text.
+ */
+var Autolinker = /** @class */ (function () {
+ /**
+ * @method constructor
+ * @param {Object} [cfg] The configuration options for the Autolinker instance,
+ * specified in an Object (map).
+ */
+ function Autolinker(cfg) {
+ if (cfg === void 0) { cfg = {}; }
+ /**
+ * The Autolinker version number exposed on the instance itself.
+ *
+ * Ex: 0.25.1
+ */
+ this.version = Autolinker.version;
+ /**
+ * @cfg {Boolean/Object} [urls]
+ *
+ * `true` if URLs should be automatically linked, `false` if they should not
+ * be. Defaults to `true`.
+ *
+ * Examples:
+ *
+ * urls: true
+ *
+ * // or
+ *
+ * urls: {
+ * schemeMatches : true,
+ * wwwMatches : true,
+ * tldMatches : true
+ * }
+ *
+ * As shown above, this option also accepts an Object form with 3 properties
+ * to allow for more customization of what exactly gets linked. All default
+ * to `true`:
+ *
+ * @cfg {Boolean} [urls.schemeMatches] `true` to match URLs found prefixed
+ * with a scheme, i.e. `http://google.com`, or `other+scheme://google.com`,
+ * `false` to prevent these types of matches.
+ * @cfg {Boolean} [urls.wwwMatches] `true` to match urls found prefixed with
+ * `'www.'`, i.e. `www.google.com`. `false` to prevent these types of
+ * matches. Note that if the URL had a prefixed scheme, and
+ * `schemeMatches` is true, it will still be linked.
+ * @cfg {Boolean} [urls.tldMatches] `true` to match URLs with known top
+ * level domains (.com, .net, etc.) that are not prefixed with a scheme or
+ * `'www.'`. This option attempts to match anything that looks like a URL
+ * in the given text. Ex: `google.com`, `asdf.org/?page=1`, etc. `false`
+ * to prevent these types of matches.
+ */
+ this.urls = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Boolean} [email=true]
+ *
+ * `true` if email addresses should be automatically linked, `false` if they
+ * should not be.
+ */
+ this.email = true; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Boolean} [phone=true]
+ *
+ * `true` if Phone numbers ("(555)555-5555") should be automatically linked,
+ * `false` if they should not be.
+ */
+ this.phone = true; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Boolean/String} [hashtag=false]
+ *
+ * A string for the service name to have hashtags (ex: "#myHashtag")
+ * auto-linked to. The currently-supported values are:
+ *
+ * - 'twitter'
+ * - 'facebook'
+ * - 'instagram'
+ *
+ * Pass `false` to skip auto-linking of hashtags.
+ */
+ this.hashtag = false; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {String/Boolean} [mention=false]
+ *
+ * A string for the service name to have mentions (ex: "@myuser")
+ * auto-linked to. The currently supported values are:
+ *
+ * - 'twitter'
+ * - 'instagram'
+ * - 'soundcloud'
+ *
+ * Defaults to `false` to skip auto-linking of mentions.
+ */
+ this.mention = false; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Boolean} [newWindow=true]
+ *
+ * `true` if the links should open in a new window, `false` otherwise.
+ */
+ this.newWindow = true; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Boolean/Object} [stripPrefix=true]
+ *
+ * `true` if 'http://' (or 'https://') and/or the 'www.' should be stripped
+ * from the beginning of URL links' text, `false` otherwise. Defaults to
+ * `true`.
+ *
+ * Examples:
+ *
+ * stripPrefix: true
+ *
+ * // or
+ *
+ * stripPrefix: {
+ * scheme : true,
+ * www : true
+ * }
+ *
+ * As shown above, this option also accepts an Object form with 2 properties
+ * to allow for more customization of what exactly is prevented from being
+ * displayed. Both default to `true`:
+ *
+ * @cfg {Boolean} [stripPrefix.scheme] `true` to prevent the scheme part of
+ * a URL match from being displayed to the user. Example:
+ * `'http://google.com'` will be displayed as `'google.com'`. `false` to
+ * not strip the scheme. NOTE: Only an `'http://'` or `'https://'` scheme
+ * will be removed, so as not to remove a potentially dangerous scheme
+ * (such as `'file://'` or `'javascript:'`)
+ * @cfg {Boolean} [stripPrefix.www] www (Boolean): `true` to prevent the
+ * `'www.'` part of a URL match from being displayed to the user. Ex:
+ * `'www.google.com'` will be displayed as `'google.com'`. `false` to not
+ * strip the `'www'`.
+ */
+ this.stripPrefix = { scheme: true, www: true }; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Boolean} [stripTrailingSlash=true]
+ *
+ * `true` to remove the trailing slash from URL matches, `false` to keep
+ * the trailing slash.
+ *
+ * Example when `true`: `http://google.com/` will be displayed as
+ * `http://google.com`.
+ */
+ this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Boolean} [decodePercentEncoding=true]
+ *
+ * `true` to decode percent-encoded characters in URL matches, `false` to keep
+ * the percent-encoded characters.
+ *
+ * Example when `true`: `https://en.wikipedia.org/wiki/San_Jos%C3%A9` will
+ * be displayed as `https://en.wikipedia.org/wiki/San_José`.
+ */
+ this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Number/Object} [truncate=0]
+ *
+ * ## Number Form
+ *
+ * A number for how many characters matched text should be truncated to
+ * inside the text of a link. If the matched text is over this number of
+ * characters, it will be truncated to this length by adding a two period
+ * ellipsis ('..') to the end of the string.
+ *
+ * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file'
+ * truncated to 25 characters might look something like this:
+ * 'yahoo.com/some/long/pat..'
+ *
+ * Example Usage:
+ *
+ * truncate: 25
+ *
+ *
+ * Defaults to `0` for "no truncation."
+ *
+ *
+ * ## Object Form
+ *
+ * An Object may also be provided with two properties: `length` (Number) and
+ * `location` (String). `location` may be one of the following: 'end'
+ * (default), 'middle', or 'smart'.
+ *
+ * Example Usage:
+ *
+ * truncate: { length: 25, location: 'middle' }
+ *
+ * @cfg {Number} [truncate.length=0] How many characters to allow before
+ * truncation will occur. Defaults to `0` for "no truncation."
+ * @cfg {"end"/"middle"/"smart"} [truncate.location="end"]
+ *
+ * - 'end' (default): will truncate up to the number of characters, and then
+ * add an ellipsis at the end. Ex: 'yahoo.com/some/long/pat..'
+ * - 'middle': will truncate and add the ellipsis in the middle. Ex:
+ * 'yahoo.com/s..th/to/a/file'
+ * - 'smart': for URLs where the algorithm attempts to strip out unnecessary
+ * parts first (such as the 'www.', then URL scheme, hash, etc.),
+ * attempting to make the URL human-readable before looking for a good
+ * point to insert the ellipsis if it is still too long. Ex:
+ * 'yahoo.com/some..to/a/file'. For more details, see
+ * {@link Autolinker.truncate.TruncateSmart}.
+ */
+ this.truncate = { length: 0, location: 'end' }; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {String} className
+ *
+ * A CSS class name to add to the generated links. This class will be added
+ * to all links, as well as this class plus match suffixes for styling
+ * url/email/phone/hashtag/mention links differently.
+ *
+ * For example, if this config is provided as "myLink", then:
+ *
+ * - URL links will have the CSS classes: "myLink myLink-url"
+ * - Email links will have the CSS classes: "myLink myLink-email", and
+ * - Phone links will have the CSS classes: "myLink myLink-phone"
+ * - Hashtag links will have the CSS classes: "myLink myLink-hashtag"
+ * - Mention links will have the CSS classes: "myLink myLink-mention myLink-[type]"
+ * where [type] is either "instagram", "twitter" or "soundcloud"
+ */
+ this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Function} replaceFn
+ *
+ * A function to individually process each match found in the input string.
+ *
+ * See the class's description for usage.
+ *
+ * The `replaceFn` can be called with a different context object (`this`
+ * reference) using the {@link #context} cfg.
+ *
+ * This function is called with the following parameter:
+ *
+ * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which
+ * can be used to retrieve information about the match that the `replaceFn`
+ * is currently processing. See {@link Autolinker.match.Match} subclasses
+ * for details.
+ */
+ this.replaceFn = null; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Object} context
+ *
+ * The context object (`this` reference) to call the `replaceFn` with.
+ *
+ * Defaults to this Autolinker instance.
+ */
+ this.context = undefined; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @cfg {Boolean} [sanitizeHtml=false]
+ *
+ * `true` to HTML-encode the start and end brackets of existing HTML tags found
+ * in the input string. This will escape `<` and `>` characters to `<` and
+ * `>`, respectively.
+ *
+ * Setting this to `true` will prevent XSS (Cross-site Scripting) attacks,
+ * but will remove the significance of existing HTML tags in the input string. If
+ * you would like to maintain the significance of existing HTML tags while also
+ * making the output HTML string safe, leave this option as `false` and use a
+ * tool like https://github.com/cure53/DOMPurify (or others) on the input string
+ * before running Autolinker.
+ */
+ this.sanitizeHtml = false; // default value just to get the above doc comment in the ES5 output and documentation generator
+ /**
+ * @private
+ * @property {Autolinker.matcher.Matcher[]} matchers
+ *
+ * The {@link Autolinker.matcher.Matcher} instances for this Autolinker
+ * instance.
+ *
+ * This is lazily created in {@link #getMatchers}.
+ */
+ this.matchers = null;
+ /**
+ * @private
+ * @property {Autolinker.AnchorTagBuilder} tagBuilder
+ *
+ * The AnchorTagBuilder instance used to build match replacement anchor tags.
+ * Note: this is lazily instantiated in the {@link #getTagBuilder} method.
+ */
+ this.tagBuilder = null;
+ // Note: when `this.something` is used in the rhs of these assignments,
+ // it refers to the default values set above the constructor
+ this.urls = this.normalizeUrlsCfg(cfg.urls);
+ this.email = typeof cfg.email === 'boolean' ? cfg.email : this.email;
+ this.phone = typeof cfg.phone === 'boolean' ? cfg.phone : this.phone;
+ this.hashtag = cfg.hashtag || this.hashtag;
+ this.mention = cfg.mention || this.mention;
+ this.newWindow = typeof cfg.newWindow === 'boolean' ? cfg.newWindow : this.newWindow;
+ this.stripPrefix = this.normalizeStripPrefixCfg(cfg.stripPrefix);
+ this.stripTrailingSlash = typeof cfg.stripTrailingSlash === 'boolean' ? cfg.stripTrailingSlash : this.stripTrailingSlash;
+ this.decodePercentEncoding = typeof cfg.decodePercentEncoding === 'boolean' ? cfg.decodePercentEncoding : this.decodePercentEncoding;
+ this.sanitizeHtml = cfg.sanitizeHtml || false;
+ // Validate the value of the `mention` cfg
+ var mention = this.mention;
+ if (mention !== false && mention !== 'mastodon' && mention !== 'twitter' && mention !== 'instagram' && mention !== 'soundcloud') {
+ throw new Error("invalid `mention` cfg - see docs");
+ }
+ // Validate the value of the `hashtag` cfg
+ var hashtag = this.hashtag;
+ if (hashtag !== false && hashtag !== 'twitter' && hashtag !== 'facebook' && hashtag !== 'instagram') {
+ throw new Error("invalid `hashtag` cfg - see docs");
+ }
+ this.truncate = this.normalizeTruncateCfg(cfg.truncate);
+ this.className = cfg.className || this.className;
+ this.replaceFn = cfg.replaceFn || this.replaceFn;
+ this.context = cfg.context || this;
+ }
+ /**
+ * Automatically links URLs, Email addresses, Phone Numbers, Twitter handles,
+ * Hashtags, and Mentions found in the given chunk of HTML. Does not link URLs
+ * found within HTML tags.
+ *
+ * For instance, if given the text: `You should go to http://www.yahoo.com`,
+ * then the result will be `You should go to <a href="http://www.yahoo.com">http://www.yahoo.com</a>`
+ *
+ * Example:
+ *
+ * var linkedText = Autolinker.link( "Go to google.com", { newWindow: false } );
+ * // Produces: "Go to google.com"
+ *
+ * @static
+ * @param {String} textOrHtml The HTML or text to find matches within (depending
+ * on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #mention},
+ * {@link #hashtag}, and {@link #mention} options are enabled).
+ * @param {Object} [options] Any of the configuration options for the Autolinker
+ * class, specified in an Object (map). See the class description for an
+ * example call.
+ * @return {String} The HTML text, with matches automatically linked.
+ */
+ Autolinker.link = function (textOrHtml, options) {
+ var autolinker = new Autolinker(options);
+ return autolinker.link(textOrHtml);
+ };
+ /**
+ * Parses the input `textOrHtml` looking for URLs, email addresses, phone
+ * numbers, username handles, and hashtags (depending on the configuration
+ * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
+ * objects describing those matches (without making any replacements).
+ *
+ * Note that if parsing multiple pieces of text, it is slightly more efficient
+ * to create an Autolinker instance, and use the instance-level {@link #parse}
+ * method.
+ *
+ * Example:
+ *
+ * var matches = Autolinker.parse( "Hello google.com, I am asdf@asdf.com", {
+ * urls: true,
+ * email: true
+ * } );
+ *
+ * console.log( matches.length ); // 2
+ * console.log( matches[ 0 ].getType() ); // 'url'
+ * console.log( matches[ 0 ].getUrl() ); // 'google.com'
+ * console.log( matches[ 1 ].getType() ); // 'email'
+ * console.log( matches[ 1 ].getEmail() ); // 'asdf@asdf.com'
+ *
+ * @static
+ * @param {String} textOrHtml The HTML or text to find matches within
+ * (depending on if the {@link #urls}, {@link #email}, {@link #phone},
+ * {@link #hashtag}, and {@link #mention} options are enabled).
+ * @param {Object} [options] Any of the configuration options for the Autolinker
+ * class, specified in an Object (map). See the class description for an
+ * example call.
+ * @return {Autolinker.match.Match[]} The array of Matches found in the
+ * given input `textOrHtml`.
+ */
+ Autolinker.parse = function (textOrHtml, options) {
+ var autolinker = new Autolinker(options);
+ return autolinker.parse(textOrHtml);
+ };
+ /**
+ * Normalizes the {@link #urls} config into an Object with 3 properties:
+ * `schemeMatches`, `wwwMatches`, and `tldMatches`, all Booleans.
+ *
+ * See {@link #urls} config for details.
+ *
+ * @private
+ * @param {Boolean/Object} urls
+ * @return {Object}
+ */
+ Autolinker.prototype.normalizeUrlsCfg = function (urls) {
+ if (urls == null)
+ urls = true; // default to `true`
+ if (typeof urls === 'boolean') {
+ return { schemeMatches: urls, wwwMatches: urls, tldMatches: urls };
+ }
+ else { // object form
+ return {
+ schemeMatches: typeof urls.schemeMatches === 'boolean' ? urls.schemeMatches : true,
+ wwwMatches: typeof urls.wwwMatches === 'boolean' ? urls.wwwMatches : true,
+ tldMatches: typeof urls.tldMatches === 'boolean' ? urls.tldMatches : true
+ };
+ }
+ };
+ /**
+ * Normalizes the {@link #stripPrefix} config into an Object with 2
+ * properties: `scheme`, and `www` - both Booleans.
+ *
+ * See {@link #stripPrefix} config for details.
+ *
+ * @private
+ * @param {Boolean/Object} stripPrefix
+ * @return {Object}
+ */
+ Autolinker.prototype.normalizeStripPrefixCfg = function (stripPrefix) {
+ if (stripPrefix == null)
+ stripPrefix = true; // default to `true`
+ if (typeof stripPrefix === 'boolean') {
+ return { scheme: stripPrefix, www: stripPrefix };
+ }
+ else { // object form
+ return {
+ scheme: typeof stripPrefix.scheme === 'boolean' ? stripPrefix.scheme : true,
+ www: typeof stripPrefix.www === 'boolean' ? stripPrefix.www : true
+ };
+ }
+ };
+ /**
+ * Normalizes the {@link #truncate} config into an Object with 2 properties:
+ * `length` (Number), and `location` (String).
+ *
+ * See {@link #truncate} config for details.
+ *
+ * @private
+ * @param {Number/Object} truncate
+ * @return {Object}
+ */
+ Autolinker.prototype.normalizeTruncateCfg = function (truncate) {
+ if (typeof truncate === 'number') {
+ return { length: truncate, location: 'end' };
+ }
+ else { // object, or undefined/null
+ return defaults(truncate || {}, {
+ length: Number.POSITIVE_INFINITY,
+ location: 'end'
+ });
+ }
+ };
+ /**
+ * Parses the input `textOrHtml` looking for URLs, email addresses, phone
+ * numbers, username handles, and hashtags (depending on the configuration
+ * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
+ * objects describing those matches (without making any replacements).
+ *
+ * This method is used by the {@link #link} method, but can also be used to
+ * simply do parsing of the input in order to discover what kinds of links
+ * there are and how many.
+ *
+ * Example usage:
+ *
+ * var autolinker = new Autolinker( {
+ * urls: true,
+ * email: true
+ * } );
+ *
+ * var matches = autolinker.parse( "Hello google.com, I am asdf@asdf.com" );
+ *
+ * console.log( matches.length ); // 2
+ * console.log( matches[ 0 ].getType() ); // 'url'
+ * console.log( matches[ 0 ].getUrl() ); // 'google.com'
+ * console.log( matches[ 1 ].getType() ); // 'email'
+ * console.log( matches[ 1 ].getEmail() ); // 'asdf@asdf.com'
+ *
+ * @param {String} textOrHtml The HTML or text to find matches within
+ * (depending on if the {@link #urls}, {@link #email}, {@link #phone},
+ * {@link #hashtag}, and {@link #mention} options are enabled).
+ * @return {Autolinker.match.Match[]} The array of Matches found in the
+ * given input `textOrHtml`.
+ */
+ Autolinker.prototype.parse = function (textOrHtml) {
+ var _this = this;
+ var skipTagNames = ['a', 'style', 'script'], skipTagsStackCount = 0, // used to only Autolink text outside of anchor/script/style tags. We don't want to autolink something that is already linked inside of an tag, for instance
+ matches = [];
+ // Find all matches within the `textOrHtml` (but not matches that are
+ // already nested within ,