@@ -324,7 +324,8 @@ Autolinker.prototype = {
324324 * This method finds the text around any HTML elements in the input `textOrHtml`, which will be the text that is processed.
325325 * Any original HTML elements will be left as-is, as well as the text that is already wrapped in anchor (<a>) tags.
326326 *
327- * @param {String } textOrHtml The HTML or text to link URLs, email addresses, and Twitter handles within.
327+ * @param {String } textOrHtml The HTML or text to link URLs, email addresses, and Twitter handles within (depending on if
328+ * the {@link #urls}, {@link #email}, and {@link #twitter} options are enabled).
328329 * @return {String } The HTML, with URLs/emails/Twitter handles automatically linked.
329330 */
330331 link : function ( textOrHtml ) {
@@ -434,76 +435,124 @@ Autolinker.prototype = {
434435 * @return {String } The text with anchor tags auto-filled.
435436 */
436437 processTextNode : function ( text ) {
437- var me = this , // for closure
438- charBeforeProtocolRelMatchRegex = this . charBeforeProtocolRelMatchRegex ;
438+ var me = this ; // for closure
439439
440440 return text . replace ( this . matcherRegex , function ( matchStr , $1 , $2 , $3 , $4 , $5 , $6 , $7 ) {
441- var twitterMatch = $1 ,
442- twitterHandlePrefixWhitespaceChar = $2 , // The whitespace char before the @ sign in a Twitter handle match. This is needed because of no lookbehinds in JS regexes.
443- twitterHandle = $3 , // The actual twitterUser (i.e the word after the @ sign in a Twitter handle match)
444- emailAddressMatch = $4 , // For both determining if it is an email address, and stores the actual email address
445- urlMatch = $5 , // The matched URL string
446- protocolRelativeMatch = $6 || $7 , // The '//' for a protocol-relative match, with the character that comes before the '//'
447-
448- prefixStr = "" , // A string to use to prefix the anchor tag that is created. This is needed for the Twitter handle match
449- 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.
450-
451- match ; // Will be an Autolinker.match.Match object
452-
441+ var matchDescObj = me . processCandidateMatch . apply ( me , arguments ) ; // match description object
453442
454443 // Return out with no changes for match types that are disabled (url, email, twitter), or for matches that are
455444 // invalid (false positives from the matcherRegex, which can't use look-behinds since they are unavailable in JS).
456- if ( ! me . isValidMatch ( twitterMatch , emailAddressMatch , urlMatch , protocolRelativeMatch ) ) {
445+ if ( ! matchDescObj ) {
457446 return matchStr ;
447+
448+ } else {
449+ // Generate the replacement text for the match
450+ var matchReturnVal = me . createMatchReturnVal ( matchDescObj . match , matchDescObj . matchStr ) ;
451+ return matchDescObj . prefixStr + matchReturnVal + matchDescObj . suffixStr ;
458452 }
453+ } ) ;
454+ } ,
455+
456+
457+ /**
458+ * Processes a candidate match from the {@link #matcherRegex}.
459+ *
460+ * Not all matches found by the regex are actual URL/email/Twitter matches, as determined by {@link #isValidMatch}. In
461+ * this case, the method returns `null`. Otherwise, a valid Object with `prefixStr`, `match`, and `suffixStr` is returned.
462+ *
463+ * @private
464+ * @param {String } matchStr The full match that was found by the {@link #matcherRegex}.
465+ * @param {String } twitterMatch The matched text of a Twitter handle, if the match is a Twitter match.
466+ * @param {String } twitterHandlePrefixWhitespaceChar The whitespace char before the @ sign in a Twitter handle match. This
467+ * is needed because of no lookbehinds in JS regexes, and is need to re-include the character for the anchor tag replacement.
468+ * @param {String } twitterHandle The actual Twitter user (i.e the word after the @ sign in a Twitter match).
469+ * @param {String } emailAddressMatch The matched email address for an email address match.
470+ * @param {String } urlMatch The matched URL string for a URL match.
471+ * @param {String } wwwProtocolRelativeMatch The '//' for a protocol-relative match from a 'www' url, with the character that
472+ * comes before the '//'.
473+ * @param {String } tldProtocolRelativeMatch The '//' for a protocol-relative match from a TLD (top level domain) match, with
474+ * the character that comes before the '//'.
475+ *
476+ * @return {Object } A "match description object". This will be `null` if the match was invalid, or if a match type is disabled.
477+ * Otherwise, this will be an Object (map) with the following properties:
478+ * @return {String } return.prefixStr The char(s) that should be prepended to the replacement string. These are char(s) that
479+ * were needed to be included from the regex match that were ignored by processing code, and should be re-inserted into
480+ * the replacement stream.
481+ * @return {String } return.suffixStr The char(s) that should be appended to the replacement string. These are char(s) that
482+ * were needed to be included from the regex match that were ignored by processing code, and should be re-inserted into
483+ * the replacement stream.
484+ * @return {String } return.matchStr The `matchStr`, fixed up to remove characters that are no longer needed (which have been
485+ * added to `prefixStr` and `suffixStr`).
486+ * @return {Autolinker.match.Match } return.match The Match object that represents the match that was found.
487+ */
488+ processCandidateMatch : function (
489+ matchStr , twitterMatch , twitterHandlePrefixWhitespaceChar , twitterHandle ,
490+ emailAddressMatch , urlMatch , wwwProtocolRelativeMatch , tldProtocolRelativeMatch
491+ ) {
492+ var protocolRelativeMatch = wwwProtocolRelativeMatch || tldProtocolRelativeMatch ,
493+ match , // Will be an Autolinker.match.Match object
494+
495+ prefixStr = "" , // A string to use to prefix the anchor tag that is created. This is needed for the Twitter handle match
496+ 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.
497+
498+
499+ // Return out with `null` for match types that are disabled (url, email, twitter), or for matches that are
500+ // invalid (false positives from the matcherRegex, which can't use look-behinds since they are unavailable in JS).
501+ if ( ! this . isValidMatch ( twitterMatch , emailAddressMatch , urlMatch , protocolRelativeMatch ) ) {
502+ return null ;
503+ }
504+
505+ // Handle a closing parenthesis at the end of the match, and exclude it if there is not a matching open parenthesis
506+ // in the match itself.
507+ if ( this . matchHasUnbalancedClosingParen ( matchStr ) ) {
508+ matchStr = matchStr . substr ( 0 , matchStr . length - 1 ) ; // remove the trailing ")"
509+ suffixStr = ")" ; // this will be added after the generated <a> tag
510+ }
511+
512+
513+ if ( emailAddressMatch ) {
514+ match = new Autolinker . match . Email ( { matchedText : matchStr , email : emailAddressMatch } ) ;
459515
460- // Handle a closing parenthesis at the end of the match, and exclude it if there is not a matching open parenthesis
461- // in the match itself.
462- if ( me . matchHasUnbalancedClosingParen ( matchStr ) ) {
463- matchStr = matchStr . substr ( 0 , matchStr . length - 1 ) ; // remove the trailing ")"
464- suffixStr = ")" ; // this will be added after the generated <a> tag
516+ } else if ( twitterMatch ) {
517+ // fix up the `matchStr` if there was a preceding whitespace char, which was needed to determine the match
518+ // itself (since there are no look-behinds in JS regexes)
519+ if ( twitterHandlePrefixWhitespaceChar ) {
520+ prefixStr = twitterHandlePrefixWhitespaceChar ;
521+ matchStr = matchStr . slice ( 1 ) ; // remove the prefixed whitespace char from the match
465522 }
523+ match = new Autolinker . match . Twitter ( { matchedText : matchStr , twitterHandle : twitterHandle } ) ;
466524
467-
468- if ( emailAddressMatch ) {
469- match = new Autolinker . match . Email ( { matchedText : matchStr , email : emailAddressMatch } ) ;
525+ } else { // url match
526+ // If it's a protocol-relative '//' match, remove the character before the '//' (which the matcherRegex needed
527+ // to match due to the lack of a negative look-behind in JavaScript regular expressions)
528+ if ( protocolRelativeMatch ) {
529+ var charBeforeMatch = protocolRelativeMatch . match ( this . charBeforeProtocolRelMatchRegex ) [ 1 ] || "" ;
470530
471- } else if ( twitterMatch ) {
472- // fix up the `matchStr` if there was a preceding whitespace char, which was needed to determine the match
473- // itself (since there are no look-behinds in JS regexes)
474- if ( twitterHandlePrefixWhitespaceChar ) {
475- prefixStr = twitterHandlePrefixWhitespaceChar ;
476- matchStr = matchStr . slice ( 1 ) ; // remove the prefixed whitespace char from the match
531+ if ( charBeforeMatch ) { // fix up the `matchStr` if there was a preceding char before a protocol-relative match, which was needed to determine the match itself (since there are no look-behinds in JS regexes)
532+ prefixStr = charBeforeMatch ;
533+ matchStr = matchStr . slice ( 1 ) ; // remove the prefixed char from the match
477534 }
478- match = new Autolinker . match . Twitter ( { matchedText : matchStr , twitterHandle : twitterHandle } ) ;
479-
480- } else { // url match
481- // If it's a protocol-relative '//' match, remove the character before the '//' (which the matcherRegex needed
482- // to match due to the lack of a negative look-behind in JavaScript regular expressions)
483- if ( protocolRelativeMatch ) {
484- var charBeforeMatch = protocolRelativeMatch . match ( charBeforeProtocolRelMatchRegex ) [ 1 ] || "" ;
485-
486- if ( charBeforeMatch ) { // fix up the `matchStr` if there was a preceding char before a protocol-relative match, which was needed to determine the match itself (since there are no look-behinds in JS regexes)
487- prefixStr = charBeforeMatch ;
488- matchStr = matchStr . slice ( 1 ) ; // remove the prefixed char from the match
489- }
490- }
491-
492- match = new Autolinker . match . Url ( {
493- matchedText : matchStr ,
494- url : matchStr ,
495- protocolRelativeMatch : protocolRelativeMatch ,
496- stripPrefix : me . stripPrefix
497- } ) ;
498535 }
499-
500- // Generate the replacement text for the match
501- var matchReturnVal = me . createMatchReturnVal ( match , matchStr ) ;
502- return prefixStr + matchReturnVal + suffixStr ;
503- } ) ;
536+
537+ match = new Autolinker . match . Url ( {
538+ matchedText : matchStr ,
539+ url : matchStr ,
540+ protocolRelativeMatch : protocolRelativeMatch ,
541+ stripPrefix : this . stripPrefix
542+ } ) ;
543+ }
544+
545+ return {
546+ prefixStr : prefixStr ,
547+ suffixStr : suffixStr ,
548+ matchStr : matchStr ,
549+ match : match
550+ } ;
504551 } ,
505552
506553
554+
555+
507556 /**
508557 * Determines if a given match found by {@link #processTextNode} is valid. Will return `false` for:
509558 *
@@ -627,15 +676,15 @@ Autolinker.prototype = {
627676 * // Produces: "Go to <a href="http://google.com">google.com</a>"
628677 *
629678 * @static
630- * @method link
631- * @param { String } html The HTML text to link URLs within .
679+ * @param { String } textOrHtml The HTML or text to find URLs, email addresses, and Twitter handles within (depending on if
680+ * the { @link #urls}, { @link #email}, and { @link #twitter} options are enabled) .
632681 * @param {Object } [options] Any of the configuration options for the Autolinker class, specified in an Object (map).
633682 * See the class description for an example call.
634683 * @return {String } The HTML text, with URLs automatically linked
635684 */
636- Autolinker . link = function ( text , options ) {
685+ Autolinker . link = function ( textOrHtml , options ) {
637686 var autolinker = new Autolinker ( options ) ;
638- return autolinker . link ( text ) ;
687+ return autolinker . link ( textOrHtml ) ;
639688} ;
640689
641690
0 commit comments