1 | "use strict";
|
---|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
3 | var version_1 = require("./version");
|
---|
4 | var utils_1 = require("./utils");
|
---|
5 | var anchor_tag_builder_1 = require("./anchor-tag-builder");
|
---|
6 | var match_1 = require("./match/match");
|
---|
7 | var email_match_1 = require("./match/email-match");
|
---|
8 | var hashtag_match_1 = require("./match/hashtag-match");
|
---|
9 | var mention_match_1 = require("./match/mention-match");
|
---|
10 | var phone_match_1 = require("./match/phone-match");
|
---|
11 | var url_match_1 = require("./match/url-match");
|
---|
12 | var matcher_1 = require("./matcher/matcher");
|
---|
13 | var html_tag_1 = require("./html-tag");
|
---|
14 | var email_matcher_1 = require("./matcher/email-matcher");
|
---|
15 | var url_matcher_1 = require("./matcher/url-matcher");
|
---|
16 | var hashtag_matcher_1 = require("./matcher/hashtag-matcher");
|
---|
17 | var phone_matcher_1 = require("./matcher/phone-matcher");
|
---|
18 | var mention_matcher_1 = require("./matcher/mention-matcher");
|
---|
19 | var parse_html_1 = require("./htmlParser/parse-html");
|
---|
20 | /**
|
---|
21 | * @class Autolinker
|
---|
22 | * @extends Object
|
---|
23 | *
|
---|
24 | * Utility class used to process a given string of text, and wrap the matches in
|
---|
25 | * the appropriate anchor (<a>) tags to turn them into links.
|
---|
26 | *
|
---|
27 | * Any of the configuration options may be provided in an Object provided
|
---|
28 | * to the Autolinker constructor, which will configure how the {@link #link link()}
|
---|
29 | * method will process the links.
|
---|
30 | *
|
---|
31 | * For example:
|
---|
32 | *
|
---|
33 | * var autolinker = new Autolinker( {
|
---|
34 | * newWindow : false,
|
---|
35 | * truncate : 30
|
---|
36 | * } );
|
---|
37 | *
|
---|
38 | * var html = autolinker.link( "Joe went to www.yahoo.com" );
|
---|
39 | * // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>'
|
---|
40 | *
|
---|
41 | *
|
---|
42 | * The {@link #static-link static link()} method may also be used to inline
|
---|
43 | * options into a single call, which may be more convenient for one-off uses.
|
---|
44 | * For example:
|
---|
45 | *
|
---|
46 | * var html = Autolinker.link( "Joe went to www.yahoo.com", {
|
---|
47 | * newWindow : false,
|
---|
48 | * truncate : 30
|
---|
49 | * } );
|
---|
50 | * // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>'
|
---|
51 | *
|
---|
52 | *
|
---|
53 | * ## Custom Replacements of Links
|
---|
54 | *
|
---|
55 | * If the configuration options do not provide enough flexibility, a {@link #replaceFn}
|
---|
56 | * may be provided to fully customize the output of Autolinker. This function is
|
---|
57 | * called once for each URL/Email/Phone#/Hashtag/Mention (Twitter, Instagram, Soundcloud)
|
---|
58 | * match that is encountered.
|
---|
59 | *
|
---|
60 | * For example:
|
---|
61 | *
|
---|
62 | * var input = "..."; // string with URLs, Email Addresses, Phone #s, Hashtags, and Mentions (Twitter, Instagram, Soundcloud)
|
---|
63 | *
|
---|
64 | * var linkedText = Autolinker.link( input, {
|
---|
65 | * replaceFn : function( match ) {
|
---|
66 | * console.log( "href = ", match.getAnchorHref() );
|
---|
67 | * console.log( "text = ", match.getAnchorText() );
|
---|
68 | *
|
---|
69 | * switch( match.getType() ) {
|
---|
70 | * case 'url' :
|
---|
71 | * console.log( "url: ", match.getUrl() );
|
---|
72 | *
|
---|
73 | * if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) {
|
---|
74 | * var tag = match.buildTag(); // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes
|
---|
75 | * tag.setAttr( 'rel', 'nofollow' );
|
---|
76 | * tag.addClass( 'external-link' );
|
---|
77 | *
|
---|
78 | * return tag;
|
---|
79 | *
|
---|
80 | * } else {
|
---|
81 | * return true; // let Autolinker perform its normal anchor tag replacement
|
---|
82 | * }
|
---|
83 | *
|
---|
84 | * case 'email' :
|
---|
85 | * var email = match.getEmail();
|
---|
86 | * console.log( "email: ", email );
|
---|
87 | *
|
---|
88 | * if( email === "my@own.address" ) {
|
---|
89 | * return false; // don't auto-link this particular email address; leave as-is
|
---|
90 | * } else {
|
---|
91 | * return; // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`)
|
---|
92 | * }
|
---|
93 | *
|
---|
94 | * case 'phone' :
|
---|
95 | * var phoneNumber = match.getPhoneNumber();
|
---|
96 | * console.log( phoneNumber );
|
---|
97 | *
|
---|
98 | * return '<a href="http://newplace.to.link.phone.numbers.to/">' + phoneNumber + '</a>';
|
---|
99 | *
|
---|
100 | * case 'hashtag' :
|
---|
101 | * var hashtag = match.getHashtag();
|
---|
102 | * console.log( hashtag );
|
---|
103 | *
|
---|
104 | * return '<a href="http://newplace.to.link.hashtag.handles.to/">' + hashtag + '</a>';
|
---|
105 | *
|
---|
106 | * case 'mention' :
|
---|
107 | * var mention = match.getMention();
|
---|
108 | * console.log( mention );
|
---|
109 | *
|
---|
110 | * return '<a href="http://newplace.to.link.mention.to/">' + mention + '</a>';
|
---|
111 | * }
|
---|
112 | * }
|
---|
113 | * } );
|
---|
114 | *
|
---|
115 | *
|
---|
116 | * The function may return the following values:
|
---|
117 | *
|
---|
118 | * - `true` (Boolean): Allow Autolinker to replace the match as it normally
|
---|
119 | * would.
|
---|
120 | * - `false` (Boolean): Do not replace the current match at all - leave as-is.
|
---|
121 | * - Any String: If a string is returned from the function, the string will be
|
---|
122 | * used directly as the replacement HTML for the match.
|
---|
123 | * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify
|
---|
124 | * an HTML tag before writing out its HTML text.
|
---|
125 | */
|
---|
126 | var Autolinker = /** @class */ (function () {
|
---|
127 | /**
|
---|
128 | * @method constructor
|
---|
129 | * @param {Object} [cfg] The configuration options for the Autolinker instance,
|
---|
130 | * specified in an Object (map).
|
---|
131 | */
|
---|
132 | function Autolinker(cfg) {
|
---|
133 | if (cfg === void 0) { cfg = {}; }
|
---|
134 | /**
|
---|
135 | * The Autolinker version number exposed on the instance itself.
|
---|
136 | *
|
---|
137 | * Ex: 0.25.1
|
---|
138 | */
|
---|
139 | this.version = Autolinker.version;
|
---|
140 | /**
|
---|
141 | * @cfg {Boolean/Object} [urls]
|
---|
142 | *
|
---|
143 | * `true` if URLs should be automatically linked, `false` if they should not
|
---|
144 | * be. Defaults to `true`.
|
---|
145 | *
|
---|
146 | * Examples:
|
---|
147 | *
|
---|
148 | * urls: true
|
---|
149 | *
|
---|
150 | * // or
|
---|
151 | *
|
---|
152 | * urls: {
|
---|
153 | * schemeMatches : true,
|
---|
154 | * wwwMatches : true,
|
---|
155 | * tldMatches : true
|
---|
156 | * }
|
---|
157 | *
|
---|
158 | * As shown above, this option also accepts an Object form with 3 properties
|
---|
159 | * to allow for more customization of what exactly gets linked. All default
|
---|
160 | * to `true`:
|
---|
161 | *
|
---|
162 | * @cfg {Boolean} [urls.schemeMatches] `true` to match URLs found prefixed
|
---|
163 | * with a scheme, i.e. `http://google.com`, or `other+scheme://google.com`,
|
---|
164 | * `false` to prevent these types of matches.
|
---|
165 | * @cfg {Boolean} [urls.wwwMatches] `true` to match urls found prefixed with
|
---|
166 | * `'www.'`, i.e. `www.google.com`. `false` to prevent these types of
|
---|
167 | * matches. Note that if the URL had a prefixed scheme, and
|
---|
168 | * `schemeMatches` is true, it will still be linked.
|
---|
169 | * @cfg {Boolean} [urls.tldMatches] `true` to match URLs with known top
|
---|
170 | * level domains (.com, .net, etc.) that are not prefixed with a scheme or
|
---|
171 | * `'www.'`. This option attempts to match anything that looks like a URL
|
---|
172 | * in the given text. Ex: `google.com`, `asdf.org/?page=1`, etc. `false`
|
---|
173 | * to prevent these types of matches.
|
---|
174 | */
|
---|
175 | this.urls = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
176 | /**
|
---|
177 | * @cfg {Boolean} [email=true]
|
---|
178 | *
|
---|
179 | * `true` if email addresses should be automatically linked, `false` if they
|
---|
180 | * should not be.
|
---|
181 | */
|
---|
182 | this.email = true; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
183 | /**
|
---|
184 | * @cfg {Boolean} [phone=true]
|
---|
185 | *
|
---|
186 | * `true` if Phone numbers ("(555)555-5555") should be automatically linked,
|
---|
187 | * `false` if they should not be.
|
---|
188 | */
|
---|
189 | this.phone = true; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
190 | /**
|
---|
191 | * @cfg {Boolean/String} [hashtag=false]
|
---|
192 | *
|
---|
193 | * A string for the service name to have hashtags (ex: "#myHashtag")
|
---|
194 | * auto-linked to. The currently-supported values are:
|
---|
195 | *
|
---|
196 | * - 'twitter'
|
---|
197 | * - 'facebook'
|
---|
198 | * - 'instagram'
|
---|
199 | *
|
---|
200 | * Pass `false` to skip auto-linking of hashtags.
|
---|
201 | */
|
---|
202 | this.hashtag = false; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
203 | /**
|
---|
204 | * @cfg {String/Boolean} [mention=false]
|
---|
205 | *
|
---|
206 | * A string for the service name to have mentions (ex: "@myuser")
|
---|
207 | * auto-linked to. The currently supported values are:
|
---|
208 | *
|
---|
209 | * - 'twitter'
|
---|
210 | * - 'instagram'
|
---|
211 | * - 'soundcloud'
|
---|
212 | *
|
---|
213 | * Defaults to `false` to skip auto-linking of mentions.
|
---|
214 | */
|
---|
215 | this.mention = false; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
216 | /**
|
---|
217 | * @cfg {Boolean} [newWindow=true]
|
---|
218 | *
|
---|
219 | * `true` if the links should open in a new window, `false` otherwise.
|
---|
220 | */
|
---|
221 | this.newWindow = true; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
222 | /**
|
---|
223 | * @cfg {Boolean/Object} [stripPrefix=true]
|
---|
224 | *
|
---|
225 | * `true` if 'http://' (or 'https://') and/or the 'www.' should be stripped
|
---|
226 | * from the beginning of URL links' text, `false` otherwise. Defaults to
|
---|
227 | * `true`.
|
---|
228 | *
|
---|
229 | * Examples:
|
---|
230 | *
|
---|
231 | * stripPrefix: true
|
---|
232 | *
|
---|
233 | * // or
|
---|
234 | *
|
---|
235 | * stripPrefix: {
|
---|
236 | * scheme : true,
|
---|
237 | * www : true
|
---|
238 | * }
|
---|
239 | *
|
---|
240 | * As shown above, this option also accepts an Object form with 2 properties
|
---|
241 | * to allow for more customization of what exactly is prevented from being
|
---|
242 | * displayed. Both default to `true`:
|
---|
243 | *
|
---|
244 | * @cfg {Boolean} [stripPrefix.scheme] `true` to prevent the scheme part of
|
---|
245 | * a URL match from being displayed to the user. Example:
|
---|
246 | * `'http://google.com'` will be displayed as `'google.com'`. `false` to
|
---|
247 | * not strip the scheme. NOTE: Only an `'http://'` or `'https://'` scheme
|
---|
248 | * will be removed, so as not to remove a potentially dangerous scheme
|
---|
249 | * (such as `'file://'` or `'javascript:'`)
|
---|
250 | * @cfg {Boolean} [stripPrefix.www] www (Boolean): `true` to prevent the
|
---|
251 | * `'www.'` part of a URL match from being displayed to the user. Ex:
|
---|
252 | * `'www.google.com'` will be displayed as `'google.com'`. `false` to not
|
---|
253 | * strip the `'www'`.
|
---|
254 | */
|
---|
255 | this.stripPrefix = {
|
---|
256 | scheme: true,
|
---|
257 | www: true,
|
---|
258 | }; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
259 | /**
|
---|
260 | * @cfg {Boolean} [stripTrailingSlash=true]
|
---|
261 | *
|
---|
262 | * `true` to remove the trailing slash from URL matches, `false` to keep
|
---|
263 | * the trailing slash.
|
---|
264 | *
|
---|
265 | * Example when `true`: `http://google.com/` will be displayed as
|
---|
266 | * `http://google.com`.
|
---|
267 | */
|
---|
268 | this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
269 | /**
|
---|
270 | * @cfg {Boolean} [decodePercentEncoding=true]
|
---|
271 | *
|
---|
272 | * `true` to decode percent-encoded characters in URL matches, `false` to keep
|
---|
273 | * the percent-encoded characters.
|
---|
274 | *
|
---|
275 | * Example when `true`: `https://en.wikipedia.org/wiki/San_Jos%C3%A9` will
|
---|
276 | * be displayed as `https://en.wikipedia.org/wiki/San_José`.
|
---|
277 | */
|
---|
278 | this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
279 | /**
|
---|
280 | * @cfg {Number/Object} [truncate=0]
|
---|
281 | *
|
---|
282 | * ## Number Form
|
---|
283 | *
|
---|
284 | * A number for how many characters matched text should be truncated to
|
---|
285 | * inside the text of a link. If the matched text is over this number of
|
---|
286 | * characters, it will be truncated to this length by adding a two period
|
---|
287 | * ellipsis ('..') to the end of the string.
|
---|
288 | *
|
---|
289 | * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file'
|
---|
290 | * truncated to 25 characters might look something like this:
|
---|
291 | * 'yahoo.com/some/long/pat..'
|
---|
292 | *
|
---|
293 | * Example Usage:
|
---|
294 | *
|
---|
295 | * truncate: 25
|
---|
296 | *
|
---|
297 | *
|
---|
298 | * Defaults to `0` for "no truncation."
|
---|
299 | *
|
---|
300 | *
|
---|
301 | * ## Object Form
|
---|
302 | *
|
---|
303 | * An Object may also be provided with two properties: `length` (Number) and
|
---|
304 | * `location` (String). `location` may be one of the following: 'end'
|
---|
305 | * (default), 'middle', or 'smart'.
|
---|
306 | *
|
---|
307 | * Example Usage:
|
---|
308 | *
|
---|
309 | * truncate: { length: 25, location: 'middle' }
|
---|
310 | *
|
---|
311 | * @cfg {Number} [truncate.length=0] How many characters to allow before
|
---|
312 | * truncation will occur. Defaults to `0` for "no truncation."
|
---|
313 | * @cfg {"end"/"middle"/"smart"} [truncate.location="end"]
|
---|
314 | *
|
---|
315 | * - 'end' (default): will truncate up to the number of characters, and then
|
---|
316 | * add an ellipsis at the end. Ex: 'yahoo.com/some/long/pat..'
|
---|
317 | * - 'middle': will truncate and add the ellipsis in the middle. Ex:
|
---|
318 | * 'yahoo.com/s..th/to/a/file'
|
---|
319 | * - 'smart': for URLs where the algorithm attempts to strip out unnecessary
|
---|
320 | * parts first (such as the 'www.', then URL scheme, hash, etc.),
|
---|
321 | * attempting to make the URL human-readable before looking for a good
|
---|
322 | * point to insert the ellipsis if it is still too long. Ex:
|
---|
323 | * 'yahoo.com/some..to/a/file'. For more details, see
|
---|
324 | * {@link Autolinker.truncate.TruncateSmart}.
|
---|
325 | */
|
---|
326 | this.truncate = {
|
---|
327 | length: 0,
|
---|
328 | location: 'end',
|
---|
329 | }; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
330 | /**
|
---|
331 | * @cfg {String} className
|
---|
332 | *
|
---|
333 | * A CSS class name to add to the generated links. This class will be added
|
---|
334 | * to all links, as well as this class plus match suffixes for styling
|
---|
335 | * url/email/phone/hashtag/mention links differently.
|
---|
336 | *
|
---|
337 | * For example, if this config is provided as "myLink", then:
|
---|
338 | *
|
---|
339 | * - URL links will have the CSS classes: "myLink myLink-url"
|
---|
340 | * - Email links will have the CSS classes: "myLink myLink-email", and
|
---|
341 | * - Phone links will have the CSS classes: "myLink myLink-phone"
|
---|
342 | * - Hashtag links will have the CSS classes: "myLink myLink-hashtag"
|
---|
343 | * - Mention links will have the CSS classes: "myLink myLink-mention myLink-[type]"
|
---|
344 | * where [type] is either "instagram", "twitter" or "soundcloud"
|
---|
345 | */
|
---|
346 | this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
347 | /**
|
---|
348 | * @cfg {Function} replaceFn
|
---|
349 | *
|
---|
350 | * A function to individually process each match found in the input string.
|
---|
351 | *
|
---|
352 | * See the class's description for usage.
|
---|
353 | *
|
---|
354 | * The `replaceFn` can be called with a different context object (`this`
|
---|
355 | * reference) using the {@link #context} cfg.
|
---|
356 | *
|
---|
357 | * This function is called with the following parameter:
|
---|
358 | *
|
---|
359 | * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which
|
---|
360 | * can be used to retrieve information about the match that the `replaceFn`
|
---|
361 | * is currently processing. See {@link Autolinker.match.Match} subclasses
|
---|
362 | * for details.
|
---|
363 | */
|
---|
364 | this.replaceFn = null; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
365 | /**
|
---|
366 | * @cfg {Object} context
|
---|
367 | *
|
---|
368 | * The context object (`this` reference) to call the `replaceFn` with.
|
---|
369 | *
|
---|
370 | * Defaults to this Autolinker instance.
|
---|
371 | */
|
---|
372 | this.context = undefined; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
373 | /**
|
---|
374 | * @cfg {Boolean} [sanitizeHtml=false]
|
---|
375 | *
|
---|
376 | * `true` to HTML-encode the start and end brackets of existing HTML tags found
|
---|
377 | * in the input string. This will escape `<` and `>` characters to `<` and
|
---|
378 | * `>`, respectively.
|
---|
379 | *
|
---|
380 | * Setting this to `true` will prevent XSS (Cross-site Scripting) attacks,
|
---|
381 | * but will remove the significance of existing HTML tags in the input string. If
|
---|
382 | * you would like to maintain the significance of existing HTML tags while also
|
---|
383 | * making the output HTML string safe, leave this option as `false` and use a
|
---|
384 | * tool like https://github.com/cure53/DOMPurify (or others) on the input string
|
---|
385 | * before running Autolinker.
|
---|
386 | */
|
---|
387 | this.sanitizeHtml = false; // default value just to get the above doc comment in the ES5 output and documentation generator
|
---|
388 | /**
|
---|
389 | * @private
|
---|
390 | * @property {Autolinker.matcher.Matcher[]} matchers
|
---|
391 | *
|
---|
392 | * The {@link Autolinker.matcher.Matcher} instances for this Autolinker
|
---|
393 | * instance.
|
---|
394 | *
|
---|
395 | * This is lazily created in {@link #getMatchers}.
|
---|
396 | */
|
---|
397 | this.matchers = null;
|
---|
398 | /**
|
---|
399 | * @private
|
---|
400 | * @property {Autolinker.AnchorTagBuilder} tagBuilder
|
---|
401 | *
|
---|
402 | * The AnchorTagBuilder instance used to build match replacement anchor tags.
|
---|
403 | * Note: this is lazily instantiated in the {@link #getTagBuilder} method.
|
---|
404 | */
|
---|
405 | this.tagBuilder = null;
|
---|
406 | // Note: when `this.something` is used in the rhs of these assignments,
|
---|
407 | // it refers to the default values set above the constructor
|
---|
408 | this.urls = this.normalizeUrlsCfg(cfg.urls);
|
---|
409 | this.email = typeof cfg.email === 'boolean' ? cfg.email : this.email;
|
---|
410 | this.phone = typeof cfg.phone === 'boolean' ? cfg.phone : this.phone;
|
---|
411 | this.hashtag = cfg.hashtag || this.hashtag;
|
---|
412 | this.mention = cfg.mention || this.mention;
|
---|
413 | this.newWindow = typeof cfg.newWindow === 'boolean' ? cfg.newWindow : this.newWindow;
|
---|
414 | this.stripPrefix = this.normalizeStripPrefixCfg(cfg.stripPrefix);
|
---|
415 | this.stripTrailingSlash =
|
---|
416 | typeof cfg.stripTrailingSlash === 'boolean'
|
---|
417 | ? cfg.stripTrailingSlash
|
---|
418 | : this.stripTrailingSlash;
|
---|
419 | this.decodePercentEncoding =
|
---|
420 | typeof cfg.decodePercentEncoding === 'boolean'
|
---|
421 | ? cfg.decodePercentEncoding
|
---|
422 | : this.decodePercentEncoding;
|
---|
423 | this.sanitizeHtml = cfg.sanitizeHtml || false;
|
---|
424 | // Validate the value of the `mention` cfg
|
---|
425 | var mention = this.mention;
|
---|
426 | if (mention !== false &&
|
---|
427 | ['twitter', 'instagram', 'soundcloud', 'tiktok'].indexOf(mention) === -1) {
|
---|
428 | throw new Error("invalid `mention` cfg '".concat(mention, "' - see docs"));
|
---|
429 | }
|
---|
430 | // Validate the value of the `hashtag` cfg
|
---|
431 | var hashtag = this.hashtag;
|
---|
432 | if (hashtag !== false && hashtag_matcher_1.hashtagServices.indexOf(hashtag) === -1) {
|
---|
433 | throw new Error("invalid `hashtag` cfg '".concat(hashtag, "' - see docs"));
|
---|
434 | }
|
---|
435 | this.truncate = this.normalizeTruncateCfg(cfg.truncate);
|
---|
436 | this.className = cfg.className || this.className;
|
---|
437 | this.replaceFn = cfg.replaceFn || this.replaceFn;
|
---|
438 | this.context = cfg.context || this;
|
---|
439 | }
|
---|
440 | /**
|
---|
441 | * Automatically links URLs, Email addresses, Phone Numbers, Twitter handles,
|
---|
442 | * Hashtags, and Mentions found in the given chunk of HTML. Does not link URLs
|
---|
443 | * found within HTML tags.
|
---|
444 | *
|
---|
445 | * For instance, if given the text: `You should go to http://www.yahoo.com`,
|
---|
446 | * then the result will be `You should go to <a href="http://www.yahoo.com">http://www.yahoo.com</a>`
|
---|
447 | *
|
---|
448 | * Example:
|
---|
449 | *
|
---|
450 | * var linkedText = Autolinker.link( "Go to google.com", { newWindow: false } );
|
---|
451 | * // Produces: "Go to <a href="http://google.com">google.com</a>"
|
---|
452 | *
|
---|
453 | * @static
|
---|
454 | * @param {String} textOrHtml The HTML or text to find matches within (depending
|
---|
455 | * on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #mention},
|
---|
456 | * {@link #hashtag}, and {@link #mention} options are enabled).
|
---|
457 | * @param {Object} [options] Any of the configuration options for the Autolinker
|
---|
458 | * class, specified in an Object (map). See the class description for an
|
---|
459 | * example call.
|
---|
460 | * @return {String} The HTML text, with matches automatically linked.
|
---|
461 | */
|
---|
462 | Autolinker.link = function (textOrHtml, options) {
|
---|
463 | var autolinker = new Autolinker(options);
|
---|
464 | return autolinker.link(textOrHtml);
|
---|
465 | };
|
---|
466 | /**
|
---|
467 | * Parses the input `textOrHtml` looking for URLs, email addresses, phone
|
---|
468 | * numbers, username handles, and hashtags (depending on the configuration
|
---|
469 | * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
|
---|
470 | * objects describing those matches (without making any replacements).
|
---|
471 | *
|
---|
472 | * Note that if parsing multiple pieces of text, it is slightly more efficient
|
---|
473 | * to create an Autolinker instance, and use the instance-level {@link #parse}
|
---|
474 | * method.
|
---|
475 | *
|
---|
476 | * Example:
|
---|
477 | *
|
---|
478 | * var matches = Autolinker.parse( "Hello google.com, I am asdf@asdf.com", {
|
---|
479 | * urls: true,
|
---|
480 | * email: true
|
---|
481 | * } );
|
---|
482 | *
|
---|
483 | * console.log( matches.length ); // 2
|
---|
484 | * console.log( matches[ 0 ].getType() ); // 'url'
|
---|
485 | * console.log( matches[ 0 ].getUrl() ); // 'google.com'
|
---|
486 | * console.log( matches[ 1 ].getType() ); // 'email'
|
---|
487 | * console.log( matches[ 1 ].getEmail() ); // 'asdf@asdf.com'
|
---|
488 | *
|
---|
489 | * @static
|
---|
490 | * @param {String} textOrHtml The HTML or text to find matches within
|
---|
491 | * (depending on if the {@link #urls}, {@link #email}, {@link #phone},
|
---|
492 | * {@link #hashtag}, and {@link #mention} options are enabled).
|
---|
493 | * @param {Object} [options] Any of the configuration options for the Autolinker
|
---|
494 | * class, specified in an Object (map). See the class description for an
|
---|
495 | * example call.
|
---|
496 | * @return {Autolinker.match.Match[]} The array of Matches found in the
|
---|
497 | * given input `textOrHtml`.
|
---|
498 | */
|
---|
499 | Autolinker.parse = function (textOrHtml, options) {
|
---|
500 | var autolinker = new Autolinker(options);
|
---|
501 | return autolinker.parse(textOrHtml);
|
---|
502 | };
|
---|
503 | /**
|
---|
504 | * Normalizes the {@link #urls} config into an Object with 3 properties:
|
---|
505 | * `schemeMatches`, `wwwMatches`, and `tldMatches`, all Booleans.
|
---|
506 | *
|
---|
507 | * See {@link #urls} config for details.
|
---|
508 | *
|
---|
509 | * @private
|
---|
510 | * @param {Boolean/Object} urls
|
---|
511 | * @return {Object}
|
---|
512 | */
|
---|
513 | Autolinker.prototype.normalizeUrlsCfg = function (urls) {
|
---|
514 | if (urls == null)
|
---|
515 | urls = true; // default to `true`
|
---|
516 | if (typeof urls === 'boolean') {
|
---|
517 | return { schemeMatches: urls, wwwMatches: urls, tldMatches: urls };
|
---|
518 | }
|
---|
519 | else {
|
---|
520 | // object form
|
---|
521 | return {
|
---|
522 | schemeMatches: typeof urls.schemeMatches === 'boolean' ? urls.schemeMatches : true,
|
---|
523 | wwwMatches: typeof urls.wwwMatches === 'boolean' ? urls.wwwMatches : true,
|
---|
524 | tldMatches: typeof urls.tldMatches === 'boolean' ? urls.tldMatches : true,
|
---|
525 | };
|
---|
526 | }
|
---|
527 | };
|
---|
528 | /**
|
---|
529 | * Normalizes the {@link #stripPrefix} config into an Object with 2
|
---|
530 | * properties: `scheme`, and `www` - both Booleans.
|
---|
531 | *
|
---|
532 | * See {@link #stripPrefix} config for details.
|
---|
533 | *
|
---|
534 | * @private
|
---|
535 | * @param {Boolean/Object} stripPrefix
|
---|
536 | * @return {Object}
|
---|
537 | */
|
---|
538 | Autolinker.prototype.normalizeStripPrefixCfg = function (stripPrefix) {
|
---|
539 | if (stripPrefix == null)
|
---|
540 | stripPrefix = true; // default to `true`
|
---|
541 | if (typeof stripPrefix === 'boolean') {
|
---|
542 | return { scheme: stripPrefix, www: stripPrefix };
|
---|
543 | }
|
---|
544 | else {
|
---|
545 | // object form
|
---|
546 | return {
|
---|
547 | scheme: typeof stripPrefix.scheme === 'boolean' ? stripPrefix.scheme : true,
|
---|
548 | www: typeof stripPrefix.www === 'boolean' ? stripPrefix.www : true,
|
---|
549 | };
|
---|
550 | }
|
---|
551 | };
|
---|
552 | /**
|
---|
553 | * Normalizes the {@link #truncate} config into an Object with 2 properties:
|
---|
554 | * `length` (Number), and `location` (String).
|
---|
555 | *
|
---|
556 | * See {@link #truncate} config for details.
|
---|
557 | *
|
---|
558 | * @private
|
---|
559 | * @param {Number/Object} truncate
|
---|
560 | * @return {Object}
|
---|
561 | */
|
---|
562 | Autolinker.prototype.normalizeTruncateCfg = function (truncate) {
|
---|
563 | if (typeof truncate === 'number') {
|
---|
564 | return { length: truncate, location: 'end' };
|
---|
565 | }
|
---|
566 | else {
|
---|
567 | // object, or undefined/null
|
---|
568 | return (0, utils_1.defaults)(truncate || {}, {
|
---|
569 | length: Number.POSITIVE_INFINITY,
|
---|
570 | location: 'end',
|
---|
571 | });
|
---|
572 | }
|
---|
573 | };
|
---|
574 | /**
|
---|
575 | * Parses the input `textOrHtml` looking for URLs, email addresses, phone
|
---|
576 | * numbers, username handles, and hashtags (depending on the configuration
|
---|
577 | * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
|
---|
578 | * objects describing those matches (without making any replacements).
|
---|
579 | *
|
---|
580 | * This method is used by the {@link #link} method, but can also be used to
|
---|
581 | * simply do parsing of the input in order to discover what kinds of links
|
---|
582 | * there are and how many.
|
---|
583 | *
|
---|
584 | * Example usage:
|
---|
585 | *
|
---|
586 | * var autolinker = new Autolinker( {
|
---|
587 | * urls: true,
|
---|
588 | * email: true
|
---|
589 | * } );
|
---|
590 | *
|
---|
591 | * var matches = autolinker.parse( "Hello google.com, I am asdf@asdf.com" );
|
---|
592 | *
|
---|
593 | * console.log( matches.length ); // 2
|
---|
594 | * console.log( matches[ 0 ].getType() ); // 'url'
|
---|
595 | * console.log( matches[ 0 ].getUrl() ); // 'google.com'
|
---|
596 | * console.log( matches[ 1 ].getType() ); // 'email'
|
---|
597 | * console.log( matches[ 1 ].getEmail() ); // 'asdf@asdf.com'
|
---|
598 | *
|
---|
599 | * @param {String} textOrHtml The HTML or text to find matches within
|
---|
600 | * (depending on if the {@link #urls}, {@link #email}, {@link #phone},
|
---|
601 | * {@link #hashtag}, and {@link #mention} options are enabled).
|
---|
602 | * @return {Autolinker.match.Match[]} The array of Matches found in the
|
---|
603 | * given input `textOrHtml`.
|
---|
604 | */
|
---|
605 | Autolinker.prototype.parse = function (textOrHtml) {
|
---|
606 | var _this = this;
|
---|
607 | 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 <a> tag, for instance
|
---|
608 | matches = [];
|
---|
609 | // Find all matches within the `textOrHtml` (but not matches that are
|
---|
610 | // already nested within <a>, <style> and <script> tags)
|
---|
611 | (0, parse_html_1.parseHtml)(textOrHtml, {
|
---|
612 | onOpenTag: function (tagName) {
|
---|
613 | if (skipTagNames.indexOf(tagName) >= 0) {
|
---|
614 | skipTagsStackCount++;
|
---|
615 | }
|
---|
616 | },
|
---|
617 | onText: function (text, offset) {
|
---|
618 | // Only process text nodes that are not within an <a>, <style> or <script> tag
|
---|
619 | if (skipTagsStackCount === 0) {
|
---|
620 | // "Walk around" common HTML entities. An ' ' (for example)
|
---|
621 | // could be at the end of a URL, but we don't want to
|
---|
622 | // include the trailing '&' in the URL. See issue #76
|
---|
623 | // TODO: Handle HTML entities separately in parseHtml() and
|
---|
624 | // don't emit them as "text" except for & entities
|
---|
625 | var htmlCharacterEntitiesRegex = /( | |<|<|>|>|"|"|')/gi;
|
---|
626 | var textSplit = (0, utils_1.splitAndCapture)(text, htmlCharacterEntitiesRegex);
|
---|
627 | var currentOffset_1 = offset;
|
---|
628 | textSplit.forEach(function (splitText, i) {
|
---|
629 | // even number matches are text, odd numbers are html entities
|
---|
630 | if (i % 2 === 0) {
|
---|
631 | var textNodeMatches = _this.parseText(splitText, currentOffset_1);
|
---|
632 | matches.push.apply(matches, textNodeMatches);
|
---|
633 | }
|
---|
634 | currentOffset_1 += splitText.length;
|
---|
635 | });
|
---|
636 | }
|
---|
637 | },
|
---|
638 | onCloseTag: function (tagName) {
|
---|
639 | if (skipTagNames.indexOf(tagName) >= 0) {
|
---|
640 | skipTagsStackCount = Math.max(skipTagsStackCount - 1, 0); // attempt to handle extraneous </a> tags by making sure the stack count never goes below 0
|
---|
641 | }
|
---|
642 | },
|
---|
643 | onComment: function (offset) { },
|
---|
644 | onDoctype: function (offset) { }, // no need to process doctype nodes
|
---|
645 | });
|
---|
646 | // After we have found all matches, remove subsequent matches that
|
---|
647 | // overlap with a previous match. This can happen for instance with URLs,
|
---|
648 | // where the url 'google.com/#link' would match '#link' as a hashtag.
|
---|
649 | matches = this.compactMatches(matches);
|
---|
650 | // And finally, remove matches for match types that have been turned
|
---|
651 | // off. We needed to have all match types turned on initially so that
|
---|
652 | // things like hashtags could be filtered out if they were really just
|
---|
653 | // part of a URL match (for instance, as a named anchor).
|
---|
654 | matches = this.removeUnwantedMatches(matches);
|
---|
655 | return matches;
|
---|
656 | };
|
---|
657 | /**
|
---|
658 | * After we have found all matches, we need to remove matches that overlap
|
---|
659 | * with a previous match. This can happen for instance with URLs, where the
|
---|
660 | * url 'google.com/#link' would match '#link' as a hashtag. Because the
|
---|
661 | * '#link' part is contained in a larger match that comes before the HashTag
|
---|
662 | * match, we'll remove the HashTag match.
|
---|
663 | *
|
---|
664 | * @private
|
---|
665 | * @param {Autolinker.match.Match[]} matches
|
---|
666 | * @return {Autolinker.match.Match[]}
|
---|
667 | */
|
---|
668 | Autolinker.prototype.compactMatches = function (matches) {
|
---|
669 | // First, the matches need to be sorted in order of offset
|
---|
670 | matches.sort(function (a, b) {
|
---|
671 | return a.getOffset() - b.getOffset();
|
---|
672 | });
|
---|
673 | var i = 0;
|
---|
674 | while (i < matches.length - 1) {
|
---|
675 | var match = matches[i], offset = match.getOffset(), matchedTextLength = match.getMatchedText().length, endIdx = offset + matchedTextLength;
|
---|
676 | if (i + 1 < matches.length) {
|
---|
677 | // Remove subsequent matches that equal offset with current match
|
---|
678 | if (matches[i + 1].getOffset() === offset) {
|
---|
679 | var removeIdx = matches[i + 1].getMatchedText().length > matchedTextLength ? i : i + 1;
|
---|
680 | matches.splice(removeIdx, 1);
|
---|
681 | continue;
|
---|
682 | }
|
---|
683 | // Remove subsequent matches that overlap with the current match
|
---|
684 | if (matches[i + 1].getOffset() < endIdx) {
|
---|
685 | matches.splice(i + 1, 1);
|
---|
686 | continue;
|
---|
687 | }
|
---|
688 | }
|
---|
689 | i++;
|
---|
690 | }
|
---|
691 | return matches;
|
---|
692 | };
|
---|
693 | /**
|
---|
694 | * Removes matches for matchers that were turned off in the options. For
|
---|
695 | * example, if {@link #hashtag hashtags} were not to be matched, we'll
|
---|
696 | * remove them from the `matches` array here.
|
---|
697 | *
|
---|
698 | * Note: we *must* use all Matchers on the input string, and then filter
|
---|
699 | * them out later. For example, if the options were `{ url: false, hashtag: true }`,
|
---|
700 | * we wouldn't want to match the text '#link' as a HashTag inside of the text
|
---|
701 | * 'google.com/#link'. The way the algorithm works is that we match the full
|
---|
702 | * URL first (which prevents the accidental HashTag match), and then we'll
|
---|
703 | * simply throw away the URL match.
|
---|
704 | *
|
---|
705 | * @private
|
---|
706 | * @param {Autolinker.match.Match[]} matches The array of matches to remove
|
---|
707 | * the unwanted matches from. Note: this array is mutated for the
|
---|
708 | * removals.
|
---|
709 | * @return {Autolinker.match.Match[]} The mutated input `matches` array.
|
---|
710 | */
|
---|
711 | Autolinker.prototype.removeUnwantedMatches = function (matches) {
|
---|
712 | if (!this.hashtag)
|
---|
713 | (0, utils_1.remove)(matches, function (match) {
|
---|
714 | return match.getType() === 'hashtag';
|
---|
715 | });
|
---|
716 | if (!this.email)
|
---|
717 | (0, utils_1.remove)(matches, function (match) {
|
---|
718 | return match.getType() === 'email';
|
---|
719 | });
|
---|
720 | if (!this.phone)
|
---|
721 | (0, utils_1.remove)(matches, function (match) {
|
---|
722 | return match.getType() === 'phone';
|
---|
723 | });
|
---|
724 | if (!this.mention)
|
---|
725 | (0, utils_1.remove)(matches, function (match) {
|
---|
726 | return match.getType() === 'mention';
|
---|
727 | });
|
---|
728 | if (!this.urls.schemeMatches) {
|
---|
729 | (0, utils_1.remove)(matches, function (m) {
|
---|
730 | return m.getType() === 'url' && m.getUrlMatchType() === 'scheme';
|
---|
731 | });
|
---|
732 | }
|
---|
733 | if (!this.urls.wwwMatches) {
|
---|
734 | (0, utils_1.remove)(matches, function (m) { return m.getType() === 'url' && m.getUrlMatchType() === 'www'; });
|
---|
735 | }
|
---|
736 | if (!this.urls.tldMatches) {
|
---|
737 | (0, utils_1.remove)(matches, function (m) { return m.getType() === 'url' && m.getUrlMatchType() === 'tld'; });
|
---|
738 | }
|
---|
739 | return matches;
|
---|
740 | };
|
---|
741 | /**
|
---|
742 | * Parses the input `text` looking for URLs, email addresses, phone
|
---|
743 | * numbers, username handles, and hashtags (depending on the configuration
|
---|
744 | * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
|
---|
745 | * objects describing those matches.
|
---|
746 | *
|
---|
747 | * This method processes a **non-HTML string**, and is used to parse and
|
---|
748 | * match within the text nodes of an HTML string. This method is used
|
---|
749 | * internally by {@link #parse}.
|
---|
750 | *
|
---|
751 | * @private
|
---|
752 | * @param {String} text The text to find matches within (depending on if the
|
---|
753 | * {@link #urls}, {@link #email}, {@link #phone},
|
---|
754 | * {@link #hashtag}, and {@link #mention} options are enabled). This must be a non-HTML string.
|
---|
755 | * @param {Number} [offset=0] The offset of the text node within the
|
---|
756 | * original string. This is used when parsing with the {@link #parse}
|
---|
757 | * method to generate correct offsets within the {@link Autolinker.match.Match}
|
---|
758 | * instances, but may be omitted if calling this method publicly.
|
---|
759 | * @return {Autolinker.match.Match[]} The array of Matches found in the
|
---|
760 | * given input `text`.
|
---|
761 | */
|
---|
762 | Autolinker.prototype.parseText = function (text, offset) {
|
---|
763 | if (offset === void 0) { offset = 0; }
|
---|
764 | offset = offset || 0;
|
---|
765 | var matchers = this.getMatchers(), matches = [];
|
---|
766 | for (var i = 0, numMatchers = matchers.length; i < numMatchers; i++) {
|
---|
767 | var textMatches = matchers[i].parseMatches(text);
|
---|
768 | // Correct the offset of each of the matches. They are originally
|
---|
769 | // the offset of the match within the provided text node, but we
|
---|
770 | // need to correct them to be relative to the original HTML input
|
---|
771 | // string (i.e. the one provided to #parse).
|
---|
772 | for (var j = 0, numTextMatches = textMatches.length; j < numTextMatches; j++) {
|
---|
773 | textMatches[j].setOffset(offset + textMatches[j].getOffset());
|
---|
774 | }
|
---|
775 | matches.push.apply(matches, textMatches);
|
---|
776 | }
|
---|
777 | return matches;
|
---|
778 | };
|
---|
779 | /**
|
---|
780 | * Automatically links URLs, Email addresses, Phone numbers, Hashtags,
|
---|
781 | * and Mentions (Twitter, Instagram, Soundcloud) found in the given chunk of HTML. Does not link
|
---|
782 | * URLs found within HTML tags.
|
---|
783 | *
|
---|
784 | * For instance, if given the text: `You should go to http://www.yahoo.com`,
|
---|
785 | * then the result will be `You should go to
|
---|
786 | * <a href="http://www.yahoo.com">http://www.yahoo.com</a>`
|
---|
787 | *
|
---|
788 | * This method finds the text around any HTML elements in the input
|
---|
789 | * `textOrHtml`, which will be the text that is processed. Any original HTML
|
---|
790 | * elements will be left as-is, as well as the text that is already wrapped
|
---|
791 | * in anchor (<a>) tags.
|
---|
792 | *
|
---|
793 | * @param {String} textOrHtml The HTML or text to autolink matches within
|
---|
794 | * (depending on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #hashtag}, and {@link #mention} options are enabled).
|
---|
795 | * @return {String} The HTML, with matches automatically linked.
|
---|
796 | */
|
---|
797 | Autolinker.prototype.link = function (textOrHtml) {
|
---|
798 | if (!textOrHtml) {
|
---|
799 | return '';
|
---|
800 | } // handle `null` and `undefined` (for JavaScript users that don't have TypeScript support)
|
---|
801 | /* We would want to sanitize the start and end characters of a tag
|
---|
802 | * before processing the string in order to avoid an XSS scenario.
|
---|
803 | * This behaviour can be changed by toggling the sanitizeHtml option.
|
---|
804 | */
|
---|
805 | if (this.sanitizeHtml) {
|
---|
806 | textOrHtml = textOrHtml.replace(/</g, '<').replace(/>/g, '>');
|
---|
807 | }
|
---|
808 | var matches = this.parse(textOrHtml), newHtml = [], lastIndex = 0;
|
---|
809 | for (var i = 0, len = matches.length; i < len; i++) {
|
---|
810 | var match = matches[i];
|
---|
811 | newHtml.push(textOrHtml.substring(lastIndex, match.getOffset()));
|
---|
812 | newHtml.push(this.createMatchReturnVal(match));
|
---|
813 | lastIndex = match.getOffset() + match.getMatchedText().length;
|
---|
814 | }
|
---|
815 | newHtml.push(textOrHtml.substring(lastIndex)); // handle the text after the last match
|
---|
816 | return newHtml.join('');
|
---|
817 | };
|
---|
818 | /**
|
---|
819 | * Creates the return string value for a given match in the input string.
|
---|
820 | *
|
---|
821 | * This method handles the {@link #replaceFn}, if one was provided.
|
---|
822 | *
|
---|
823 | * @private
|
---|
824 | * @param {Autolinker.match.Match} match The Match object that represents
|
---|
825 | * the match.
|
---|
826 | * @return {String} The string that the `match` should be replaced with.
|
---|
827 | * This is usually the anchor tag string, but may be the `matchStr` itself
|
---|
828 | * if the match is not to be replaced.
|
---|
829 | */
|
---|
830 | Autolinker.prototype.createMatchReturnVal = function (match) {
|
---|
831 | // Handle a custom `replaceFn` being provided
|
---|
832 | var replaceFnResult;
|
---|
833 | if (this.replaceFn) {
|
---|
834 | replaceFnResult = this.replaceFn.call(this.context, match); // Autolinker instance is the context
|
---|
835 | }
|
---|
836 | if (typeof replaceFnResult === 'string') {
|
---|
837 | return replaceFnResult; // `replaceFn` returned a string, use that
|
---|
838 | }
|
---|
839 | else if (replaceFnResult === false) {
|
---|
840 | return match.getMatchedText(); // no replacement for the match
|
---|
841 | }
|
---|
842 | else if (replaceFnResult instanceof html_tag_1.HtmlTag) {
|
---|
843 | return replaceFnResult.toAnchorString();
|
---|
844 | }
|
---|
845 | else {
|
---|
846 | // replaceFnResult === true, or no/unknown return value from function
|
---|
847 | // Perform Autolinker's default anchor tag generation
|
---|
848 | var anchorTag = match.buildTag(); // returns an Autolinker.HtmlTag instance
|
---|
849 | return anchorTag.toAnchorString();
|
---|
850 | }
|
---|
851 | };
|
---|
852 | /**
|
---|
853 | * Lazily instantiates and returns the {@link Autolinker.matcher.Matcher}
|
---|
854 | * instances for this Autolinker instance.
|
---|
855 | *
|
---|
856 | * @private
|
---|
857 | * @return {Autolinker.matcher.Matcher[]}
|
---|
858 | */
|
---|
859 | Autolinker.prototype.getMatchers = function () {
|
---|
860 | if (!this.matchers) {
|
---|
861 | var tagBuilder = this.getTagBuilder();
|
---|
862 | var matchers = [
|
---|
863 | new hashtag_matcher_1.HashtagMatcher({
|
---|
864 | tagBuilder: tagBuilder,
|
---|
865 | serviceName: this.hashtag,
|
---|
866 | }),
|
---|
867 | new email_matcher_1.EmailMatcher({ tagBuilder: tagBuilder }),
|
---|
868 | new phone_matcher_1.PhoneMatcher({ tagBuilder: tagBuilder }),
|
---|
869 | new mention_matcher_1.MentionMatcher({
|
---|
870 | tagBuilder: tagBuilder,
|
---|
871 | serviceName: this.mention,
|
---|
872 | }),
|
---|
873 | new url_matcher_1.UrlMatcher({
|
---|
874 | tagBuilder: tagBuilder,
|
---|
875 | stripPrefix: this.stripPrefix,
|
---|
876 | stripTrailingSlash: this.stripTrailingSlash,
|
---|
877 | decodePercentEncoding: this.decodePercentEncoding,
|
---|
878 | }),
|
---|
879 | ];
|
---|
880 | return (this.matchers = matchers);
|
---|
881 | }
|
---|
882 | else {
|
---|
883 | return this.matchers;
|
---|
884 | }
|
---|
885 | };
|
---|
886 | /**
|
---|
887 | * Returns the {@link #tagBuilder} instance for this Autolinker instance,
|
---|
888 | * lazily instantiating it if it does not yet exist.
|
---|
889 | *
|
---|
890 | * @private
|
---|
891 | * @return {Autolinker.AnchorTagBuilder}
|
---|
892 | */
|
---|
893 | Autolinker.prototype.getTagBuilder = function () {
|
---|
894 | var tagBuilder = this.tagBuilder;
|
---|
895 | if (!tagBuilder) {
|
---|
896 | tagBuilder = this.tagBuilder = new anchor_tag_builder_1.AnchorTagBuilder({
|
---|
897 | newWindow: this.newWindow,
|
---|
898 | truncate: this.truncate,
|
---|
899 | className: this.className,
|
---|
900 | });
|
---|
901 | }
|
---|
902 | return tagBuilder;
|
---|
903 | };
|
---|
904 | // NOTE: must be 'export default' here for UMD module
|
---|
905 | /**
|
---|
906 | * @static
|
---|
907 | * @property {String} version
|
---|
908 | *
|
---|
909 | * The Autolinker version number in the form major.minor.patch
|
---|
910 | *
|
---|
911 | * Ex: 3.15.0
|
---|
912 | */
|
---|
913 | Autolinker.version = version_1.version;
|
---|
914 | /**
|
---|
915 | * For backwards compatibility with Autolinker 1.x, the AnchorTagBuilder
|
---|
916 | * class is provided as a static on the Autolinker class.
|
---|
917 | */
|
---|
918 | Autolinker.AnchorTagBuilder = anchor_tag_builder_1.AnchorTagBuilder;
|
---|
919 | /**
|
---|
920 | * For backwards compatibility with Autolinker 1.x, the HtmlTag class is
|
---|
921 | * provided as a static on the Autolinker class.
|
---|
922 | */
|
---|
923 | Autolinker.HtmlTag = html_tag_1.HtmlTag;
|
---|
924 | /**
|
---|
925 | * For backwards compatibility with Autolinker 1.x, the Matcher classes are
|
---|
926 | * provided as statics on the Autolinker class.
|
---|
927 | */
|
---|
928 | Autolinker.matcher = {
|
---|
929 | Email: email_matcher_1.EmailMatcher,
|
---|
930 | Hashtag: hashtag_matcher_1.HashtagMatcher,
|
---|
931 | Matcher: matcher_1.Matcher,
|
---|
932 | Mention: mention_matcher_1.MentionMatcher,
|
---|
933 | Phone: phone_matcher_1.PhoneMatcher,
|
---|
934 | Url: url_matcher_1.UrlMatcher,
|
---|
935 | };
|
---|
936 | /**
|
---|
937 | * For backwards compatibility with Autolinker 1.x, the Match classes are
|
---|
938 | * provided as statics on the Autolinker class.
|
---|
939 | */
|
---|
940 | Autolinker.match = {
|
---|
941 | Email: email_match_1.EmailMatch,
|
---|
942 | Hashtag: hashtag_match_1.HashtagMatch,
|
---|
943 | Match: match_1.Match,
|
---|
944 | Mention: mention_match_1.MentionMatch,
|
---|
945 | Phone: phone_match_1.PhoneMatch,
|
---|
946 | Url: url_match_1.UrlMatch,
|
---|
947 | };
|
---|
948 | return Autolinker;
|
---|
949 | }());
|
---|
950 | exports.default = Autolinker;
|
---|
951 | //# sourceMappingURL=autolinker.js.map |
---|