[d24f17c] | 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)
|
---|