Skip to content

Commit ed3a007

Browse files
committed
Experimenting with preprocess config function
Now all candidate text for linkifying is first passed to a preprocess function to enable arbitrary extension while piggy-backing on the nice href detection.
1 parent 248f733 commit ed3a007

File tree

5 files changed

+66
-11
lines changed

5 files changed

+66
-11
lines changed

dist/Autolinker.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@
119119
};
120120

121121

122+
var defaultSecondPassFn = function( context, str ) {
123+
return str;
124+
};
125+
122126
Autolinker.prototype = {
123127
constructor : Autolinker, // fix constructor property
124128

@@ -209,6 +213,20 @@
209213
*/
210214

211215

216+
/**
217+
* @cfg {Function} secondPassReplaceFn
218+
*
219+
* A function which gets called for any string where no built-in matches are found in the input.
220+
* Defaults to the identity function.
221+
* This function is called with the following parameters:
222+
*
223+
* @cfg {Autolinker} secondPassReplaceFn.autolinker The Autolinker instance
224+
* @cfg {String} secondPassReplaceFn.str The text to be replaced
225+
*
226+
*
227+
*/
228+
secondPassReplaceFn: defaultSecondPassFn,
229+
212230
/**
213231
* @private
214232
* @property {Autolinker.htmlParser.HtmlParser} htmlParser
@@ -236,7 +254,6 @@
236254
*/
237255
tagBuilder : undefined,
238256

239-
240257
/**
241258
* Automatically links URLs, email addresses, phone numbers, and Twitter handles found in the given chunk of HTML.
242259
* Does not link URLs found within HTML tags.
@@ -294,7 +311,6 @@
294311
return resultHtml.join( "" );
295312
},
296313

297-
298314
/**
299315
* Process the text that lies in between HTML tags, performing the anchor tag replacements for matched
300316
* URLs/emails/phone#s/Twitter handles, and returns the string with the replacements made.
@@ -306,7 +322,7 @@
306322
* @return {String} The text with anchor tags auto-filled.
307323
*/
308324
linkifyStr : function( str ) {
309-
return this.getMatchParser().replace( str, this.createMatchReturnVal, this );
325+
return this.getMatchParser().replace( str, this.createMatchReturnVal, this.secondPassReplaceFn, this );
310326
},
311327

312328

@@ -1647,10 +1663,11 @@
16471663
* @param {Object} [contextObj=window] The context object ("scope") to run the `replaceFn` in.
16481664
* @return {String}
16491665
*/
1650-
replace : function( text, replaceFn, contextObj ) {
1666+
replace : function( text, replaceFn, secondPassReplaceFn, contextObj ) {
16511667
var me = this; // for closure
1668+
var didFindMatch = false;
16521669

1653-
return text.replace( this.matcherRegex, function( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9) {
1670+
var initialResult = text.replace( this.matcherRegex, function( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9) {
16541671
var matchDescObj = me.processCandidateMatch( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9); // "match description" object
16551672

16561673
// Return out with no changes for match types that are disabled (url, email, twitter), or for matches that are
@@ -1660,10 +1677,17 @@
16601677

16611678
} else {
16621679
// Generate replacement text for the match from the `replaceFn`
1680+
didFindMatch = true;
16631681
var replaceStr = replaceFn.call( contextObj, matchDescObj.match );
16641682
return matchDescObj.prefixStr + replaceStr + matchDescObj.suffixStr;
16651683
}
16661684
} );
1685+
1686+
if (!didFindMatch) {
1687+
return secondPassReplaceFn.call( contextObj, initialResult );
1688+
} else {
1689+
return initialResult;
1690+
}
16671691
},
16681692

16691693

dist/Autolinker.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Autolinker.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ var Autolinker = function( cfg ) {
9494
};
9595

9696

97+
var defaultPreprocessFn = function( autolinker, str ) {
98+
return str;
99+
};
100+
97101
Autolinker.prototype = {
98102
constructor : Autolinker, // fix constructor property
99103

@@ -184,6 +188,20 @@ Autolinker.prototype = {
184188
*/
185189

186190

191+
/**
192+
* @cfg {Function} preprocessFn
193+
*
194+
* A function which gets called to preprocess input strings before performing the built-in autolinker replacement operations.
195+
* Defaults to the identity function.
196+
* This function is called with the following parameters:
197+
*
198+
* @cfg {Autolinker} preprocessFn.autolinker The Autolinker instance
199+
* @cfg {String} preoprocessFn.str The text to be replaced
200+
*
201+
*
202+
*/
203+
preprocessFn: defaultPreprocessFn,
204+
187205
/**
188206
* @private
189207
* @property {Autolinker.htmlParser.HtmlParser} htmlParser
@@ -211,7 +229,6 @@ Autolinker.prototype = {
211229
*/
212230
tagBuilder : undefined,
213231

214-
215232
/**
216233
* Automatically links URLs, email addresses, phone numbers, and Twitter handles found in the given chunk of HTML.
217234
* Does not link URLs found within HTML tags.
@@ -269,7 +286,6 @@ Autolinker.prototype = {
269286
return resultHtml.join( "" );
270287
},
271288

272-
273289
/**
274290
* Process the text that lies in between HTML tags, performing the anchor tag replacements for matched
275291
* URLs/emails/phone#s/Twitter handles, and returns the string with the replacements made.
@@ -281,7 +297,9 @@ Autolinker.prototype = {
281297
* @return {String} The text with anchor tags auto-filled.
282298
*/
283299
linkifyStr : function( str ) {
284-
return this.getMatchParser().replace( str, this.createMatchReturnVal, this );
300+
// preprocess string, then pas into match parser.
301+
var initialResult = this.preprocessFn( this, str );
302+
return this.getMatchParser().replace( initialResult, this.createMatchReturnVal, this );
285303
},
286304

287305

src/matchParser/MatchParser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, {
204204
// invalid (false positives from the matcherRegex, which can't use look-behinds since they are unavailable in JS).
205205
if( !matchDescObj ) {
206206
return matchStr;
207-
208207
} else {
209208
// Generate replacement text for the match from the `replaceFn`
209+
didFindMatch = true;
210210
var replaceStr = replaceFn.call( contextObj, matchDescObj.match );
211211
return matchDescObj.prefixStr + replaceStr + matchDescObj.suffixStr;
212212
}

tests/AutolinkerSpec.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
/*global Autolinker, _, describe, beforeEach, afterEach, it, expect */
22
describe( "Autolinker", function() {
33

4+
describe( "preprocess function", function() {
5+
it( "should capitalize string, then linkify", function() {
6+
var capitalizer = function( autolinker, str ){
7+
return str.toUpperCase();
8+
}
9+
10+
var autolinker = new Autolinker( { newWindow: false, preprocessFn: capitalizer});
11+
12+
var result = autolinker.link( "Hi, my number is: 919-789-1622" );
13+
expect( result ).toBe('HI, MY NUMBER IS: <a href="tel:9197891622">919-789-1622</a>');
14+
});
15+
16+
});
17+
418
describe( "instantiating and using as a class", function() {
519

620
it( "should configure the instance with configuration options, and then be able to execute the link() method", function() {
@@ -12,7 +26,6 @@ describe( "Autolinker", function() {
1226

1327
} );
1428

15-
1629
describe( "link() method", function() {
1730
var autolinker;
1831

0 commit comments

Comments
 (0)