diff --git a/src/Linkify.jsx b/src/Linkify.jsx
index 4142e12..ac77e59 100644
--- a/src/Linkify.jsx
+++ b/src/Linkify.jsx
@@ -2,8 +2,42 @@ import React from 'react';
import LinkifyIt from 'linkify-it';
import tlds from 'tlds';
-export const linkify = new LinkifyIt();
-linkify.tlds(tlds);
+// const globalLinkify = new LinkifyIt();
+// globalLinkify.tlds(tlds);
+
+const globalCustomizations = {
+ add: [],
+ tlds: [],
+ set: []
+};
+
+export const config = {
+ add: (...args) => {
+ globalCustomizations.add.push(args);
+ // globalLinkify.add(...args);
+
+ return config;
+ },
+ tlds: (...args) => {
+ globalCustomizations.tlds.push(args);
+ // globalLinkify.tlds(...args);
+
+ return config;
+ },
+ set: (...args) => {
+ globalCustomizations.set.push(args);
+ // globalLinkify.set(...args);
+
+ return config;
+ },
+ resetAll: () => {
+ for (let type in globalCustomizations) {
+ globalCustomizations[type] = [];
+ }
+
+ return config;
+ }
+};
class Linkify extends React.Component {
static MATCH = 'LINKIFY_MATCH'
@@ -20,7 +54,10 @@ class Linkify extends React.Component {
validate: React.PropTypes.func.isRequired,
normalize: React.PropTypes.func.isRequired
})
- )
+ ),
+ fuzzyLink: React.PropTypes.bool,
+ fuzzyIP: React.PropTypes.bool,
+ fuzzyEmail: React.PropTypes.bool
}
static defaultProps = {
@@ -35,33 +72,39 @@ class Linkify extends React.Component {
}
componentDidUpdate(nextProps) {
- if (this.props.handlers !== nextProps.handlers) {
- this.addCustomHandlers();
- }
+ this.addCustomHandlers();
}
addCustomHandlers() {
const { handlers } = this.props;
- if (handlers.length) {
- this.linkify = new LinkifyIt();
- this.linkify.tlds(tlds);
+ this.linkify = this.linkify || new LinkifyIt();
+ this.linkify.tlds(tlds);
- handlers.forEach(handler => {
- this.linkify.add(handler.prefix, {
- validate: handler.validate,
- normalize: handler.normalize
- });
- });
+ // add global customizations
+ for (let type in globalCustomizations) {
+ globalCustomizations[type].forEach(c => this.linkify[type](...c))
}
+
+ // add instance customizations
+ (handlers || []).forEach((handler) => {
+ this.linkify.add(handler.prefix, {
+ validate: handler.validate,
+ normalize: handler.normalize
+ });
+ });
+
+ ['fuzzyLink', 'fuzzyIP', 'fuzzyEmail'].forEach(f => {
+ typeof this.props[f] === 'boolean' && this.linkify.set({ [f]: this.props[f] })
+ })
}
parseCounter = 0
getMatches(string) {
- const linkifyInstance = this.linkify || linkify;
+ // const linkifyInstance = this.linkify || globalLinkify;
- return linkifyInstance.match(string);
+ return this.linkify.match(string);
}
parseString(string) {
diff --git a/src/__tests__/Linkify-test.js b/src/__tests__/Linkify-test.js
index 4f2578d..528a986 100644
--- a/src/__tests__/Linkify-test.js
+++ b/src/__tests__/Linkify-test.js
@@ -5,6 +5,8 @@ let TestUtils = require('react-addons-test-utils');
describe('Linkify', () => {
let Linkify = require('../Linkify.jsx').default;
+ let linkifyCustomizations = require('../Linkify.jsx').config;
+
describe('#parseString', () => {
let linkify = TestUtils.renderIntoDocument();
@@ -121,7 +123,7 @@ describe('Linkify', () => {
});
});
- describe('#addCustomHandlers', () => {
+ describe('LinkifyIt config', () => {
it('should match a custom handler added through the "handlers" prop', () => {
const linkify = TestUtils.renderIntoDocument(
{
expect(output[3].props.children).toEqual(input[3]);
expect(output[4]).toEqual(input[4]);
})
+
+ it('should apply global customizations', () => {
+ linkifyCustomizations
+ .resetAll()
+ .tlds('linkify', true)
+ .add('@', {
+ validate() {
+ return 7;
+ },
+ normalize(match) {
+ match.url = 'https://twitter.com/' + match.url.replace(/^@/, '');
+ }
+ })
+ const linkify = TestUtils.renderIntoDocument(
+
+ );
+
+ const input = ['this is an ', '@mention', ' and ', 'test.linkify', ' TLD handler'];
+ const output = linkify.parseString(input.join(''));
+
+ expect(output[0]).toEqual(input[0]);
+ expect(output[1].type).toEqual('a');
+ expect(output[1].props.href).toEqual(`https://twitter.com/mention`);
+ expect(output[1].props.children).toEqual(input[1]);
+
+ expect(output[2]).toEqual(input[2]);
+ expect(output[3].type).toEqual('a');
+ expect(output[3].props.href).toEqual(`http://test.linkify`);
+ expect(output[3].props.children).toEqual(input[3]);
+ expect(output[4]).toEqual(input[4]);
+ });
+
+ it('should merge global and instance handlers', () => {
+ linkifyCustomizations
+ .resetAll()
+ .add('@', {
+ validate() {
+ return 7;
+ },
+ normalize(match) {
+ match.url = 'https://twitter.com/' + match.url.replace(/^@/, '');
+ }
+ })
+ const linkify = TestUtils.renderIntoDocument(
+
+
+ );
+
+ const input = ['this is an ', '@mention', ' and ', '$mention', ' handler'];
+ const output = linkify.parseString(input.join(''));
+
+ expect(output[0]).toEqual(input[0]);
+ expect(output[1].type).toEqual('a');
+ expect(output[1].props.href).toEqual(`https://twitter.com/mention`);
+ expect(output[1].props.children).toEqual(input[1]);
+
+ expect(output[2]).toEqual(input[2]);
+ expect(output[3].type).toEqual('a');
+ expect(output[3].props.href).toEqual(`https://blingtwitter.com/mention`);
+ expect(output[3].props.children).toEqual(input[3]);
+ expect(output[4]).toEqual(input[4]);
+ });
+
+ it('should set fuzzy* options', () => {
+ const linkify = TestUtils.renderIntoDocument(
+
+ );
+
+ const linkInput = 'this should not match: www.test.com';
+ const linkOutput = linkify.parseString(linkInput);
+ expect(linkOutput).toEqual(linkInput);
+ });
+
+ it('should reset global customizations', () => {
+ linkifyCustomizations
+ .add('@', {
+ validate() {
+ return 7;
+ },
+ normalize(match) {
+ match.url = 'https://twitter.com/' + match.url.replace(/^@/, '');
+ }
+ })
+ .resetAll()
+
+ const linkify = TestUtils.renderIntoDocument(
+
+ );
+
+ const input = 'this @mention should not match';
+ const output = linkify.parseString(input);
+
+ expect(output).toEqual(input);
+ })
});
describe('#render', () => {