Skip to content

Commit aa68d88

Browse files
committed
Build v0.22.0
1 parent ba438ba commit aa68d88

File tree

3 files changed

+136
-44
lines changed

3 files changed

+136
-44
lines changed

dist/Autolinker.js

Lines changed: 133 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
/*!
1818
* Autolinker.js
19-
* 0.21.0
19+
* 0.22.0
2020
*
2121
* Copyright(c) 2015 Gregory Jacobs <[email protected]>
2222
* MIT
@@ -138,44 +138,59 @@ var Autolinker = function( cfg ) {
138138
throw new Error( "invalid `hashtag` cfg - see docs" );
139139
}
140140

141-
// Normalize the `truncate` option
142-
var truncate = this.truncate = this.truncate || {};
143-
if( typeof truncate === 'number' ) {
144-
this.truncate = { length: truncate, location: 'end' };
145-
} else if( typeof truncate === 'object' ) {
146-
this.truncate.length = truncate.length || Number.POSITIVE_INFINITY;
147-
this.truncate.location = truncate.location || 'end';
148-
}
141+
// Normalize the configs
142+
this.urls = this.normalizeUrlsCfg( this.urls );
143+
this.truncate = this.normalizeTruncateCfg( this.truncate );
149144
};
150145

151146
Autolinker.prototype = {
152147
constructor : Autolinker, // fix constructor property
153148

154149
/**
155-
* @cfg {Boolean} urls
150+
* @cfg {Boolean/Object} urls
151+
*
152+
* `true` if URLs should be automatically linked, `false` if they should not
153+
* be.
154+
*
155+
* This option also accepts an Object form with 3 properties, to allow for
156+
* more customization of what exactly gets linked. All default to `true`:
156157
*
157-
* `true` if miscellaneous URLs should be automatically linked, `false` if they should not be.
158+
* @param {Boolean} schemeMatches `true` to match URLs found prefixed with a
159+
* scheme, i.e. `http://google.com`, or `other+scheme://google.com`,
160+
* `false` to prevent these types of matches.
161+
* @param {Boolean} wwwMatches `true` to match urls found prefixed with
162+
* `'www.'`, i.e. `www.google.com`. `false` to prevent these types of
163+
* matches. Note that if the URL had a prefixed scheme, and
164+
* `schemeMatches` is true, it will still be linked.
165+
* @param {Boolean} tldMatches `true` to match URLs with known top level
166+
* domains (.com, .net, etc.) that are not prefixed with a scheme or
167+
* `'www.'`. This option attempts to match anything that looks like a URL
168+
* in the given text. Ex: `google.com`, `asdf.org/?page=1`, etc. `false`
169+
* to prevent these types of matches.
158170
*/
159171
urls : true,
160172

161173
/**
162174
* @cfg {Boolean} email
163175
*
164-
* `true` if email addresses should be automatically linked, `false` if they should not be.
176+
* `true` if email addresses should be automatically linked, `false` if they
177+
* should not be.
165178
*/
166179
email : true,
167180

168181
/**
169182
* @cfg {Boolean} twitter
170183
*
171-
* `true` if Twitter handles ("@example") should be automatically linked, `false` if they should not be.
184+
* `true` if Twitter handles ("@example") should be automatically linked,
185+
* `false` if they should not be.
172186
*/
173187
twitter : true,
174188

175189
/**
176190
* @cfg {Boolean} phone
177191
*
178-
* `true` if Phone numbers ("(555)555-5555") should be automatically linked, `false` if they should not be.
192+
* `true` if Phone numbers ("(555)555-5555") should be automatically linked,
193+
* `false` if they should not be.
179194
*/
180195
phone: true,
181196

@@ -313,6 +328,49 @@ Autolinker.prototype = {
313328
*/
314329
tagBuilder : undefined,
315330

331+
332+
/**
333+
* Normalizes the {@link #urls} config into an Object with 3 properties:
334+
* `schemeMatches`, `wwwMatches`, and `tldMatches`, all Booleans.
335+
*
336+
* See {@link #urls} config for details.
337+
*
338+
* @private
339+
* @param {Boolean/Object} urls
340+
* @return {Object}
341+
*/
342+
normalizeUrlsCfg : function( urls ) {
343+
if( typeof urls === 'boolean' ) {
344+
return { schemeMatches: urls, wwwMatches: urls, tldMatches: urls };
345+
} else {
346+
return Autolinker.Util.defaults( urls || {}, { schemeMatches: true, wwwMatches: true, tldMatches: true } );
347+
}
348+
},
349+
350+
351+
/**
352+
* Normalizes the {@link #truncate} config into an Object with 2 properties:
353+
* `length` (Number), and `location` (String).
354+
*
355+
* See {@link #truncate} config for details.
356+
*
357+
* @private
358+
* @param {Number/Object} truncate
359+
* @return {Object}
360+
*/
361+
normalizeTruncateCfg : function( truncate ) {
362+
if( typeof truncate === 'number' ) {
363+
return { length: truncate, location: 'end' };
364+
365+
} else { // object, or undefined/null
366+
return Autolinker.Util.defaults( truncate || {}, {
367+
length : Number.POSITIVE_INFINITY,
368+
location : 'end'
369+
} );
370+
}
371+
},
372+
373+
316374
/**
317375
* Automatically links URLs, Email addresses, Phone numbers, Twitter
318376
* handles, and Hashtags found in the given chunk of HTML. Does not link
@@ -589,6 +647,25 @@ Autolinker.Util = {
589647
},
590648

591649

650+
/**
651+
* Assigns (shallow copies) the properties of `src` onto `dest`, if the
652+
* corresponding property on `dest` === `undefined`.
653+
*
654+
* @param {Object} dest The destination object.
655+
* @param {Object} src The source object.
656+
* @return {Object} The destination object (`dest`)
657+
*/
658+
defaults : function( dest, src ) {
659+
for( var prop in src ) {
660+
if( src.hasOwnProperty( prop ) && dest[ prop ] === undefined ) {
661+
dest[ prop ] = src[ prop ];
662+
}
663+
}
664+
665+
return dest;
666+
},
667+
668+
592669
/**
593670
* Extends `superclass` to create a new subclass, adding the `protoProps` to the new subclass's prototype.
594671
*
@@ -1700,7 +1777,7 @@ Autolinker.htmlParser.TextNode = Autolinker.Util.extend( Autolinker.htmlParser.H
17001777
Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
17011778

17021779
/**
1703-
* @cfg {Boolean} urls
1780+
* @cfg {Object} urls
17041781
* @inheritdoc Autolinker#urls
17051782
*/
17061783
urls : true,
@@ -1764,26 +1841,31 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
17641841
* used to match protocol URLs with just a single word, like 'http://localhost',
17651842
* where we won't double check that the domain name has at least one '.'
17661843
* in it.
1767-
* 7. A protocol-relative ('//') match for the case of a 'www.' prefixed
1844+
* 7. Group that matches a 'www.' prefixed URL. This is only matched if the
1845+
* 'www.' text was not prefixed by a scheme (i.e.: not prefixed by
1846+
* 'http://', 'ftp:', etc.)
1847+
* 8. A protocol-relative ('//') match for the case of a 'www.' prefixed
17681848
* URL. Will be an empty string if it is not a protocol-relative match.
17691849
* We need to know the character before the '//' in order to determine
17701850
* if it is a valid match or the // was in a string we don't want to
17711851
* auto-link.
1772-
* 8. A protocol-relative ('//') match for the case of a known TLD prefixed
1852+
* 9. Group that matches a known TLD (top level domain), when a scheme
1853+
* or 'www.'-prefixed domain is not matched.
1854+
* 10. A protocol-relative ('//') match for the case of a known TLD prefixed
17731855
* URL. Will be an empty string if it is not a protocol-relative match.
17741856
* See #6 for more info.
1775-
* 9. Group that is used to determine if there is a phone number match.
1776-
* 10. If there is a phone number match, and a '+' sign was included with
1857+
* 11. Group that is used to determine if there is a phone number match.
1858+
* 12. If there is a phone number match, and a '+' sign was included with
17771859
* the phone number, this group will be populated with the '+' sign.
1778-
* 11. Group that is used to determine if there is a Hashtag match
1860+
* 13. Group that is used to determine if there is a Hashtag match
17791861
* (i.e. \#someHashtag). Simply check for its existence to determine if
17801862
* there is a Hashtag match. The next couple of capturing groups give
17811863
* information about the Hashtag match.
1782-
* 12. The whitespace character before the #sign in a Hashtag handle. This
1864+
* 14. The whitespace character before the #sign in a Hashtag handle. This
17831865
* is needed because there are no look-behinds in JS regular
17841866
* expressions, and can be used to reconstruct the original string in a
17851867
* replace().
1786-
* 13. The Hashtag itself in a Hashtag match. If the match is
1868+
* 15. The Hashtag itself in a Hashtag match. If the match is
17871869
* '#someHashtag', the hashtag is 'someHashtag'.
17881870
*/
17891871
matcherRegex : (function() {
@@ -1821,23 +1903,23 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
18211903

18221904
'(', // *** Capturing group $5, which is used to match a URL
18231905
'(?:', // parens to cover match for protocol (optional), and domain
1824-
'(', // *** Capturing group $6, for a protocol-prefixed url (ex: http://google.com)
1906+
'(', // *** Capturing group $6, for a scheme-prefixed url (ex: http://google.com)
18251907
protocolRegex.source,
18261908
domainNameRegex.source,
18271909
')',
18281910

18291911
'|',
18301912

1831-
'(?:', // non-capturing paren for a 'www.' prefixed url (ex: www.google.com)
1832-
'(.?//)?', // *** Capturing group $7 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character
1913+
'(', // *** Capturing group $7, for a 'www.' prefixed url (ex: www.google.com)
1914+
'(.?//)?', // *** Capturing group $8 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character
18331915
wwwRegex.source,
18341916
domainNameRegex.source,
18351917
')',
18361918

18371919
'|',
18381920

1839-
'(?:', // non-capturing paren for known a TLD url (ex: google.com)
1840-
'(.?//)?', // *** Capturing group $8 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character
1921+
'(', // *** Capturing group $9, for known a TLD url (ex: google.com)
1922+
'(.?//)?', // *** Capturing group $10 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character
18411923
domainNameRegex.source,
18421924
tldRegex.source,
18431925
')',
@@ -1849,16 +1931,17 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
18491931
'|',
18501932

18511933
// this setup does not scale well for open extension :( Need to rethink design of autolinker...
1852-
// *** Capturing group $9, which matches a (USA for now) phone number
1934+
// *** Capturing group $11, which matches a (USA for now) phone number, and
1935+
// *** Capturing group $12, which matches the '+' sign for international numbers, if it exists
18531936
'(',
18541937
phoneRegex.source,
18551938
')',
18561939

18571940
'|',
18581941

1859-
'(', // *** Capturing group $10, which can be used to check for a Hashtag match. Use group $12 for the actual Hashtag though. $11 may be used to reconstruct the original string in a replace()
1860-
// *** Capturing group $11, which matches the whitespace character before the '#' sign (needed because of no lookbehinds), and
1861-
// *** Capturing group $12, which matches the actual Hashtag
1942+
'(', // *** Capturing group $13, which can be used to check for a Hashtag match. Use group $12 for the actual Hashtag though. $11 may be used to reconstruct the original string in a replace()
1943+
// *** Capturing group $14, which matches the whitespace character before the '#' sign (needed because of no lookbehinds), and
1944+
// *** Capturing group $15, which matches the actual Hashtag
18621945
hashtagRegex.source,
18631946
')'
18641947
].join( "" ), 'gi' );
@@ -1915,8 +1998,8 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
19151998
replace : function( text, replaceFn, contextObj ) {
19161999
var me = this; // for closure
19172000

1918-
return text.replace( this.matcherRegex, function( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13 ) {
1919-
var matchDescObj = me.processCandidateMatch( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13 ); // "match description" object
2001+
return text.replace( this.matcherRegex, function( matchStr/*, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15*/ ) {
2002+
var matchDescObj = me.processCandidateMatch.apply( me, arguments ); // "match description" object
19202003

19212004
// Return out with no changes for match types that are disabled (url,
19222005
// email, phone, etc.), or for matches that are invalid (false
@@ -1956,12 +2039,17 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
19562039
* @param {String} emailAddressMatch The matched email address for an email
19572040
* address match.
19582041
* @param {String} urlMatch The matched URL string for a URL match.
1959-
* @param {String} protocolUrlMatch The match URL string for a protocol
2042+
* @param {String} schemeUrlMatch The match URL string for a protocol
19602043
* match. Ex: 'http://yahoo.com'. This is used to match something like
19612044
* 'http://localhost', where we won't double check that the domain name
19622045
* has at least one '.' in it.
2046+
* @param {String} wwwMatch The matched string of a 'www.'-prefixed URL that
2047+
* was matched. This is only matched if the 'www.' text was not prefixed
2048+
* by a scheme (i.e.: not prefixed by 'http://', 'ftp:', etc.).
19632049
* @param {String} wwwProtocolRelativeMatch The '//' for a protocol-relative
19642050
* match from a 'www' url, with the character that comes before the '//'.
2051+
* @param {String} tldMatch The matched string of a known TLD (top level
2052+
* domain), when a scheme or 'www.'-prefixed domain is not matched.
19652053
* @param {String} tldProtocolRelativeMatch The '//' for a protocol-relative
19662054
* match from a TLD (top level domain) match, with the character that
19672055
* comes before the '//'.
@@ -1993,8 +2081,8 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
19932081
*/
19942082
processCandidateMatch : function(
19952083
matchStr, twitterMatch, twitterHandlePrefixWhitespaceChar, twitterHandle,
1996-
emailAddressMatch, urlMatch, protocolUrlMatch, wwwProtocolRelativeMatch,
1997-
tldProtocolRelativeMatch, phoneMatch, phonePlusSignMatch, hashtagMatch,
2084+
emailAddressMatch, urlMatch, schemeUrlMatch, wwwMatch, wwwProtocolRelativeMatch,
2085+
tldMatch, tldProtocolRelativeMatch, phoneMatch, phonePlusSignMatch, hashtagMatch,
19982086
hashtagPrefixWhitespaceChar, hashtag
19992087
) {
20002088
// Note: The `matchStr` variable wil be fixed up to remove characters that are no longer needed (which will
@@ -2004,19 +2092,23 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
20042092
match, // Will be an Autolinker.match.Match object
20052093

20062094
prefixStr = "", // A string to use to prefix the anchor tag that is created. This is needed for the Twitter and Hashtag matches.
2007-
suffixStr = ""; // A string to suffix the anchor tag that is created. This is used if there is a trailing parenthesis that should not be auto-linked.
2095+
suffixStr = "", // A string to suffix the anchor tag that is created. This is used if there is a trailing parenthesis that should not be auto-linked.
2096+
2097+
urls = this.urls; // the 'urls' config
20082098

20092099
// Return out with `null` for match types that are disabled (url, email,
20102100
// twitter, hashtag), or for matches that are invalid (false positives
20112101
// from the matcherRegex, which can't use look-behinds since they are
20122102
// unavailable in JS).
20132103
if(
2014-
( urlMatch && !this.urls ) ||
2104+
( schemeUrlMatch && !urls.schemeMatches ) ||
2105+
( wwwMatch && !urls.wwwMatches ) ||
2106+
( tldMatch && !urls.tldMatches ) ||
20152107
( emailAddressMatch && !this.email ) ||
20162108
( phoneMatch && !this.phone ) ||
20172109
( twitterMatch && !this.twitter ) ||
20182110
( hashtagMatch && !this.hashtag ) ||
2019-
!this.matchValidator.isValidMatch( urlMatch, protocolUrlMatch, protocolRelativeMatch )
2111+
!this.matchValidator.isValidMatch( urlMatch, schemeUrlMatch, protocolRelativeMatch )
20202112
) {
20212113
return null;
20222114
}
@@ -2029,7 +2121,7 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
20292121
suffixStr = ")"; // this will be added after the generated <a> tag
20302122
} else {
20312123
// Handle an invalid character after the TLD
2032-
var pos = this.matchHasInvalidCharAfterTld( urlMatch, protocolUrlMatch );
2124+
var pos = this.matchHasInvalidCharAfterTld( urlMatch, schemeUrlMatch );
20332125
if( pos > -1 ) {
20342126
suffixStr = matchStr.substr(pos); // this will be added after the generated <a> tag
20352127
matchStr = matchStr.substr( 0, pos ); // remove the trailing invalid chars
@@ -2081,7 +2173,7 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
20812173
match = new Autolinker.match.Url( {
20822174
matchedText : matchStr,
20832175
url : matchStr,
2084-
protocolUrlMatch : !!protocolUrlMatch,
2176+
protocolUrlMatch : !!schemeUrlMatch,
20852177
protocolRelativeMatch : !!protocolRelativeMatch,
20862178
stripPrefix : this.stripPrefix
20872179
} );

0 commit comments

Comments
 (0)