JSFiddle - React, Tailwind, and code Playground
HTML
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Link finder</title>
</head>
<body>
<div id="text" contenteditable="true">test</div>
<div id="comment"></div>
</body>
</html>
CSS
#text .link {
color:blue;
display: inline-block;
margin:0;
}
#text {
border: 1px solid black;
padding: 0.5em;
min-height:100px;
min-width:200px;
}
JavaScript
$(window).load(function () {
var links = [];
var comment = jQuery('#comment');
jQuery('#text').keyup(function () {
checkForLinks(jQuery(this));
}).blur(function () {
checkForLinks(jQuery(this), true);
});
function checkForLinks(elem, isBlur) {
var text = elem.html();
var urlCheckString = '((?:http[s]?:\\/\\/(?:www\\.)?|www\\.){1}(?:[0-9A-Za-z\\-%_]+\\.)+[a-zA-Z]{2,}(?::[0-9]+)?(?:(?:/[0-9A-Za-z\\-\\.%_]*)+)?(?:\\?(?:[0-9A-Za-z\\-\\.%_]+(?:=[0-9A-Za-z\\-\\.%_\\+]*)?)?(?:&(?:[0-9A-Za-z\\-\\.%_]+(?:=[0-9A-Za-z\\-\\.%_\\+]*)?)?)*)?(?:#[0-9A-Za-z\\-\\.%_\\+=\\?&;]*)?)'; //full url
if (isBlur) {
var regex = new RegExp(urlCheckString, 'gi');
} else {
var regex = new RegExp(urlCheckString + '(?!<br>)[^0-9A-Za-z\-\.%_\+\/=&\?;#]', 'gi');
}
//console.log("Text: " + text);
var newText = text;
newText = newText.replace(new RegExp('<p class="link">([^<]*)</p>', 'gi'), '$1');
newText = newText.replace(new RegExp('<p class="link">([^<]*<br>[^<]*)</p>', 'gi'), '$1');
newText = newText.replace(new RegExp('<p></p>', 'gi'), '');
newText = newText.replace(new RegExp('<a[^>]*>([^<]*)</a>', 'gi'), '$1'); //change back the IE autochange
//console.log("newText: " + newText);
newText = newText.replace(regex, function (match, link, offset, string) {
var trailingChar = match.substr(link.length);
if (!links[link]) {
links[link] = link;
linkDetected(link);
}
return '<p class="link">' + link + '</p>' + trailingChar;
});
//console.log("newTextafter: " + newText);
if (text.localeCompare(newText) != 0) {
elem.html(newText);
}
}
function linkDetected(linkString) {
comment.append('<pre>' + linkString + '</pre>');
}
});