1 | # Autolinker.js
|
2 |
|
3 | Because I had so much trouble finding a good auto-linking implementation out in
|
4 | the wild, I decided to roll my own. It seemed that everything I found out there
|
5 | was either an implementation that didn't cover every case, or was just limited
|
6 | in one way or another.
|
7 |
|
8 | So, this utility attempts to handle everything. It:
|
9 |
|
10 | - Autolinks URLs, whether or not they start with the protocol (i.e. 'http://').
|
11 | In other words, it will automatically link the text "google.com", as well as
|
12 | "http://google.com".
|
13 | - Will properly handle URLs with special characters
|
14 | - Will properly handle URLs with query parameters or a named anchor (i.e. hash)
|
15 | - Will autolink email addresses.
|
16 | - Will autolink phone numbers.
|
17 | - Will autolink mentions (Twitter, Instagram, Soundcloud, TikTok).
|
18 | - Will autolink hashtags.
|
19 | - Will properly handle HTML input. The utility will not change the `href`
|
20 | attribute inside anchor (<a>) tags (or any other tag/attribute),
|
21 | and will not accidentally wrap the inner text of an anchor tag with a
|
22 | new one (which would cause doubly-nested anchor tags).
|
23 |
|
24 | Hope that this utility helps you as well!
|
25 |
|
26 | Full API Docs: [http://gregjacobs.github.io/Autolinker.js/api/](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker)<br>
|
27 | Live Example: [http://gregjacobs.github.io/Autolinker.js/examples/live-example/](http://gregjacobs.github.io/Autolinker.js/examples/live-example/)
|
28 |
|
29 |
|
30 | ## v4.0 released September 2022
|
31 |
|
32 | See [Upgrading from v3.x -> v4.x (Breaking Changes)](#upgrading-from-v3x---v4x-breaking-changes) at the bottom of this readme.
|
33 |
|
34 | ## Installation
|
35 |
|
36 | #### Installing with the [npm](https://www.npmjs.org/) package manager:
|
37 |
|
38 | ```shell
|
39 | npm install autolinker --save
|
40 | ```
|
41 |
|
42 |
|
43 | #### Installing with the [Yarn](https://yarnpkg.com/) package manager:
|
44 |
|
45 | ```shell
|
46 | yarn add autolinker
|
47 | ```
|
48 |
|
49 |
|
50 | #### Installing with the [Bower](http://bower.io) package manager:
|
51 |
|
52 | ```shell
|
53 | bower install Autolinker.js --save
|
54 | ```
|
55 |
|
56 |
|
57 | #### Direct download
|
58 |
|
59 | Simply clone this repository or download a zip of the project, and link to
|
60 | either `dist/Autolinker.js` or `dist/Autolinker.min.js` with a script tag.
|
61 |
|
62 |
|
63 | ## Importing Autolinker
|
64 |
|
65 | #### ES6/TypeScript/Webpack:
|
66 |
|
67 | ```ts
|
68 | import Autolinker from 'autolinker';
|
69 | ```
|
70 |
|
71 | #### Node.js:
|
72 |
|
73 | ```javascript
|
74 | const Autolinker = require('autolinker');
|
75 | // note: npm wants an all-lowercase package name, but the utility is a class and
|
76 | // should be aliased with a capital letter
|
77 | ```
|
78 |
|
79 | #### Browser
|
80 |
|
81 | ```html
|
82 | <!-- 'Autolinker.js' or 'Autolinker.min.js' - non-minified is better for
|
83 | debugging, minified is better for users' download time -->
|
84 | <script src="path/to/autolinker/dist/Autolinker.min.js"></script>
|
85 | ```
|
86 |
|
87 |
|
88 | ## Usage
|
89 |
|
90 | Using the static [link()](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-static-method-link)
|
91 | method:
|
92 |
|
93 | ```javascript
|
94 | const linkedText = Autolinker.link(textToAutolink[, options]);
|
95 | ```
|
96 |
|
97 | Using as a class:
|
98 |
|
99 | ```javascript
|
100 | const autolinker = new Autolinker([ options ]);
|
101 |
|
102 | const linkedText = autolinker.link(textToAutoLink);
|
103 | ```
|
104 |
|
105 | Note: if using the same options to autolink multiple pieces of html/text, it is
|
106 | slightly more efficient to create a single Autolinker instance, and run the
|
107 | [link()](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-method-link)
|
108 | method repeatedly (i.e. use the "class" form above).
|
109 |
|
110 |
|
111 | #### Examples:
|
112 |
|
113 | ```javascript
|
114 | const linkedText = Autolinker.link("Check out google.com");
|
115 | // Produces: "Check out <a href="http://google.com" target="_blank" rel="noopener noreferrer">google.com</a>"
|
116 |
|
117 | const linkedText = Autolinker.link("Check out google.com", {
|
118 | newWindow: false
|
119 | });
|
120 | // Produces: "Check out <a href="http://google.com">google.com</a>"
|
121 | ```
|
122 |
|
123 | ## Options
|
124 |
|
125 | The following are the options which may be specified for linking. These are
|
126 | specified by providing an Object as the second parameter to [Autolinker.link()](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-static-method-link).
|
127 | These include:
|
128 |
|
129 | - [newWindow](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-newWindow) : boolean<br />
|
130 | `true` to have the links should open in a new window when clicked, `false`
|
131 | otherwise. Defaults to `true`.
|
132 |
|
133 | - [urls](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-urls) : boolean/Object<br />
|
134 | `true` to have URLs auto-linked, `false` to skip auto-linking of URLs. Defaults
|
135 | to `true`.
|
136 |
|
137 | This option also accepts an Object form with 3 properties to allow for
|
138 | more customization of what exactly gets linked. All default to `true`:
|
139 |
|
140 | - schemeMatches (boolean): `true` to match URLs found prefixed with a scheme,
|
141 | i.e. `http://google.com`, or `other+scheme://google.com`, `false` to
|
142 | prevent these types of matches.
|
143 | - tldMatches: `true` to match URLs with known top level domains (.com, .net,
|
144 | etc.) that are not prefixed with a scheme (i.e. 'http://'). Ex: `google.com`,
|
145 | `asdf.org/?page=1`, etc. Set to `false` to prevent these types of matches.
|
146 | - ipV4Matches (boolean): `true` to match IPv4 addresses. Ex: `192.168.0.1`.
|
147 | `false` to prevent these types of matches. Note that if the IP address had
|
148 | a prefixed scheme (such as 'http://'), and `schemeMatches` is true, it
|
149 | will still be linked.
|
150 |
|
151 | Example usage: `urls: { schemeMatches: true, tldMatches: false, ipV4Matches: true }`
|
152 |
|
153 | - [email](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-email) : boolean<br />
|
154 | `true` to have email addresses auto-linked, `false` to skip auto-linking of
|
155 | email addresses. Defaults to `true`.
|
156 |
|
157 | - [phone](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-phone) : boolean<br />
|
158 | `true` to have phone numbers auto-linked, `false` to skip auto-linking of
|
159 | phone numbers. Defaults to `true`.
|
160 |
|
161 | - [mention](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-mention) : string<br />
|
162 | A string for the service name to have mentions (@username) auto-linked to. Supported
|
163 | values at this time are 'twitter', 'soundcloud', 'instagram' and 'tiktok'. Pass `false` to skip
|
164 | auto-linking of mentions. Defaults to `false`.
|
165 |
|
166 | - [hashtag](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-hashtag) : boolean/string<br />
|
167 | A string for the service name to have hashtags auto-linked to. Supported
|
168 | values at this time are 'twitter', 'facebook', 'instagram' and 'tiktok'. Pass `false` to skip
|
169 | auto-linking of hashtags. Defaults to `false`.
|
170 |
|
171 | - [stripPrefix](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-stripPrefix) : boolean<br />
|
172 | `true` to have the `'http://'` (or `'https://'`) and/or the `'www.'`
|
173 | stripped from the beginning of displayed links, `false` otherwise.
|
174 | Defaults to `true`.
|
175 |
|
176 | This option also accepts an Object form with 2 properties to allow for
|
177 | more customization of what exactly is prevented from being displayed.
|
178 | Both default to `true`:
|
179 |
|
180 | - scheme (boolean): `true` to prevent the scheme part of a URL match
|
181 | from being displayed to the user. Example: `'http://google.com'`
|
182 | will be displayed as `'google.com'`. `false` to not strip the
|
183 | scheme. NOTE: Only an `'http://'` or `'https://'` scheme will be
|
184 | removed, so as not to remove a potentially dangerous scheme (such
|
185 | as `'file://'` or `'javascript:'`).
|
186 | - www (boolean): `true` to prevent the `'www.'` part of a URL match
|
187 | from being displayed to the user. Ex: `'www.google.com'` will be
|
188 | displayed as `'google.com'`. `false` to not strip the `'www'`.
|
189 |
|
190 | - [stripTrailingSlash](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-stripTrailingSlash) : boolean<br />
|
191 | `true` to remove the trailing slash from URL matches, `false` to keep
|
192 | the trailing slash. Example when `true`: `http://google.com/` will be
|
193 | displayed as `http://google.com`. Defaults to `true`.
|
194 |
|
195 | - [truncate](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-truncate) : number/Object<br />
|
196 | A number for how many characters long URLs/emails/Twitter handles/Twitter
|
197 | hashtags should be truncated to inside the text of a link. If the match is
|
198 | over the number of characters, it will be truncated to this length by
|
199 | replacing the end of the string with a two period ellipsis ('..').
|
200 |
|
201 | Example: a url like 'http://www.yahoo.com/some/long/path/to/a/file' truncated
|
202 | to 25 characters may look like this: 'yahoo.com/some/long/pat..'
|
203 |
|
204 | In the object form, both `length` and `location` may be specified to perform
|
205 | truncation. Available options for `location` are: 'end' (default), 'middle',
|
206 | or 'smart'. Example usage:
|
207 |
|
208 | ```javascript
|
209 | truncate: { length: 32, location: 'middle' }
|
210 | ```
|
211 |
|
212 | The 'smart' truncation option is for URLs where the algorithm attempts to
|
213 | strip out unnecessary parts of the URL (such as the 'www.', then URL scheme,
|
214 | hash, etc.) before trying to find a good point to insert the ellipsis if it is
|
215 | still too long. For details, see source code of:
|
216 | [TruncateSmart](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker.truncate.TruncateSmart)
|
217 |
|
218 | - [className](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-className) : string<br />
|
219 | A CSS class name to add to the generated anchor tags. This class will be added
|
220 | to all links, as well as this class plus "url"/"email"/"phone"/"hashtag"/"mention"
|
221 | suffixes for styling url/email/phone/hashtag/mention links differently.
|
222 |
|
223 | The name of the hashtag/mention service is also added as a CSS class for those
|
224 | types of matches.
|
225 |
|
226 | For example, if this config is provided as "my-link", then:
|
227 |
|
228 | - URL links will have the CSS classes: "my-link my-link-url"
|
229 | - Email links will have the CSS classes: "my-link my-link-email"
|
230 | - Phone links will have the CSS classes: "my-link my-link-phone"
|
231 | - Twitter mention links will have the CSS classes: "my-link my-link-mention my-link-twitter"
|
232 | - Instagram mention links will have the CSS classes: "my-link my-link-mention my-link-instagram"
|
233 | - Hashtag links will have the CSS classes: "my-link my-link-hashtag my-link-twitter"
|
234 |
|
235 | - [decodePercentEncoding](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-decodePercentEncoding): boolean<br />
|
236 | `true` to decode percent-encoded characters in URL matches, `false` to keep
|
237 | the percent-encoded characters.
|
238 |
|
239 | Example when `true`: `https://en.wikipedia.org/wiki/San_Jos%C3%A9` will
|
240 | be displayed as `https://en.wikipedia.org/wiki/San_José`.
|
241 |
|
242 | Defaults to `true`.
|
243 |
|
244 | - [replaceFn](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-replaceFn) : Function<br />
|
245 | A function to use to programmatically make replacements of matches in the
|
246 | input string, one at a time. See the section
|
247 | <a href="#custom-replacement-function">Custom Replacement Function</a> for
|
248 | more details.
|
249 |
|
250 | - [sanitizeHtml](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-sanitizeHtml) : boolean<br />
|
251 |
|
252 | `true` to HTML-encode the start and end brackets of existing HTML tags found
|
253 | in the input string. This will escape `<` and `>` characters to `<` and
|
254 | `>`, respectively.
|
255 |
|
256 | Setting this to `true` will prevent XSS (Cross-site Scripting) attacks,
|
257 | but will remove the significance of existing HTML tags in the input string. If
|
258 | you would like to maintain the significance of existing HTML tags while also
|
259 | making the output HTML string safe, leave this option as `false` and use a
|
260 | tool like https://github.com/cure53/DOMPurify (or others) on the input string
|
261 | before running Autolinker.
|
262 |
|
263 | Defaults to `false`.
|
264 |
|
265 | For example, if you wanted to disable links from opening in [new windows](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-newWindow), you could do:
|
266 |
|
267 | ```javascript
|
268 | const linkedText = Autolinker.link("Check out google.com", {
|
269 | newWindow: false
|
270 | });
|
271 | // Produces: "Check out <a href="http://google.com">google.com</a>"
|
272 | ```
|
273 |
|
274 | And if you wanted to truncate the length of URLs (while also not opening in a new window), you could do:
|
275 |
|
276 | ```javascript
|
277 | const linkedText = Autolinker.link("http://www.yahoo.com/some/long/path/to/a/file", {
|
278 | truncate: 25,
|
279 | newWindow: false
|
280 | });
|
281 | // Produces: "<a href="http://www.yahoo.com/some/long/path/to/a/file">yahoo.com/some/long/pat..</a>"
|
282 | ```
|
283 |
|
284 | ## More Examples
|
285 |
|
286 | One could update an entire DOM element that has unlinked text to auto-link them
|
287 | as such:
|
288 |
|
289 | ```javascript
|
290 | const myTextEl = document.getElementById('text');
|
291 | myTextEl.innerHTML = Autolinker.link(myTextEl.innerHTML);
|
292 | ```
|
293 |
|
294 | Using the same pre-configured [Autolinker](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker)
|
295 | instance in multiple locations of a codebase (usually by dependency injection):
|
296 |
|
297 | ```javascript
|
298 | const autolinker = new Autolinker({ newWindow: false, truncate: 25 });
|
299 |
|
300 | //...
|
301 |
|
302 | autolinker.link("Check out http://www.yahoo.com/some/long/path/to/a/file");
|
303 | // Produces: "Check out <a href="http://www.yahoo.com/some/long/path/to/a/file">yahoo.com/some/long/pat..</a>"
|
304 |
|
305 | //...
|
306 |
|
307 | autolinker.link( "Go to www.google.com" );
|
308 | // Produces: "Go to <a href="http://www.google.com">google.com</a>"
|
309 |
|
310 | ```
|
311 |
|
312 | ## Retrieving the List of Matches
|
313 |
|
314 | If you're just interested in retrieving the list of [Matches](http://greg-jacobs.com/Autolinker.js/api/#!/api/Autolinker.match.Match) without producing a transformed string, you can use the [parse()](http://greg-jacobs.com/Autolinker.js/api/#!/api/Autolinker-static-method-parse) method.
|
315 |
|
316 | For example:
|
317 |
|
318 | ```
|
319 | const matches = Autolinker.parse("Hello google.com, I am asdf@asdf.com", {
|
320 | urls: true,
|
321 | email: true
|
322 | });
|
323 |
|
324 | console.log(matches.length); // 2
|
325 | console.log(matches[0].type); // 'url'
|
326 | console.log(matches[0].getUrl()); // 'google.com'
|
327 | console.log(matches[1].type); // 'email'
|
328 | console.log(matches[1].getEmail()); // 'asdf@asdf.com'
|
329 | ```
|
330 |
|
331 |
|
332 | ## Custom Replacement Function
|
333 |
|
334 | A custom replacement function ([replaceFn](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker-cfg-replaceFn))
|
335 | may be provided to replace url/email/phone/mention/hashtag matches on an
|
336 | individual basis, based on the return from this function.
|
337 |
|
338 | #### Full example, for purposes of documenting the API:
|
339 |
|
340 | ```javascript
|
341 | const input = "..."; // string with URLs, Email Addresses, Mentions (Twitter, Instagram), and Hashtags
|
342 |
|
343 | const linkedText = Autolinker.link(input, {
|
344 | replaceFn : function(match) {
|
345 | console.log("href = ", match.getAnchorHref());
|
346 | console.log("text = ", match.getAnchorText());
|
347 |
|
348 | switch(match.type) {
|
349 | case 'url':
|
350 | console.log("url: ", match.getUrl());
|
351 |
|
352 | return true; // let Autolinker perform its normal anchor tag replacement
|
353 |
|
354 | case 'email':
|
355 | const email = match.getEmail();
|
356 | console.log("email: ", email);
|
357 |
|
358 | if(email === "my@own.address") {
|
359 | return false; // don't auto-link this particular email address; leave as-is
|
360 | } else {
|
361 | return; // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`)
|
362 | }
|
363 |
|
364 | case 'phone':
|
365 | console.log("Phone Number: ", match.getPhoneNumber());
|
366 |
|
367 | return '<a href="http://newplace.to.link.phone.numbers.to/">' + match.getPhoneNumber() + '</a>';
|
368 |
|
369 | case 'mention':
|
370 | console.log("Mention: ", match.getMention());
|
371 | console.log("Mention Service Name: ", match.getServiceName());
|
372 |
|
373 | return '<a href="http://newplace.to.link.mention.handles.to/">' + match.getMention() + '</a>';
|
374 |
|
375 | case 'hashtag':
|
376 | console.log("Hashtag: ", match.getHashtag());
|
377 |
|
378 | return '<a href="http://newplace.to.link.hashtag.handles.to/">' + match.getHashtag() + '</a>';
|
379 | }
|
380 | }
|
381 | } );
|
382 | ```
|
383 |
|
384 | #### Modifying the default generated anchor tag
|
385 |
|
386 | ```javascript
|
387 | const input = "..."; // string with URLs, Email Addresses, Mentions (Twitter, Instagram), and Hashtags
|
388 |
|
389 | const linkedText = Autolinker.link( input, {
|
390 | replaceFn : function( match ) {
|
391 | console.log("href = ", match.getAnchorHref());
|
392 | console.log("text = ", match.getAnchorText());
|
393 |
|
394 | const tag = match.buildTag(); // returns an `Autolinker.HtmlTag` instance for an <a> tag
|
395 | tag.setAttr('rel', 'nofollow'); // adds a 'rel' attribute
|
396 | tag.addClass('external-link'); // adds a CSS class
|
397 | tag.setInnerHtml('Click here!'); // sets the inner html for the anchor tag
|
398 |
|
399 | return tag;
|
400 | }
|
401 | } );
|
402 | ```
|
403 |
|
404 |
|
405 | The `replaceFn` is provided one argument:
|
406 |
|
407 | 1. An [Autolinker.match.Match](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker.match.Match)
|
408 | object which details the match that is to be replaced.
|
409 |
|
410 |
|
411 | A replacement of the match is made based on the return value of the function.
|
412 | The following return values may be provided:
|
413 |
|
414 | 1. No return value (`undefined`), or `true` (boolean): Delegate back to
|
415 | Autolinker to replace the match as it normally would.
|
416 | 2. `false` (boolean): Do not replace the current match at all - leave as-is.
|
417 | 3. Any string: If a string is returned from the function, the string will be used
|
418 | directly as the replacement HTML for the match.
|
419 | 4. An [Autolinker.HtmlTag](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker.HtmlTag)
|
420 | instance, which can be used to build/modify an HTML tag before writing out its
|
421 | HTML text.
|
422 |
|
423 |
|
424 | ## Full API Docs
|
425 |
|
426 | The full API docs for Autolinker may be referenced at:
|
427 | [http://gregjacobs.github.io/Autolinker.js/api/](http://gregjacobs.github.io/Autolinker.js/api/#!/api/Autolinker)
|
428 |
|
429 | ## Live Example
|
430 |
|
431 | [http://gregjacobs.github.io/Autolinker.js/examples/](http://gregjacobs.github.io/Autolinker.js/examples/)
|
432 |
|
433 |
|
434 | ## Upgrading from v3.x -> 4.x (Breaking Changes)
|
435 |
|
436 | 1. Internet Explorer support has been removed since its official demise in June
|
437 | 2022.
|
438 | 1. The `urls.wwwMatches` config has been removed. A `www.` prefix is now treated
|
439 | like any other subdomain of a top level domain (TLD) match (such as
|
440 | 'subdomain.google.com').
|
441 | 1. `Match.getType()` should be replaced with `Match.type`. This allows for
|
442 | TypeScript type narrowing of `Match` objects returned by the `parse()`
|
443 | method or inside the `replaceFn`.
|
444 | 1. The `Matcher` classes have been removed in favor of a single finite state
|
445 | machine parser, greatly improving the performance of Autolinker but removing
|
446 | some of the customizability of the old regular expressions. Will address this customizability in a future release.
|
447 | 1. `Autolinker.AnchorTagBuilder`, `Autolinker.HtmlTag`, and `Autolinker.match.*`
|
448 | references have been removed. These shouldn't be needed as public APIs, but
|
449 | please raise a GitHub issue if these are for some reason needed.
|
450 |
|
451 | ## Upgrading from v2.x -> v3.x (Breaking Changes)
|
452 |
|
453 | 1. If you are still on v1.x, first follow the instructions in the
|
454 | [Upgrading from v1.x -> v2.x](#upgrading-from-v1x---v2x-breaking-changes)
|
455 | section below.
|
456 | 2. The `HtmlParser` class has been removed in favor of an internal `parseHtml()`
|
457 | function which replaces the old regexp-based implementation with a state
|
458 | machine parser that is guaranteed to run in linear time. If you were using
|
459 | the `HtmlParser` class directly, I recommend switching to [htmlparser2](https://github.com/fb55/htmlparser2), which implements the HTML semantics
|
460 | better. The internal `parseHtml()` function that Autolinker now uses is
|
461 | fairly geared towards Autolinker's purposes, and may not be useful in a
|
462 | general HTML parsing sense.
|
463 |
|
464 | ## Upgrading from v1.x -> v2.x (Breaking Changes)
|
465 |
|
466 | 1. If you are still on v0.x, first follow the instructions in the
|
467 | [Upgrading from v0.x -> v1.x](#upgrading-from-v0x---v1x-breaking-changes)
|
468 | section below.
|
469 | 2. The codebase has been converted to TypeScript, and uses ES6 exports. You can
|
470 | now use the `import` statement to pull in the `Autolinker` class and related
|
471 | entities such as `Match`:
|
472 |
|
473 | ```ts
|
474 | // ES6/TypeScript/Webpack
|
475 | import Autolinker, { Match } from 'autolinker';
|
476 | ```
|
477 |
|
478 | The `require()` interface is still supported as well for Node.js:
|
479 |
|
480 | ```ts
|
481 | // Node.js
|
482 | const Autolinker = require('autolinker');
|
483 | ```
|
484 |
|
485 | 3. You will no longer need the `@types/autolinker` package as this package now
|
486 | exports its own types
|
487 | 4. You will no longer be able to override the regular expressions in the
|
488 | `Matcher` classes by assigning to the prototype (for instance, something like
|
489 | `PhoneMatcher.prototype.regex = ...`). This is due to how TypeScript creates
|
490 | properties for class instances in the constructor rather than on prototypes.
|
491 |
|
492 | The idea of providing your own regular expression for these classes is a
|
493 | brittle notion anyway, as the `Matcher` classes rely on capturing groups in
|
494 | the RegExp being in the right place, or even multiple capturing groups for
|
495 | the same piece of information to support a different format. These capturing
|
496 | groups and associated code are subject to change as the regular expression
|
497 | needs to be updated, and will not involve a major version release of
|
498 | Autolinker.
|
499 |
|
500 | In the future you will be able to override the default `Matcher` classes
|
501 | entirely to provide your own implementation, but please raise an issue (or
|
502 | +1 an issue) if you think the library should support a currently-unsupported
|
503 | format.
|
504 |
|
505 | ## Upgrading from v0.x -> v1.x (Breaking Changes)
|
506 |
|
507 | 1. `twitter` option removed, replaced with `mention` (which accepts 'twitter',
|
508 | 'instagram' and 'soundcloud' values)
|
509 | 2. Matching mentions (previously the `twitter` option) now defaults to
|
510 | being turned off. Previously, Twitter handle matching was on by
|
511 | default.
|
512 | 3. `replaceFn` option now called with just one argument: the `Match`
|
513 | object (previously was called with two arguments: `autolinker` and
|
514 | `match`)
|
515 | 4. (Used inside the `replaceFn`) `TwitterMatch` replaced with
|
516 | `MentionMatch`, and `MentionMatch.getType()` now returns `'mention'`
|
517 | instead of `'twitter'`
|
518 | 5. (Used inside the `replaceFn`) `TwitterMatch.getTwitterHandle()` ->
|
519 | `MentionMatch.getMention()`
|
520 |
|
521 |
|
522 | ## Developing / Contributing
|
523 |
|
524 | Pull requests definitely welcome. To setup the project, make
|
525 | sure you have [Node.js](https://nodejs.org) installed. Then
|
526 | open up a command prompt and type the following:
|
527 |
|
528 | ```
|
529 | cd Autolinker.js # where you cloned the project
|
530 | npm install
|
531 | ```
|
532 |
|
533 | To run the tests:
|
534 |
|
535 | ```
|
536 | npm run test
|
537 | ```
|
538 |
|
539 | - Make sure to add tests to check your new functionality/bugfix
|
540 | - Run the `npm run test` command to test
|
541 |
|
542 |
|
543 | #### Building the Project Fully
|
544 |
|
545 | For this you will need [Ruby](https://www.ruby-lang.org) installed (note: Ruby
|
546 | comes pre-installed on MacOS), with the [JSDuck](https://github.com/senchalabs/jsduck)
|
547 | gem.
|
548 |
|
549 | See https://github.com/senchalabs/jsduck#getting-it for installation
|
550 | instructions on Windows/Mac/Linux
|
551 |
|
552 | [JSDuck](https://github.com/senchalabs/jsduck) is used to build the project's
|
553 | API/documentation site. See [Documentation Generator Notes](#Documentation Generator Notes)
|
554 | for more info.
|
555 |
|
556 |
|
557 | #### Running the Live Example Page Locally
|
558 |
|
559 | Run:
|
560 |
|
561 | ```
|
562 | yarn serve
|
563 | ```
|
564 |
|
565 | Then open your browser to: http://localhost:8080/docs/examples/index.html
|
566 |
|
567 | You should be able to make a change to source files, and refresh the page to see
|
568 | the changes.
|
569 |
|
570 | Note: If anyone wants to submit a PR converting `gulp watch` to `webpack` with
|
571 | the live development server, that would be much appreciated :)
|
572 |
|
573 |
|
574 | #### Documentation Generator Notes
|
575 |
|
576 | This project uses [JSDuck](https://github.com/senchalabs/jsduck) for its
|
577 | documentation generation, which produces the page at [http://gregjacobs.github.io/Autolinker.js](http://gregjacobs.github.io/Autolinker.js).
|
578 |
|
579 | Unfortunately, JSDuck is a very old project that is no longer maintained. As
|
580 | such, it doesn't support TypeScript or anything from ES6 (the `class` keyword,
|
581 | arrow functions, etc). However, I have yet to find a better documentation
|
582 | generator that creates such a useful API site. (Suggestions for a new one are
|
583 | welcome though - please raise an issue.)
|
584 |
|
585 | Since ES6 is not supported, we must generate the documentation from the ES5
|
586 | output. As such, a few precautions must be taken care of to make sure the
|
587 | documentation comes out right:
|
588 |
|
589 | 1. `@cfg` documentation tags must exist above a class property that has a
|
590 | default value, or else it won't end up in the ES5 output. For example:
|
591 |
|
592 | ```ts
|
593 | // Will correctly end up in the ES5 output
|
594 |
|
595 | /**
|
596 | * @cfg {String} title
|
597 | */
|
598 | readonly title: string = '';
|
599 |
|
600 |
|
601 |
|
602 | // Will *not* end up in ES5 output, and thus, won't end up in the generated
|
603 | // documentation
|
604 |
|
605 | /**
|
606 | * @cfg {String} title
|
607 | */
|
608 | readonly title: string;
|
609 | ```
|
610 | 2. The `@constructor` tag must be replaced with `@method constructor`
|
611 |
|
612 |
|
613 | ## Changelog
|
614 |
|
615 | See [Releases](https://github.com/gregjacobs/Autolinker.js/releases)
|
616 |
|
\ | No newline at end of file |