16
16
17
17
/*!
18
18
* Autolinker.js
19
- * 0.20 .0
19
+ * 0.21 .0
20
20
*
21
21
* Copyright(c) 2015 Gregory Jacobs <[email protected] >
22
22
* MIT
@@ -1772,17 +1772,18 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
1772
1772
* 8. A protocol-relative ('//') match for the case of a known TLD prefixed
1773
1773
* URL. Will be an empty string if it is not a protocol-relative match.
1774
1774
* See #6 for more info.
1775
- * 9. Group that is used to determine if there is a phone number match. The
1776
- * next 3 groups give segments of the phone number.
1777
- * 10. Group that is used to determine if there is a Hashtag match
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
1777
+ * 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
1778
1779
* (i.e. \#someHashtag). Simply check for its existence to determine if
1779
1780
* there is a Hashtag match. The next couple of capturing groups give
1780
1781
* information about the Hashtag match.
1781
- * 11 . The whitespace character before the #sign in a Hashtag handle. This
1782
+ * 12 . The whitespace character before the #sign in a Hashtag handle. This
1782
1783
* is needed because there are no look-behinds in JS regular
1783
1784
* expressions, and can be used to reconstruct the original string in a
1784
1785
* replace().
1785
- * 12 . The Hashtag itself in a Hashtag match. If the match is
1786
+ * 13 . The Hashtag itself in a Hashtag match. If the match is
1786
1787
* '#someHashtag', the hashtag is 'someHashtag'.
1787
1788
*/
1788
1789
matcherRegex : ( function ( ) {
@@ -1791,7 +1792,7 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
1791
1792
hashtagRegex = / ( ^ | [ ^ \w ] ) # ( \w { 1 , 139 } ) / , // For matching a Hashtag. Ex: #games
1792
1793
1793
1794
emailRegex = / (?: [ \- ; : & = \+ \$ , \w \. ] + @ ) / , // something@ for email addresses (a.k.a. local-part)
1794
- phoneRegex = / (?: \+ ? \d { 1 , 3 } [ - \0 4 0 . ] ) ? \( ? \d { 3 } \) ? [ - \0 4 0 . ] ? \d { 3 } [ - \0 4 0 . ] \d { 4 } / , // ex: (123) 456-7890, 123 456 7890, 123-456-7890, etc.
1795
+ phoneRegex = / (?: ( \+ ) ? \d { 1 , 3 } [ - \0 4 0 . ] ) ? \( ? \d { 3 } \) ? [ - \0 4 0 . ] ? \d { 3 } [ - \0 4 0 . ] \d { 4 } / , // ex: (123) 456-7890, 123 456 7890, 123-456-7890, etc.
1795
1796
protocolRegex = / (?: [ A - Z a - z ] [ - . + A - Z a - z 0 - 9 ] * : (? ! [ A - Z a - z ] [ - . + A - Z a - z 0 - 9 ] * : \/ \/ ) (? ! \d + \/ ? ) (?: \/ \/ ) ? ) / , // match protocol, allow in format "http://" or "mailto:". However, do not match the first part of something like 'link:http://www.google.com' (i.e. don't match "link:"). Also, make sure we don't interpret 'google.com:8000' as if 'google.com' was a protocol here (i.e. ignore a trailing port number in this regex)
1796
1797
wwwRegex = / (?: w w w \. ) / , // starting with 'www.'
1797
1798
domainNameRegex = / [ A - Z a - z 0 - 9 \. \- ] * [ A - Z a - z 0 - 9 \- ] / , // anything looking at all like a domain, non-unicode domains, not ending in a period
@@ -1914,8 +1915,8 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
1914
1915
replace : function ( text , replaceFn , contextObj ) {
1915
1916
var me = this ; // for closure
1916
1917
1917
- return text . replace ( this . matcherRegex , function ( matchStr , $1 , $2 , $3 , $4 , $5 , $6 , $7 , $8 , $9 , $10 , $11 , $12 ) {
1918
- var matchDescObj = me . processCandidateMatch ( matchStr , $1 , $2 , $3 , $4 , $5 , $6 , $7 , $8 , $9 , $10 , $11 , $12 ) ; // "match description" object
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
1919
1920
1920
1921
// Return out with no changes for match types that are disabled (url,
1921
1922
// email, phone, etc.), or for matches that are invalid (false
@@ -1965,6 +1966,8 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
1965
1966
* match from a TLD (top level domain) match, with the character that
1966
1967
* comes before the '//'.
1967
1968
* @param {String } phoneMatch The matched text of a phone number
1969
+ * @param {String } phonePlusSignMatch The '+' sign in the phone number, if
1970
+ * it was there.
1968
1971
* @param {String } hashtagMatch The matched text of a Twitter
1969
1972
* Hashtag, if the match is a Hashtag match.
1970
1973
* @param {String } hashtagPrefixWhitespaceChar The whitespace char
@@ -1991,7 +1994,7 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
1991
1994
processCandidateMatch : function (
1992
1995
matchStr , twitterMatch , twitterHandlePrefixWhitespaceChar , twitterHandle ,
1993
1996
emailAddressMatch , urlMatch , protocolUrlMatch , wwwProtocolRelativeMatch ,
1994
- tldProtocolRelativeMatch , phoneMatch , hashtagMatch ,
1997
+ tldProtocolRelativeMatch , phoneMatch , phonePlusSignMatch , hashtagMatch ,
1995
1998
hashtagPrefixWhitespaceChar , hashtag
1996
1999
) {
1997
2000
// Note: The `matchStr` variable wil be fixed up to remove characters that are no longer needed (which will
@@ -2049,7 +2052,7 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
2049
2052
} else if ( phoneMatch ) {
2050
2053
// remove non-numeric values from phone number string
2051
2054
var cleanNumber = matchStr . replace ( / \D / g, '' ) ;
2052
- match = new Autolinker . match . Phone ( { matchedText : matchStr , number : cleanNumber } ) ;
2055
+ match = new Autolinker . match . Phone ( { matchedText : matchStr , number : cleanNumber , plusSign : ! ! phonePlusSignMatch } ) ;
2053
2056
2054
2057
} else if ( hashtagMatch ) {
2055
2058
// fix up the `matchStr` if there was a preceding whitespace char,
@@ -2611,6 +2614,15 @@ Autolinker.match.Phone = Autolinker.Util.extend( Autolinker.match.Match, {
2611
2614
* The phone number that was matched.
2612
2615
*/
2613
2616
2617
+ /**
2618
+ * @cfg {Boolean} plusSign (required)
2619
+ *
2620
+ * `true` if the matched phone number started with a '+' sign. We'll include
2621
+ * it in the `tel:` URL if so, as this is needed for international numbers.
2622
+ *
2623
+ * Ex: '+1 (123) 456 7879'
2624
+ */
2625
+
2614
2626
2615
2627
/**
2616
2628
* Returns a string name for the type of match that this class represents.
@@ -2638,7 +2650,7 @@ Autolinker.match.Phone = Autolinker.Util.extend( Autolinker.match.Match, {
2638
2650
* @return {String }
2639
2651
*/
2640
2652
getAnchorHref : function ( ) {
2641
- return 'tel:' + this . number ;
2653
+ return 'tel:' + ( this . plusSign ? '+' : '' ) + this . number ;
2642
2654
} ,
2643
2655
2644
2656
@@ -2715,116 +2727,116 @@ Autolinker.match.Twitter = Autolinker.Util.extend( Autolinker.match.Match, {
2715
2727
/**
2716
2728
* @class Autolinker.match.Url
2717
2729
* @extends Autolinker.match.Match
2718
- *
2730
+ *
2719
2731
* Represents a Url match found in an input string which should be Autolinked.
2720
- *
2732
+ *
2721
2733
* See this class's superclass ({@link Autolinker.match.Match}) for more details.
2722
2734
*/
2723
2735
Autolinker . match . Url = Autolinker . Util . extend ( Autolinker . match . Match , {
2724
-
2736
+
2725
2737
/**
2726
2738
* @cfg {String} url (required)
2727
- *
2739
+ *
2728
2740
* The url that was matched.
2729
2741
*/
2730
-
2742
+
2731
2743
/**
2732
2744
* @cfg {Boolean} protocolUrlMatch (required)
2733
- *
2745
+ *
2734
2746
* `true` if the URL is a match which already has a protocol (i.e. 'http://'), `false` if the match was from a 'www' or
2735
2747
* known TLD match.
2736
2748
*/
2737
-
2749
+
2738
2750
/**
2739
2751
* @cfg {Boolean} protocolRelativeMatch (required)
2740
- *
2752
+ *
2741
2753
* `true` if the URL is a protocol-relative match. A protocol-relative match is a URL that starts with '//',
2742
2754
* and will be either http:// or https:// based on the protocol that the site is loaded under.
2743
2755
*/
2744
-
2756
+
2745
2757
/**
2746
2758
* @cfg {Boolean} stripPrefix (required)
2747
2759
* @inheritdoc Autolinker#stripPrefix
2748
2760
*/
2749
-
2761
+
2750
2762
2751
2763
/**
2752
2764
* @private
2753
2765
* @property {RegExp } urlPrefixRegex
2754
- *
2766
+ *
2755
2767
* A regular expression used to remove the 'http://' or 'https://' and/or the 'www.' from URLs.
2756
2768
*/
2757
2769
urlPrefixRegex : / ^ ( h t t p s ? : \/ \/ ) ? ( w w w \. ) ? / i,
2758
-
2770
+
2759
2771
/**
2760
2772
* @private
2761
2773
* @property {RegExp } protocolRelativeRegex
2762
- *
2774
+ *
2763
2775
* The regular expression used to remove the protocol-relative '//' from the {@link #url} string, for purposes
2764
2776
* of {@link #getAnchorText}. A protocol-relative URL is, for example, "//yahoo.com"
2765
2777
*/
2766
2778
protocolRelativeRegex : / ^ \/ \/ / ,
2767
-
2779
+
2768
2780
/**
2769
2781
* @private
2770
2782
* @property {Boolean } protocolPrepended
2771
- *
2783
+ *
2772
2784
* Will be set to `true` if the 'http://' protocol has been prepended to the {@link #url} (because the
2773
2785
* {@link #url} did not have a protocol)
2774
2786
*/
2775
2787
protocolPrepended : false ,
2776
-
2788
+
2777
2789
2778
2790
/**
2779
2791
* Returns a string name for the type of match that this class represents.
2780
- *
2792
+ *
2781
2793
* @return {String }
2782
2794
*/
2783
2795
getType : function ( ) {
2784
2796
return 'url' ;
2785
2797
} ,
2786
-
2787
-
2798
+
2799
+
2788
2800
/**
2789
2801
* Returns the url that was matched, assuming the protocol to be 'http://' if the original
2790
2802
* match was missing a protocol.
2791
- *
2803
+ *
2792
2804
* @return {String }
2793
2805
*/
2794
2806
getUrl : function ( ) {
2795
2807
var url = this . url ;
2796
-
2808
+
2797
2809
// if the url string doesn't begin with a protocol, assume 'http://'
2798
2810
if ( ! this . protocolRelativeMatch && ! this . protocolUrlMatch && ! this . protocolPrepended ) {
2799
2811
url = this . url = 'http://' + url ;
2800
-
2812
+
2801
2813
this . protocolPrepended = true ;
2802
2814
}
2803
-
2815
+
2804
2816
return url ;
2805
2817
} ,
2806
-
2818
+
2807
2819
2808
2820
/**
2809
2821
* Returns the anchor href that should be generated for the match.
2810
- *
2822
+ *
2811
2823
* @return {String }
2812
2824
*/
2813
2825
getAnchorHref : function ( ) {
2814
2826
var url = this . getUrl ( ) ;
2815
-
2816
- return url . replace ( / & a m p ; / g, '&' ) ; // any &'s in the URL should be converted back to '&' if they were displayed as & in the source html
2827
+
2828
+ return url . replace ( / & a m p ; / g, '&' ) ; // any &'s in the URL should be converted back to '&' if they were displayed as & in the source html
2817
2829
} ,
2818
-
2819
-
2830
+
2831
+
2820
2832
/**
2821
2833
* Returns the anchor text that should be generated for the match.
2822
- *
2834
+ *
2823
2835
* @return {String }
2824
2836
*/
2825
2837
getAnchorText : function ( ) {
2826
- var anchorText = this . getUrl ( ) ;
2827
-
2838
+ var anchorText = this . getMatchedText ( ) ;
2839
+
2828
2840
if ( this . protocolRelativeMatch ) {
2829
2841
// Strip off any protocol-relative '//' from the anchor text
2830
2842
anchorText = this . stripProtocolRelativePrefix ( anchorText ) ;
@@ -2833,18 +2845,18 @@ Autolinker.match.Url = Autolinker.Util.extend( Autolinker.match.Match, {
2833
2845
anchorText = this . stripUrlPrefix ( anchorText ) ;
2834
2846
}
2835
2847
anchorText = this . removeTrailingSlash ( anchorText ) ; // remove trailing slash, if there is one
2836
-
2848
+
2837
2849
return anchorText ;
2838
2850
} ,
2839
-
2840
-
2851
+
2852
+
2841
2853
// ---------------------------------------
2842
-
2854
+
2843
2855
// Utility Functionality
2844
-
2856
+
2845
2857
/**
2846
2858
* Strips the URL prefix (such as "http://" or "https://") from the given text.
2847
- *
2859
+ *
2848
2860
* @private
2849
2861
* @param {String } text The text of the anchor that is being generated, for which to strip off the
2850
2862
* url prefix (such as stripping off "http://")
@@ -2853,11 +2865,11 @@ Autolinker.match.Url = Autolinker.Util.extend( Autolinker.match.Match, {
2853
2865
stripUrlPrefix : function ( text ) {
2854
2866
return text . replace ( this . urlPrefixRegex , '' ) ;
2855
2867
} ,
2856
-
2857
-
2868
+
2869
+
2858
2870
/**
2859
2871
* Strips any protocol-relative '//' from the anchor text.
2860
- *
2872
+ *
2861
2873
* @private
2862
2874
* @param {String } text The text of the anchor that is being generated, for which to strip off the
2863
2875
* protocol-relative prefix (such as stripping off "//")
@@ -2866,11 +2878,11 @@ Autolinker.match.Url = Autolinker.Util.extend( Autolinker.match.Match, {
2866
2878
stripProtocolRelativePrefix : function ( text ) {
2867
2879
return text . replace ( this . protocolRelativeRegex , '' ) ;
2868
2880
} ,
2869
-
2870
-
2881
+
2882
+
2871
2883
/**
2872
2884
* Removes any trailing slash from the given `anchorText`, in preparation for the text to be displayed.
2873
- *
2885
+ *
2874
2886
* @private
2875
2887
* @param {String } anchorText The text of the anchor that is being generated, for which to remove any trailing
2876
2888
* slash ('/') that may exist.
@@ -2882,7 +2894,7 @@ Autolinker.match.Url = Autolinker.Util.extend( Autolinker.match.Match, {
2882
2894
}
2883
2895
return anchorText ;
2884
2896
}
2885
-
2897
+
2886
2898
} ) ;
2887
2899
/*global Autolinker */
2888
2900
/**
0 commit comments