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