Add DOM-based linkify to goonchat (no more URLs in IC) (#38693)

* Add DOM-based linkify to goonchat (no more URLs in IC)

* Add linkify spans to places where OOC messages appear

This includes:
- OOC
- Deadchat
- Admin chat
- Admin logs
- Admin PMs
- Prayers

* Limit fallback behavior to linkify spans
This commit is contained in:
Tad Hardesty
2018-06-25 19:44:34 -07:00
committed by yogstation13-bot
parent 29c8e07a29
commit 8059c81631
8 changed files with 98 additions and 17 deletions

View File

@@ -95,8 +95,53 @@ if (typeof String.prototype.trim !== 'function') {
};
}
// Linkify the contents of a node, within its parent.
function linkify(parent, insertBefore, text) {
var start = 0;
var match;
var regex = /(?:(?:https?:\/\/)|(?:www\.))(?:[^ ]*?\.[^ ]*?)+[-A-Za-z0-9+&@#\/%?=~_|$!:,.;()]+/ig;
while ((match = regex.exec(text)) !== null) {
// add the unmatched text
parent.insertBefore(document.createTextNode(text.substring(start, match.index)), insertBefore);
var href = match[0];
if (!/^https?:\/\//i.test(match[0])) {
href = "http://" + match[0];
}
// add the link
var link = document.createElement("a");
link.href = href;
link.textContent = match[0];
parent.insertBefore(link, insertBefore);
start = regex.lastIndex;
}
if (start !== 0) {
// add the remaining text and remove the original text node
parent.insertBefore(document.createTextNode(text.substring(start)), insertBefore);
parent.removeChild(insertBefore);
}
}
// Recursively linkify the children of a given node.
function linkify_node(node) {
var children = node.childNodes;
// work backwards to avoid the risk of looping forever on our own output
for (var i = children.length - 1; i >= 0; --i) {
var child = children[i];
if (child.nodeType == Node.TEXT_NODE) {
// text is to be linkified
linkify(node, child, child.textContent);
} else if (child.nodeName != "A" && child.nodeName != "a") {
// do not linkify existing links
linkify_node(child);
}
}
}
//Shit fucking piece of crap that doesn't work god fuckin damn it
function linkify(text) {
function linkify_fallback(text) {
var rex = /((?:<a|<iframe|<img)(?:.*?(?:src="|href=").*?))?(?:(?:https?:\/\/)|(?:www\.))+(?:[^ ]*?\.[^ ]*?)+[-A-Za-z0-9+&@#\/%?=~_|$!:,.;]+/ig;
return text.replace(rex, function ($0, $1) {
if(/^https?:\/\/.+/i.test($0)) {
@@ -283,11 +328,6 @@ function output(message, flag) {
}
}
//Url stuff
if (message.length && flag != 'preventLink') {
message = linkify(message);
}
opts.messageCount++;
//Pop the top message off if history limit reached
@@ -340,6 +380,20 @@ function output(message, flag) {
$last_message = trimmed_message;
$messages[0].appendChild(entry);
$(entry).find("img.icon").error(iconError);
var to_linkify = $(entry).find(".linkify");
if (typeof Node === 'undefined') {
// Linkify fallback for old IE
for(var i = 0; i < to_linkify.length; ++i) {
to_linkify[i].innerHTML = linkify_fallback(to_linkify[i].innerHTML);
}
} else {
// Linkify for modern IE versions
for(var i = 0; i < to_linkify.length; ++i) {
linkify_node(to_linkify[i]);
}
}
//Actually do the snap
//Stuff we can do after the message shows can go here, in the interests of responsiveness
if (opts.highlightTerms && opts.highlightTerms.length > 0) {