2021-10-13 17:36:55 +00:00
|
|
|
// There are many regex for matching URL, but non seem to be the correct solution.
|
|
|
|
// Here we will use very fast and simple one.
|
|
|
|
// Tested most of the regex solutions mentioned in this post
|
|
|
|
// https://stackoverflow.com/questions/37684/how-to-replace-plain-urls-with-links.
|
|
|
|
// The best one was http://alexcorvi.github.io/anchorme.js/, which still wasn't perfect.
|
|
|
|
// The best non regex solution was https://github.com/Hypercontext/linkifyjs, but it feels a little too heavy.
|
|
|
|
// Some examples why this is better or worse from other solution:
|
|
|
|
/**
|
|
|
|
|
|
|
|
For 'http://www.uk,http://www.uk'
|
|
|
|
'OurRegex' [ 'http://www.uk', 'http://www.uk' ]
|
|
|
|
'Anchrome' [ 'http://www.uk,http://www.uk' ]
|
|
|
|
'linkify' [ 'http://www.uk,http://www.uk' ]
|
|
|
|
'url-regex' [ 'http://www.uk', 'http://www.uk' ]
|
|
|
|
|
|
|
|
For 'might.it be a link'
|
|
|
|
'OurRegex' []
|
|
|
|
'Anchrome' [ 'might.it' ]
|
|
|
|
'linkify' [ 'http://might.it' ]
|
|
|
|
'url-regex' []
|
|
|
|
|
|
|
|
For 'Is this correct.No it is not'
|
|
|
|
'OurRegex' []
|
|
|
|
'Anchrome' [ 'correct.No' ]
|
|
|
|
'linkify' [ 'http://correct.No' ]
|
|
|
|
'url-regex' []
|
|
|
|
|
|
|
|
For 'Link (in http://www.uk?)'
|
|
|
|
'OurRegex' [ 'http://www.uk' ]
|
|
|
|
'Anchrome' [ 'http://www.uk' ]
|
|
|
|
'linkify' [ 'http://www.uk' ]
|
|
|
|
'url-regex' [ 'http://www.uk?)' ]
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Match http or https then domain name (with optional port) then any text that ends with letter or number.
|
|
|
|
export const urlRegex = /(https?:\/\/[A-Za-z\d][A-Za-z\d-.]*(?!\.)(?::\d+)?(?:\/[^\s]*)?[\w\d/])/;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Detects URLs in a text and returns list of tokens { value, isLink }
|
|
|
|
*/
|
|
|
|
export function findLinks(text: string): Array<{value: string, isLink: boolean}> {
|
|
|
|
if (!text) {
|
|
|
|
return [{ value: text, isLink: false }];
|
|
|
|
}
|
|
|
|
// urls will be at odd-number indices
|
|
|
|
return text.split(urlRegex).map((value, i) => ({ value, isLink : (i % 2) === 1}));
|
|
|
|
}
|
2021-11-29 19:38:05 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Based on https://stackoverflow.com/a/22429679/2482744
|
|
|
|
* -----------------------------------------------------
|
|
|
|
* Calculate a 32 bit FNV-1a hash
|
|
|
|
* Found here: https://gist.github.com/vaiorabbit/5657561
|
|
|
|
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
|
|
|
|
*/
|
|
|
|
export function hashFnv32a(str: string): string {
|
|
|
|
let hval = 0x811c9dc5;
|
|
|
|
for (let i = 0; i < str.length; i++) {
|
|
|
|
hval ^= str.charCodeAt(i);
|
|
|
|
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
|
|
|
|
}
|
|
|
|
// Convert to 8 digit hex string
|
|
|
|
return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A poor man's hash for when proper crypto isn't worth it.
|
|
|
|
*/
|
|
|
|
export function simpleStringHash(str: string) {
|
|
|
|
let result = '';
|
|
|
|
// Crudely convert 32 bits to 128 bits to reduce collisions
|
|
|
|
for (let i = 0; i < 4; i++) {
|
|
|
|
result += hashFnv32a(result + str);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|