Linkifier rewrite.
This commit is contained in:
parent
66c5256754
commit
541454d45a
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* appchan x - Version 2.2.2 - 2013-08-03
|
||||
* appchan x - Version 2.2.2 - 2013-08-04
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
// ==/UserScript==
|
||||
|
||||
/*
|
||||
* appchan x - Version 2.2.2 - 2013-08-03
|
||||
* appchan x - Version 2.2.2 - 2013-08-04
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||
@ -3263,6 +3263,7 @@
|
||||
post: post,
|
||||
info: info,
|
||||
comment: $('.postMessage', post),
|
||||
links: [],
|
||||
quotelinks: [],
|
||||
backlinks: info.getElementsByClassName('backlink')
|
||||
};
|
||||
@ -6590,10 +6591,10 @@
|
||||
|
||||
Linkify = {
|
||||
init: function() {
|
||||
if (g.VIEW === 'catalog' || !Conf['Linkify']) {
|
||||
if (g.VIEW === 'catalog') {
|
||||
return;
|
||||
}
|
||||
this.regString = Conf['Allow False Positives'] ? /(\b([a-z]+:\/\/|[a-z]{3,}\.[-a-z0-9]+\.[a-z]+|[-a-z0-9]+\.[a-z]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-z]{3,}:[a-z0-9?]|[a-z0-9._%+-:]+@[a-z0-9.-]+\.[a-z0-9])[^\s'"]+)/gi : /(((magnet|mailto)\:|(www\.)|(news|(ht|f)tp(s?))\:\/\/){1}\S+)/gi;
|
||||
this.regString = Conf['Allow False Positives'] ? /(\b([a-z]+:\/\/|[a-z]{3,}\.[-a-z0-9]+\.[a-z]|[-a-z0-9]+\.[a-z]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]|[a-z]{3,}:[a-z0-9?]|[\S]+@[a-z0-9.-]+\.[a-z0-9])[^\s'"]+)/gi : /(((magnet|mailto)\:|(www\.)|(news|(ht|f)tp(s?))\:\/\/){1}\S+)/gi;
|
||||
if (Conf['Comment Expansion']) {
|
||||
ExpandComment.callbacks.push(this.node);
|
||||
}
|
||||
@ -6602,113 +6603,220 @@
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
cypher: $.el('div'),
|
||||
node: function() {
|
||||
var a, child, cypher, cypherText, data, embed, embedder, embeds, i, index, len, link, links, lookahead, name, next, node, nodes, snapshot, spoiler, text, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2;
|
||||
var data, embedder, i, len, link, links, match, node, range, snapshot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
|
||||
|
||||
if (this.isClone && Conf['Embedding']) {
|
||||
_ref = $$('.embedder', this.nodes.comment);
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
embedder = _ref[_i];
|
||||
$.on(embedder, "click", Linkify.toggle);
|
||||
$.on(embedder, "click", Linkify.cb.toggle);
|
||||
}
|
||||
return;
|
||||
}
|
||||
snapshot = $.X('.//text()', this.nodes.comment);
|
||||
cypher = Linkify.cypher;
|
||||
i = -1;
|
||||
len = snapshot.snapshotLength;
|
||||
links = [];
|
||||
while (++i < len) {
|
||||
nodes = $.frag();
|
||||
node = snapshot.snapshotItem(i);
|
||||
data = node.data;
|
||||
if (!(node.parentNode && Linkify.regString.test(data))) {
|
||||
continue;
|
||||
if (match = data.match(Linkify.regString)) {
|
||||
links.pushArrays(Linkify.gatherLinks(match, node));
|
||||
}
|
||||
Linkify.regString.lastIndex = 0;
|
||||
cypherText = [];
|
||||
if (next = node.nextSibling) {
|
||||
cypher.textContent = node.textContent;
|
||||
cypherText[0] = cypher.innerHTML;
|
||||
while ((next.nodeName.toLowerCase() === 'wbr' || next.nodeName.toLowerCase() === 's') && (lookahead = next.nextSibling) && ((name = lookahead.nodeName) === "#text" || name.toLowerCase() === 'br')) {
|
||||
cypher.textContent = lookahead.textContent;
|
||||
cypherText.push((spoiler = next.innerHTML) ? "<s>" + (spoiler.replace(/</g, ' <')) + "</s>" : '<wbr>');
|
||||
cypherText.push(cypher.innerHTML);
|
||||
$.rm(next);
|
||||
next = lookahead.nextSibling;
|
||||
if (lookahead.nodeName === "#text") {
|
||||
$.rm(lookahead);
|
||||
}
|
||||
if (!next) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cypherText.length) {
|
||||
data = cypherText.join('');
|
||||
}
|
||||
links = data.match(Linkify.regString);
|
||||
for (_j = 0, _len1 = links.length; _j < _len1; _j++) {
|
||||
link = links[_j];
|
||||
index = data.indexOf(link);
|
||||
if (text = data.slice(0, index)) {
|
||||
cypher.innerHTML = text;
|
||||
_ref1 = __slice.call(cypher.childNodes);
|
||||
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
|
||||
child = _ref1[_k];
|
||||
$.add(nodes, child);
|
||||
}
|
||||
}
|
||||
cypher.innerHTML = (link.indexOf(':') < 0 ? (link.indexOf('@') > 0 ? 'mailto:' + link : 'http://' + link) : link).replace(/<(wbr|s|\/s)>/g, '');
|
||||
a = $.el('a', {
|
||||
innerHTML: link,
|
||||
className: 'linkify',
|
||||
rel: 'nofollow noreferrer',
|
||||
target: '_blank',
|
||||
href: cypher.textContent
|
||||
});
|
||||
$.add(nodes, Linkify.embedder(a));
|
||||
data = data.slice(index + link.length);
|
||||
}
|
||||
if (data) {
|
||||
cypher.innerHTML = data;
|
||||
_ref2 = __slice.call(cypher.childNodes);
|
||||
for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) {
|
||||
child = _ref2[_l];
|
||||
$.add(nodes, child);
|
||||
}
|
||||
}
|
||||
$.replace(node, nodes);
|
||||
}
|
||||
if (Conf['Auto-embed']) {
|
||||
embeds = $$('.embedder', this.nodes.comment);
|
||||
for (_m = 0, _len4 = embeds.length; _m < _len4; _m++) {
|
||||
embed = embeds[_m];
|
||||
embed.click();
|
||||
if (Conf['Linkify']) {
|
||||
for (_j = 0, _len1 = links.length; _j < _len1; _j++) {
|
||||
range = links[_j];
|
||||
this.nodes.links.push(Linkify.makeLink(range));
|
||||
}
|
||||
}
|
||||
if (!(Conf['Embedding'] || Conf['Link Title'])) {
|
||||
return;
|
||||
}
|
||||
_ref1 = this.nodes.links || links;
|
||||
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
|
||||
range = _ref1[_k];
|
||||
if (link = Linkify.services(range)) {
|
||||
if (Conf['Embedding']) {
|
||||
Linkify.embed(link);
|
||||
}
|
||||
if (Conf['Link Title']) {
|
||||
Linkify.title(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
toggle: function() {
|
||||
var el, embed, style, type, url;
|
||||
gatherLinks: function(match, node) {
|
||||
var data, i, len, len2, link, links, next, range, result;
|
||||
|
||||
links = [];
|
||||
i = 0;
|
||||
len = match.length;
|
||||
data = node.data;
|
||||
while ((link = match[i++]) && i > len) {
|
||||
range = document.createRange();
|
||||
range.setStart(node, len2 = data.indexOf(link));
|
||||
range.setEnd(node, len2 + link.length);
|
||||
links.push(range);
|
||||
}
|
||||
range = document.createRange();
|
||||
range.setStart(node, len = data.indexOf(link));
|
||||
if ((data.length - (len += link.length)) > 0) {
|
||||
range.setEnd(node, len);
|
||||
links.push(range);
|
||||
return links;
|
||||
}
|
||||
while ((next = node.nextSibling) && next.nodeName.toLowerCase() !== 'br') {
|
||||
node = next;
|
||||
data = node.data;
|
||||
if (result = /[\s'"]/.exec(data)) {
|
||||
range.setEnd(node, result.index);
|
||||
}
|
||||
}
|
||||
if (range.collapsed) {
|
||||
if (node.nodeName.toLowerCase() === 'wbr') {
|
||||
node = node.previousSibling;
|
||||
}
|
||||
range.setEnd(node, node.length);
|
||||
}
|
||||
links.push(range);
|
||||
return links;
|
||||
},
|
||||
makeLink: function(range) {
|
||||
var a, link;
|
||||
|
||||
link = range.toString();
|
||||
link = link.contains(':') ? link : (link.contains('@') ? 'mailto:' : 'http://') + link;
|
||||
a = $.el('a', {
|
||||
className: 'linkify',
|
||||
rel: 'nofollow noreferrer',
|
||||
target: '_blank',
|
||||
href: link
|
||||
});
|
||||
range.surroundContents(a);
|
||||
return a;
|
||||
},
|
||||
services: function(link) {
|
||||
var href, key, match, type, _ref;
|
||||
|
||||
href = Conf['Linkify'] ? link.href : link.toString();
|
||||
_ref = Linkify.types;
|
||||
for (key in _ref) {
|
||||
type = _ref[key];
|
||||
if (!(match = type.regExp.exec(href))) {
|
||||
continue;
|
||||
}
|
||||
if (!Conf['Linkify']) {
|
||||
link = Linkify.makeLink(link);
|
||||
}
|
||||
return [key, match[1], match[2], link];
|
||||
}
|
||||
},
|
||||
embed: function(data) {
|
||||
var embed, key, link, options, uid;
|
||||
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3];
|
||||
embed = $.el('a', {
|
||||
name: uid,
|
||||
option: options,
|
||||
className: 'embedder',
|
||||
href: 'javascript:;',
|
||||
textContent: '(embed)'
|
||||
});
|
||||
embed.dataset.service = key;
|
||||
embed.dataset.originalurl = link.href;
|
||||
$.addClass(link, "" + embed.dataset.service);
|
||||
$.on(embed, 'click', Linkify.cb.toggle);
|
||||
return $.after(link, [$.tn(' '), embed]);
|
||||
},
|
||||
cb: {
|
||||
toggle: function() {
|
||||
var el, embed;
|
||||
|
||||
embed = this.previousElementSibling;
|
||||
el = !this.className.contains("embedded") ? Linkify.cb.embed(this) : Linkify.cb.unembed(this);
|
||||
$.replace(embed, el);
|
||||
return $.toggleClass(this, 'embedded');
|
||||
},
|
||||
embed: function(a) {
|
||||
var el, style, type;
|
||||
|
||||
el = (type = Linkify.types[a.dataset.service]).el.call(a);
|
||||
el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px";
|
||||
a.textContent = '(unembed)';
|
||||
return el;
|
||||
},
|
||||
unembed: function(a) {
|
||||
var el, url;
|
||||
|
||||
embed = this.previousElementSibling;
|
||||
if (this.className.contains("embedded")) {
|
||||
el = $.el('a', {
|
||||
rel: 'nofollow noreferrer',
|
||||
target: 'blank',
|
||||
className: 'linkify',
|
||||
href: url = this.getAttribute("data-originalURL"),
|
||||
textContent: this.getAttribute("data-title") || url
|
||||
href: url = a.dataset.originalurl,
|
||||
textContent: a.dataset.title || url
|
||||
});
|
||||
this.textContent = '(embed)';
|
||||
$.addClass(el, "" + (this.getAttribute('data-service')));
|
||||
} else {
|
||||
el = (type = Linkify.types[this.getAttribute("data-service")]).el.call(this);
|
||||
el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px";
|
||||
this.textContent = '(unembed)';
|
||||
a.textContent = '(embed)';
|
||||
$.addClass(el, "" + a.dataset.service);
|
||||
return el;
|
||||
},
|
||||
title: function(data) {
|
||||
var key, link, options, service, text, uid;
|
||||
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3];
|
||||
service = Linkify.types[key].title;
|
||||
return link.textContent = (function() {
|
||||
switch (this.status) {
|
||||
case 200:
|
||||
case 304:
|
||||
text = "" + (service.text.call(this));
|
||||
if (Conf['Embedding']) {
|
||||
link.nextElementSibling.dataset.title = text;
|
||||
}
|
||||
return text;
|
||||
case 404:
|
||||
return "[" + key + "] Not Found";
|
||||
case 403:
|
||||
return "[" + key + "] Forbidden or Private";
|
||||
default:
|
||||
return "[" + key + "] " + this.status + "'d";
|
||||
}
|
||||
}).call(this);
|
||||
}
|
||||
$.replace(embed, el);
|
||||
return $.toggleClass(this, 'embedded');
|
||||
},
|
||||
title: function(data) {
|
||||
var key, link, options, service, title, titles, uid;
|
||||
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3];
|
||||
titles = {};
|
||||
service = Linkify.types[key].title;
|
||||
title = "";
|
||||
return $.get('CachedTitles', {}, function(item) {
|
||||
var err;
|
||||
|
||||
titles = item['CachedTitles'];
|
||||
if (title = titles[uid]) {
|
||||
link.textContent = title[0];
|
||||
if (Conf['Embedding']) {
|
||||
link.nextElementSibling.dataset.title = title[0];
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$.cache(service.api(uid), function() {
|
||||
return title = Linkify.cb.title.apply(this, [data]);
|
||||
});
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
link.innerHTML = "[" + key + "] <span class=warning>Title Link Blocked</span> (are you using NoScript?)</a>";
|
||||
return;
|
||||
}
|
||||
if (title) {
|
||||
titles[uid] = [title, Date.now()];
|
||||
return $.set('CachedTitles', titles);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
types: {
|
||||
YouTube: {
|
||||
@ -6719,8 +6827,8 @@
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function() {
|
||||
return "https://gdata.youtube.com/feeds/api/videos/" + this.name + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode";
|
||||
api: function(uid) {
|
||||
return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode";
|
||||
},
|
||||
text: function() {
|
||||
return JSON.parse(this.responseText).entry.title.$t;
|
||||
@ -6744,8 +6852,8 @@
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function() {
|
||||
return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + this.name;
|
||||
api: function(uid) {
|
||||
return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
|
||||
},
|
||||
text: function() {
|
||||
return JSON.parse(this.responseText).title;
|
||||
@ -6775,7 +6883,7 @@
|
||||
style: 'border: 0; width: auto; height: auto;',
|
||||
el: function() {
|
||||
return $.el('div', {
|
||||
innerHTML: "<a target=_blank href='" + (this.getAttribute('data-originalURL')) + "'><img src='" + (this.getAttribute('data-originalURL')) + "'></a>"
|
||||
innerHTML: "<a target=_blank href='" + this.dataset.originalurl + "'><img src='" + this.dataset.originalurl + "'></a>"
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -6798,8 +6906,8 @@
|
||||
return div;
|
||||
},
|
||||
title: {
|
||||
api: function() {
|
||||
return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + this.name;
|
||||
api: function(uid) {
|
||||
return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid;
|
||||
},
|
||||
text: function() {
|
||||
return JSON.parse(this.responseText).title;
|
||||
@ -6826,8 +6934,8 @@
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function() {
|
||||
return "https://api.github.com/gists/" + this.name;
|
||||
api: function(uid) {
|
||||
return "https://api.github.com/gists/" + uid;
|
||||
},
|
||||
text: function() {
|
||||
var file, response;
|
||||
@ -6849,76 +6957,6 @@
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
embedder: function(a) {
|
||||
var callbacks, embed, key, match, service, titles, type, _ref;
|
||||
|
||||
if (!Conf['Link Title']) {
|
||||
return [a];
|
||||
}
|
||||
titles = {};
|
||||
callbacks = function() {
|
||||
var title;
|
||||
|
||||
return a.textContent = (function() {
|
||||
switch (this.status) {
|
||||
case 200:
|
||||
case 304:
|
||||
title = "" + (service.text.call(this));
|
||||
embed.setAttribute('data-title', title);
|
||||
titles[embed.name] = [title, Date.now()];
|
||||
$.set('CachedTitles', titles);
|
||||
return title;
|
||||
case 404:
|
||||
return "[" + key + "] Not Found";
|
||||
case 403:
|
||||
return "[" + key + "] Forbidden or Private";
|
||||
default:
|
||||
return "[" + key + "] " + this.status + "'d";
|
||||
}
|
||||
}).call(this);
|
||||
};
|
||||
_ref = Linkify.types;
|
||||
for (key in _ref) {
|
||||
type = _ref[key];
|
||||
if (!(match = a.href.match(type.regExp))) {
|
||||
continue;
|
||||
}
|
||||
embed = $.el('a', {
|
||||
name: (a.name = match[1]),
|
||||
option: match[2],
|
||||
className: 'embedder',
|
||||
href: 'javascript:;',
|
||||
textContent: '(embed)'
|
||||
});
|
||||
embed.setAttribute('data-service', key);
|
||||
embed.setAttribute('data-originalURL', a.href);
|
||||
$.addClass(a, "" + (embed.getAttribute('data-service')));
|
||||
$.on(embed, 'click', Linkify.toggle);
|
||||
if (!Conf['Embedding']) {
|
||||
embed.hidden = true;
|
||||
}
|
||||
if (Conf['Link Title'] && (service = type.title)) {
|
||||
$.get('CachedTitles', {}, function(item) {
|
||||
var err, title;
|
||||
|
||||
titles = item['CachedTitles'];
|
||||
if (title = titles[match[1]]) {
|
||||
a.textContent = title[0];
|
||||
return embed.setAttribute('data-title', title[0]);
|
||||
} else {
|
||||
try {
|
||||
return $.cache(service.api.call(a), callbacks);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return a.innerHTML = "[" + key + "] <span class=warning>Title Link Blocked</span> (are you using NoScript?)</a>";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return [a, $.tn(' '), embed];
|
||||
}
|
||||
return [a];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Generated by CoffeeScript
|
||||
/*
|
||||
* appchan x - Version 2.2.2 - 2013-08-03
|
||||
* appchan x - Version 2.2.2 - 2013-08-04
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||
@ -3272,6 +3272,7 @@
|
||||
post: post,
|
||||
info: info,
|
||||
comment: $('.postMessage', post),
|
||||
links: [],
|
||||
quotelinks: [],
|
||||
backlinks: info.getElementsByClassName('backlink')
|
||||
};
|
||||
@ -6593,10 +6594,10 @@
|
||||
|
||||
Linkify = {
|
||||
init: function() {
|
||||
if (g.VIEW === 'catalog' || !Conf['Linkify']) {
|
||||
if (g.VIEW === 'catalog') {
|
||||
return;
|
||||
}
|
||||
this.regString = Conf['Allow False Positives'] ? /(\b([a-z]+:\/\/|[a-z]{3,}\.[-a-z0-9]+\.[a-z]+|[-a-z0-9]+\.[a-z]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-z]{3,}:[a-z0-9?]|[a-z0-9._%+-:]+@[a-z0-9.-]+\.[a-z0-9])[^\s'"]+)/gi : /(((magnet|mailto)\:|(www\.)|(news|(ht|f)tp(s?))\:\/\/){1}\S+)/gi;
|
||||
this.regString = Conf['Allow False Positives'] ? /(\b([a-z]+:\/\/|[a-z]{3,}\.[-a-z0-9]+\.[a-z]|[-a-z0-9]+\.[a-z]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]|[a-z]{3,}:[a-z0-9?]|[\S]+@[a-z0-9.-]+\.[a-z0-9])[^\s'"]+)/gi : /(((magnet|mailto)\:|(www\.)|(news|(ht|f)tp(s?))\:\/\/){1}\S+)/gi;
|
||||
if (Conf['Comment Expansion']) {
|
||||
ExpandComment.callbacks.push(this.node);
|
||||
}
|
||||
@ -6605,113 +6606,220 @@
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
cypher: $.el('div'),
|
||||
node: function() {
|
||||
var a, child, cypher, cypherText, data, embed, embedder, embeds, i, index, len, link, links, lookahead, name, next, node, nodes, snapshot, spoiler, text, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2;
|
||||
var data, embedder, i, len, link, links, match, node, range, snapshot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
|
||||
|
||||
if (this.isClone && Conf['Embedding']) {
|
||||
_ref = $$('.embedder', this.nodes.comment);
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
embedder = _ref[_i];
|
||||
$.on(embedder, "click", Linkify.toggle);
|
||||
$.on(embedder, "click", Linkify.cb.toggle);
|
||||
}
|
||||
return;
|
||||
}
|
||||
snapshot = $.X('.//text()', this.nodes.comment);
|
||||
cypher = Linkify.cypher;
|
||||
i = -1;
|
||||
len = snapshot.snapshotLength;
|
||||
links = [];
|
||||
while (++i < len) {
|
||||
nodes = $.frag();
|
||||
node = snapshot.snapshotItem(i);
|
||||
data = node.data;
|
||||
if (!(node.parentNode && Linkify.regString.test(data))) {
|
||||
continue;
|
||||
if (match = data.match(Linkify.regString)) {
|
||||
links.pushArrays(Linkify.gatherLinks(match, node));
|
||||
}
|
||||
Linkify.regString.lastIndex = 0;
|
||||
cypherText = [];
|
||||
if (next = node.nextSibling) {
|
||||
cypher.textContent = node.textContent;
|
||||
cypherText[0] = cypher.innerHTML;
|
||||
while ((next.nodeName.toLowerCase() === 'wbr' || next.nodeName.toLowerCase() === 's') && (lookahead = next.nextSibling) && ((name = lookahead.nodeName) === "#text" || name.toLowerCase() === 'br')) {
|
||||
cypher.textContent = lookahead.textContent;
|
||||
cypherText.push((spoiler = next.innerHTML) ? "<s>" + (spoiler.replace(/</g, ' <')) + "</s>" : '<wbr>');
|
||||
cypherText.push(cypher.innerHTML);
|
||||
$.rm(next);
|
||||
next = lookahead.nextSibling;
|
||||
if (lookahead.nodeName === "#text") {
|
||||
$.rm(lookahead);
|
||||
}
|
||||
if (!next) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cypherText.length) {
|
||||
data = cypherText.join('');
|
||||
}
|
||||
links = data.match(Linkify.regString);
|
||||
for (_j = 0, _len1 = links.length; _j < _len1; _j++) {
|
||||
link = links[_j];
|
||||
index = data.indexOf(link);
|
||||
if (text = data.slice(0, index)) {
|
||||
cypher.innerHTML = text;
|
||||
_ref1 = __slice.call(cypher.childNodes);
|
||||
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
|
||||
child = _ref1[_k];
|
||||
$.add(nodes, child);
|
||||
}
|
||||
}
|
||||
cypher.innerHTML = (link.indexOf(':') < 0 ? (link.indexOf('@') > 0 ? 'mailto:' + link : 'http://' + link) : link).replace(/<(wbr|s|\/s)>/g, '');
|
||||
a = $.el('a', {
|
||||
innerHTML: link,
|
||||
className: 'linkify',
|
||||
rel: 'nofollow noreferrer',
|
||||
target: '_blank',
|
||||
href: cypher.textContent
|
||||
});
|
||||
$.add(nodes, Linkify.embedder(a));
|
||||
data = data.slice(index + link.length);
|
||||
}
|
||||
if (data) {
|
||||
cypher.innerHTML = data;
|
||||
_ref2 = __slice.call(cypher.childNodes);
|
||||
for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) {
|
||||
child = _ref2[_l];
|
||||
$.add(nodes, child);
|
||||
}
|
||||
}
|
||||
$.replace(node, nodes);
|
||||
}
|
||||
if (Conf['Auto-embed']) {
|
||||
embeds = $$('.embedder', this.nodes.comment);
|
||||
for (_m = 0, _len4 = embeds.length; _m < _len4; _m++) {
|
||||
embed = embeds[_m];
|
||||
embed.click();
|
||||
if (Conf['Linkify']) {
|
||||
for (_j = 0, _len1 = links.length; _j < _len1; _j++) {
|
||||
range = links[_j];
|
||||
this.nodes.links.push(Linkify.makeLink(range));
|
||||
}
|
||||
}
|
||||
if (!(Conf['Embedding'] || Conf['Link Title'])) {
|
||||
return;
|
||||
}
|
||||
_ref1 = this.nodes.links || links;
|
||||
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
|
||||
range = _ref1[_k];
|
||||
if (link = Linkify.services(range)) {
|
||||
if (Conf['Embedding']) {
|
||||
Linkify.embed(link);
|
||||
}
|
||||
if (Conf['Link Title']) {
|
||||
Linkify.title(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
toggle: function() {
|
||||
var el, embed, style, type, url;
|
||||
gatherLinks: function(match, node) {
|
||||
var data, i, len, len2, link, links, next, range, result;
|
||||
|
||||
links = [];
|
||||
i = 0;
|
||||
len = match.length;
|
||||
data = node.data;
|
||||
while ((link = match[i++]) && i > len) {
|
||||
range = document.createRange();
|
||||
range.setStart(node, len2 = data.indexOf(link));
|
||||
range.setEnd(node, len2 + link.length);
|
||||
links.push(range);
|
||||
}
|
||||
range = document.createRange();
|
||||
range.setStart(node, len = data.indexOf(link));
|
||||
if ((data.length - (len += link.length)) > 0) {
|
||||
range.setEnd(node, len);
|
||||
links.push(range);
|
||||
return links;
|
||||
}
|
||||
while ((next = node.nextSibling) && next.nodeName.toLowerCase() !== 'br') {
|
||||
node = next;
|
||||
data = node.data;
|
||||
if (result = /[\s'"]/.exec(data)) {
|
||||
range.setEnd(node, result.index);
|
||||
}
|
||||
}
|
||||
if (range.collapsed) {
|
||||
if (node.nodeName.toLowerCase() === 'wbr') {
|
||||
node = node.previousSibling;
|
||||
}
|
||||
range.setEnd(node, node.length);
|
||||
}
|
||||
links.push(range);
|
||||
return links;
|
||||
},
|
||||
makeLink: function(range) {
|
||||
var a, link;
|
||||
|
||||
link = range.toString();
|
||||
link = link.contains(':') ? link : (link.contains('@') ? 'mailto:' : 'http://') + link;
|
||||
a = $.el('a', {
|
||||
className: 'linkify',
|
||||
rel: 'nofollow noreferrer',
|
||||
target: '_blank',
|
||||
href: link
|
||||
});
|
||||
range.surroundContents(a);
|
||||
return a;
|
||||
},
|
||||
services: function(link) {
|
||||
var href, key, match, type, _ref;
|
||||
|
||||
href = Conf['Linkify'] ? link.href : link.toString();
|
||||
_ref = Linkify.types;
|
||||
for (key in _ref) {
|
||||
type = _ref[key];
|
||||
if (!(match = type.regExp.exec(href))) {
|
||||
continue;
|
||||
}
|
||||
if (!Conf['Linkify']) {
|
||||
link = Linkify.makeLink(link);
|
||||
}
|
||||
return [key, match[1], match[2], link];
|
||||
}
|
||||
},
|
||||
embed: function(data) {
|
||||
var embed, key, link, options, uid;
|
||||
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3];
|
||||
embed = $.el('a', {
|
||||
name: uid,
|
||||
option: options,
|
||||
className: 'embedder',
|
||||
href: 'javascript:;',
|
||||
textContent: '(embed)'
|
||||
});
|
||||
embed.dataset.service = key;
|
||||
embed.dataset.originalurl = link.href;
|
||||
$.addClass(link, "" + embed.dataset.service);
|
||||
$.on(embed, 'click', Linkify.cb.toggle);
|
||||
return $.after(link, [$.tn(' '), embed]);
|
||||
},
|
||||
cb: {
|
||||
toggle: function() {
|
||||
var el, embed;
|
||||
|
||||
embed = this.previousElementSibling;
|
||||
el = !this.className.contains("embedded") ? Linkify.cb.embed(this) : Linkify.cb.unembed(this);
|
||||
$.replace(embed, el);
|
||||
return $.toggleClass(this, 'embedded');
|
||||
},
|
||||
embed: function(a) {
|
||||
var el, style, type;
|
||||
|
||||
el = (type = Linkify.types[a.dataset.service]).el.call(a);
|
||||
el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px";
|
||||
a.textContent = '(unembed)';
|
||||
return el;
|
||||
},
|
||||
unembed: function(a) {
|
||||
var el, url;
|
||||
|
||||
embed = this.previousElementSibling;
|
||||
if (this.className.contains("embedded")) {
|
||||
el = $.el('a', {
|
||||
rel: 'nofollow noreferrer',
|
||||
target: 'blank',
|
||||
className: 'linkify',
|
||||
href: url = this.getAttribute("data-originalURL"),
|
||||
textContent: this.getAttribute("data-title") || url
|
||||
href: url = a.dataset.originalurl,
|
||||
textContent: a.dataset.title || url
|
||||
});
|
||||
this.textContent = '(embed)';
|
||||
$.addClass(el, "" + (this.getAttribute('data-service')));
|
||||
} else {
|
||||
el = (type = Linkify.types[this.getAttribute("data-service")]).el.call(this);
|
||||
el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px";
|
||||
this.textContent = '(unembed)';
|
||||
a.textContent = '(embed)';
|
||||
$.addClass(el, "" + a.dataset.service);
|
||||
return el;
|
||||
},
|
||||
title: function(data) {
|
||||
var key, link, options, service, text, uid;
|
||||
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3];
|
||||
service = Linkify.types[key].title;
|
||||
return link.textContent = (function() {
|
||||
switch (this.status) {
|
||||
case 200:
|
||||
case 304:
|
||||
text = "" + (service.text.call(this));
|
||||
if (Conf['Embedding']) {
|
||||
link.nextElementSibling.dataset.title = text;
|
||||
}
|
||||
return text;
|
||||
case 404:
|
||||
return "[" + key + "] Not Found";
|
||||
case 403:
|
||||
return "[" + key + "] Forbidden or Private";
|
||||
default:
|
||||
return "[" + key + "] " + this.status + "'d";
|
||||
}
|
||||
}).call(this);
|
||||
}
|
||||
$.replace(embed, el);
|
||||
return $.toggleClass(this, 'embedded');
|
||||
},
|
||||
title: function(data) {
|
||||
var key, link, options, service, title, titles, uid;
|
||||
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3];
|
||||
titles = {};
|
||||
service = Linkify.types[key].title;
|
||||
title = "";
|
||||
return $.get('CachedTitles', {}, function(item) {
|
||||
var err;
|
||||
|
||||
titles = item['CachedTitles'];
|
||||
if (title = titles[uid]) {
|
||||
link.textContent = title[0];
|
||||
if (Conf['Embedding']) {
|
||||
link.nextElementSibling.dataset.title = title[0];
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$.cache(service.api(uid), function() {
|
||||
return title = Linkify.cb.title.apply(this, [data]);
|
||||
});
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
link.innerHTML = "[" + key + "] <span class=warning>Title Link Blocked</span> (are you using NoScript?)</a>";
|
||||
return;
|
||||
}
|
||||
if (title) {
|
||||
titles[uid] = [title, Date.now()];
|
||||
return $.set('CachedTitles', titles);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
types: {
|
||||
YouTube: {
|
||||
@ -6722,8 +6830,8 @@
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function() {
|
||||
return "https://gdata.youtube.com/feeds/api/videos/" + this.name + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode";
|
||||
api: function(uid) {
|
||||
return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode";
|
||||
},
|
||||
text: function() {
|
||||
return JSON.parse(this.responseText).entry.title.$t;
|
||||
@ -6747,8 +6855,8 @@
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function() {
|
||||
return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + this.name;
|
||||
api: function(uid) {
|
||||
return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
|
||||
},
|
||||
text: function() {
|
||||
return JSON.parse(this.responseText).title;
|
||||
@ -6778,7 +6886,7 @@
|
||||
style: 'border: 0; width: auto; height: auto;',
|
||||
el: function() {
|
||||
return $.el('div', {
|
||||
innerHTML: "<a target=_blank href='" + (this.getAttribute('data-originalURL')) + "'><img src='" + (this.getAttribute('data-originalURL')) + "'></a>"
|
||||
innerHTML: "<a target=_blank href='" + this.dataset.originalurl + "'><img src='" + this.dataset.originalurl + "'></a>"
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -6801,8 +6909,8 @@
|
||||
return div;
|
||||
},
|
||||
title: {
|
||||
api: function() {
|
||||
return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + this.name;
|
||||
api: function(uid) {
|
||||
return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid;
|
||||
},
|
||||
text: function() {
|
||||
return JSON.parse(this.responseText).title;
|
||||
@ -6829,8 +6937,8 @@
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function() {
|
||||
return "https://api.github.com/gists/" + this.name;
|
||||
api: function(uid) {
|
||||
return "https://api.github.com/gists/" + uid;
|
||||
},
|
||||
text: function() {
|
||||
var file, response;
|
||||
@ -6852,76 +6960,6 @@
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
embedder: function(a) {
|
||||
var callbacks, embed, key, match, service, titles, type, _ref;
|
||||
|
||||
if (!Conf['Link Title']) {
|
||||
return [a];
|
||||
}
|
||||
titles = {};
|
||||
callbacks = function() {
|
||||
var title;
|
||||
|
||||
return a.textContent = (function() {
|
||||
switch (this.status) {
|
||||
case 200:
|
||||
case 304:
|
||||
title = "" + (service.text.call(this));
|
||||
embed.setAttribute('data-title', title);
|
||||
titles[embed.name] = [title, Date.now()];
|
||||
$.set('CachedTitles', titles);
|
||||
return title;
|
||||
case 404:
|
||||
return "[" + key + "] Not Found";
|
||||
case 403:
|
||||
return "[" + key + "] Forbidden or Private";
|
||||
default:
|
||||
return "[" + key + "] " + this.status + "'d";
|
||||
}
|
||||
}).call(this);
|
||||
};
|
||||
_ref = Linkify.types;
|
||||
for (key in _ref) {
|
||||
type = _ref[key];
|
||||
if (!(match = a.href.match(type.regExp))) {
|
||||
continue;
|
||||
}
|
||||
embed = $.el('a', {
|
||||
name: (a.name = match[1]),
|
||||
option: match[2],
|
||||
className: 'embedder',
|
||||
href: 'javascript:;',
|
||||
textContent: '(embed)'
|
||||
});
|
||||
embed.setAttribute('data-service', key);
|
||||
embed.setAttribute('data-originalURL', a.href);
|
||||
$.addClass(a, "" + (embed.getAttribute('data-service')));
|
||||
$.on(embed, 'click', Linkify.toggle);
|
||||
if (!Conf['Embedding']) {
|
||||
embed.hidden = true;
|
||||
}
|
||||
if (Conf['Link Title'] && (service = type.title)) {
|
||||
$.get('CachedTitles', {}, function(item) {
|
||||
var err, title;
|
||||
|
||||
titles = item['CachedTitles'];
|
||||
if (title = titles[match[1]]) {
|
||||
a.textContent = title[0];
|
||||
return embed.setAttribute('data-title', title[0]);
|
||||
} else {
|
||||
try {
|
||||
return $.cache(service.api.call(a), callbacks);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return a.innerHTML = "[" + key + "] <span class=warning>Title Link Blocked</span> (are you using NoScript?)</a>";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return [a, $.tn(' '), embed];
|
||||
}
|
||||
return [a];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ class Post
|
||||
post: post
|
||||
info: info
|
||||
comment: $ '.postMessage', post
|
||||
links: []
|
||||
quotelinks: []
|
||||
backlinks: info.getElementsByClassName 'backlink'
|
||||
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
Linkify =
|
||||
init: ->
|
||||
return if g.VIEW is 'catalog' or not Conf['Linkify']
|
||||
return if g.VIEW is 'catalog'
|
||||
|
||||
@regString = if Conf['Allow False Positives']
|
||||
@regString = if Conf['Allow False Positives']
|
||||
///(
|
||||
\b(
|
||||
[a-z]+://
|
||||
|
|
||||
[a-z]{3,}\.[-a-z0-9]+\.[a-z]+
|
||||
[a-z]{3,}\.[-a-z0-9]+\.[a-z]
|
||||
|
|
||||
[-a-z0-9]+\.[a-z]
|
||||
|
|
||||
[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+
|
||||
[0-9]+\.[0-9]+\.[0-9]+\.[0-9]
|
||||
|
|
||||
[a-z]{3,}:[a-z0-9?]
|
||||
|
|
||||
[a-z0-9._%+-:]+@[a-z0-9.-]+\.[a-z0-9]
|
||||
[\S]+@[a-z0-9.-]+\.[a-z0-9]
|
||||
)
|
||||
[^\s'"]+
|
||||
)///gi
|
||||
@ -29,122 +29,205 @@ Linkify =
|
||||
name: 'Linkify'
|
||||
cb: @node
|
||||
|
||||
cypher: $.el 'div'
|
||||
|
||||
node: ->
|
||||
if @isClone and Conf['Embedding']
|
||||
for embedder in $$ '.embedder', @nodes.comment
|
||||
$.on embedder, "click", Linkify.toggle
|
||||
$.on embedder, "click", Linkify.cb.toggle
|
||||
return
|
||||
|
||||
snapshot = $.X './/text()', @nodes.comment
|
||||
cypher = Linkify.cypher
|
||||
i = -1
|
||||
len = snapshot.snapshotLength
|
||||
links = []
|
||||
|
||||
while ++i < len
|
||||
nodes = $.frag()
|
||||
node = snapshot.snapshotItem i
|
||||
data = node.data
|
||||
node = snapshot.snapshotItem i
|
||||
data = node.data
|
||||
|
||||
# Test for valid links
|
||||
if match = data.match Linkify.regString
|
||||
links.pushArrays Linkify.gatherLinks match, node
|
||||
|
||||
continue unless node.parentNode and Linkify.regString.test data
|
||||
if Conf['Linkify']
|
||||
for range in links
|
||||
@nodes.links.push Linkify.makeLink range
|
||||
|
||||
Linkify.regString.lastIndex = 0
|
||||
return unless Conf['Embedding'] or Conf['Link Title']
|
||||
|
||||
for range in @nodes.links or links
|
||||
if link = Linkify.services range
|
||||
if Conf['Embedding']
|
||||
Linkify.embed link
|
||||
if Conf['Link Title']
|
||||
Linkify.title link
|
||||
|
||||
cypherText = []
|
||||
|
||||
if next = node.nextSibling
|
||||
cypher.textContent = node.textContent
|
||||
cypherText[0] = cypher.innerHTML
|
||||
|
||||
while (next.nodeName.toLowerCase() is 'wbr' or next.nodeName.toLowerCase() is 's') and (lookahead = next.nextSibling) and ((name = lookahead.nodeName) is "#text" or name.toLowerCase() is 'br')
|
||||
cypher.textContent = lookahead.textContent
|
||||
|
||||
cypherText.push if spoiler = next.innerHTML then "<s>#{spoiler.replace /</g, ' <'}</s>" else '<wbr>'
|
||||
cypherText.push cypher.innerHTML
|
||||
|
||||
$.rm next
|
||||
next = lookahead.nextSibling
|
||||
$.rm lookahead if lookahead.nodeName is "#text"
|
||||
|
||||
unless next
|
||||
break
|
||||
|
||||
if cypherText.length
|
||||
data = cypherText.join ''
|
||||
|
||||
links = data.match Linkify.regString
|
||||
|
||||
for link in links
|
||||
index = data.indexOf link
|
||||
|
||||
if text = data[...index]
|
||||
# press button get bacon
|
||||
cypher.innerHTML = text
|
||||
for child in [cypher.childNodes...]
|
||||
$.add nodes, child
|
||||
|
||||
cypher.innerHTML = (if link.indexOf(':') < 0 then (if link.indexOf('@') > 0 then 'mailto:' + link else 'http://' + link) else link).replace /<(wbr|s|\/s)>/g, ''
|
||||
|
||||
a = $.el 'a',
|
||||
innerHTML: link
|
||||
className: 'linkify'
|
||||
rel: 'nofollow noreferrer'
|
||||
target: '_blank'
|
||||
href: cypher.textContent
|
||||
|
||||
$.add nodes, Linkify.embedder a
|
||||
|
||||
data = data[index + link.length..]
|
||||
|
||||
if data
|
||||
# Potential text after the last valid link.
|
||||
cypher.innerHTML = data
|
||||
|
||||
# Convert <wbr> into elements
|
||||
for child in [cypher.childNodes...]
|
||||
$.add nodes, child
|
||||
|
||||
$.replace node, nodes
|
||||
|
||||
if Conf['Auto-embed']
|
||||
embeds = $$ '.embedder', @nodes.comment
|
||||
for embed in embeds
|
||||
embed.click()
|
||||
return
|
||||
|
||||
toggle: ->
|
||||
# We setup the link to be replaced by the embedded video
|
||||
embed = @previousElementSibling
|
||||
gatherLinks: (match, node) ->
|
||||
links = []
|
||||
i = 0
|
||||
len = match.length
|
||||
data = node.data
|
||||
|
||||
# Unembed.
|
||||
if @className.contains "embedded"
|
||||
# Recreate the original link.
|
||||
el = $.el 'a',
|
||||
rel: 'nofollow noreferrer'
|
||||
target: 'blank'
|
||||
className: 'linkify'
|
||||
href: url = @getAttribute("data-originalURL")
|
||||
textContent: @getAttribute("data-title") or url
|
||||
while (link = match[i++]) and i > len
|
||||
range = document.createRange();
|
||||
range.setStart node, len2 = data.indexOf link
|
||||
range.setEnd node, len2 + link.length
|
||||
links.push range
|
||||
|
||||
@textContent = '(embed)'
|
||||
$.addClass el, "#{@getAttribute 'data-service'}"
|
||||
range = document.createRange()
|
||||
range.setStart node, len = data.indexOf link
|
||||
|
||||
if (data.length - (len += link.length)) > 0
|
||||
range.setEnd node, len
|
||||
links.push range
|
||||
return links
|
||||
|
||||
while (next = node.nextSibling) and next.nodeName.toLowerCase() isnt 'br'
|
||||
node = next
|
||||
data = node.data
|
||||
if result = /[\s'"]/.exec data
|
||||
range.setEnd node, result.index
|
||||
|
||||
if range.collapsed
|
||||
if node.nodeName.toLowerCase() is 'wbr'
|
||||
node = node.previousSibling
|
||||
range.setEnd node, node.length
|
||||
|
||||
links.push range
|
||||
return links
|
||||
|
||||
makeLink: (range) ->
|
||||
link = range.toString()
|
||||
link =
|
||||
if link.contains ':'
|
||||
link
|
||||
else (
|
||||
if link.contains '@'
|
||||
'mailto:'
|
||||
else
|
||||
'http://'
|
||||
) + link
|
||||
|
||||
a = $.el 'a',
|
||||
className: 'linkify'
|
||||
rel: 'nofollow noreferrer'
|
||||
target: '_blank'
|
||||
href: link
|
||||
|
||||
range.surroundContents a
|
||||
return a
|
||||
|
||||
services: (link) ->
|
||||
href = if Conf['Linkify']
|
||||
link.href
|
||||
else
|
||||
# We create an element to embed
|
||||
el = (type = Linkify.types[@getAttribute("data-service")]).el.call @
|
||||
link.toString()
|
||||
|
||||
for key, type of Linkify.types
|
||||
continue unless match = type.regExp.exec href
|
||||
link = Linkify.makeLink link unless Conf['Linkify']
|
||||
return [key, match[1], match[2], link]
|
||||
|
||||
return
|
||||
|
||||
embed: (data) ->
|
||||
[key, uid, options, link] = data
|
||||
embed = $.el 'a',
|
||||
name: uid
|
||||
option: options
|
||||
className: 'embedder'
|
||||
href: 'javascript:;'
|
||||
textContent: '(embed)'
|
||||
|
||||
embed.dataset.service = key
|
||||
embed.dataset.originalurl = link.href
|
||||
|
||||
$.addClass link, "#{embed.dataset.service}"
|
||||
|
||||
$.on embed, 'click', Linkify.cb.toggle
|
||||
$.after link, [$.tn(' '), embed]
|
||||
|
||||
cb:
|
||||
toggle: ->
|
||||
# We setup the link to be replaced by the embedded video
|
||||
embed = @previousElementSibling
|
||||
|
||||
# Unembed.
|
||||
el = unless @className.contains "embedded"
|
||||
Linkify.cb.embed @
|
||||
else
|
||||
Linkify.cb.unembed @
|
||||
|
||||
$.replace embed, el
|
||||
$.toggleClass @, 'embedded'
|
||||
|
||||
embed: (a) ->
|
||||
# We create an element to embed
|
||||
el = (type = Linkify.types[a.dataset.service]).el.call a
|
||||
|
||||
# Set style values.
|
||||
el.style.cssText = if style = type.style
|
||||
style
|
||||
else
|
||||
"border: 0; width: 640px; height: 390px"
|
||||
|
||||
a.textContent = '(unembed)'
|
||||
|
||||
@textContent = '(unembed)'
|
||||
return el
|
||||
|
||||
unembed: (a) ->
|
||||
# Recreate the original link.
|
||||
el = $.el 'a',
|
||||
rel: 'nofollow noreferrer'
|
||||
target: 'blank'
|
||||
className: 'linkify'
|
||||
href: url = a.dataset.originalurl
|
||||
textContent: a.dataset.title or url
|
||||
|
||||
a.textContent = '(embed)'
|
||||
$.addClass el, "#{a.dataset.service}"
|
||||
|
||||
return el
|
||||
|
||||
$.replace embed, el
|
||||
$.toggleClass @, 'embedded'
|
||||
title: (data) ->
|
||||
[key, uid, options, link] = data
|
||||
service = Linkify.types[key].title
|
||||
link.textContent = switch @status
|
||||
when 200, 304
|
||||
text = "#{service.text.call @}"
|
||||
if Conf['Embedding']
|
||||
link.nextElementSibling.dataset.title = text
|
||||
text
|
||||
when 404
|
||||
"[#{key}] Not Found"
|
||||
when 403
|
||||
"[#{key}] Forbidden or Private"
|
||||
else
|
||||
"[#{key}] #{@status}'d"
|
||||
|
||||
title: (data) ->
|
||||
[key, uid, options, link] = data
|
||||
titles = {}
|
||||
service = Linkify.types[key].title
|
||||
title = ""
|
||||
|
||||
$.get 'CachedTitles', {}, (item) ->
|
||||
titles = item['CachedTitles']
|
||||
if title = titles[uid]
|
||||
link.textContent = title[0]
|
||||
if Conf['Embedding']
|
||||
link.nextElementSibling.dataset.title = title[0]
|
||||
return
|
||||
else
|
||||
try
|
||||
$.cache service.api(uid), ->
|
||||
title = Linkify.cb.title.apply @, [data]
|
||||
catch err
|
||||
link.innerHTML = "[#{key}] <span class=warning>Title Link Blocked</span> (are you using NoScript?)</a>"
|
||||
return
|
||||
if title
|
||||
titles[uid] = [title, Date.now()]
|
||||
$.set 'CachedTitles', titles
|
||||
|
||||
types:
|
||||
YouTube:
|
||||
@ -153,7 +236,7 @@ Linkify =
|
||||
$.el 'iframe',
|
||||
src: "//www.youtube.com/embed/#{@name}#{if @option then '#' + @option else ''}?wmode=opaque"
|
||||
title:
|
||||
api: -> "https://gdata.youtube.com/feeds/api/videos/#{@name}?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"
|
||||
api: (uid) -> "https://gdata.youtube.com/feeds/api/videos/#{uid}?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"
|
||||
text: -> JSON.parse(@responseText).entry.title.$t
|
||||
|
||||
Vocaroo:
|
||||
@ -169,7 +252,7 @@ Linkify =
|
||||
$.el 'iframe',
|
||||
src: "//player.vimeo.com/video/#{@name}?wmode=opaque"
|
||||
title:
|
||||
api: -> "https://vimeo.com/api/oembed.json?url=http://vimeo.com/#{@name}"
|
||||
api: (uid) -> "https://vimeo.com/api/oembed.json?url=http://vimeo.com/#{uid}"
|
||||
text: -> JSON.parse(@responseText).title
|
||||
|
||||
LiveLeak:
|
||||
@ -191,7 +274,7 @@ Linkify =
|
||||
style: 'border: 0; width: auto; height: auto;'
|
||||
el: ->
|
||||
$.el 'div',
|
||||
innerHTML: "<a target=_blank href='#{@getAttribute 'data-originalURL'}'><img src='#{@getAttribute 'data-originalURL'}'></a>"
|
||||
innerHTML: "<a target=_blank href='#{@dataset.originalurl}'><img src='#{@dataset.originalurl}'></a>"
|
||||
|
||||
SoundCloud:
|
||||
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
|
||||
@ -208,7 +291,7 @@ Linkify =
|
||||
false)
|
||||
div
|
||||
title:
|
||||
api: -> "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{@name}"
|
||||
api: (uid) -> "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{uid}"
|
||||
text: -> JSON.parse(@responseText).title
|
||||
|
||||
pastebin:
|
||||
@ -224,7 +307,7 @@ Linkify =
|
||||
# Github doesn't allow embedding straight from the site, so we use an external site to bypass that.
|
||||
src: "http://www.purplegene.com/script?url=https://gist.github.com/#{@name}.js"
|
||||
title:
|
||||
api: -> "https://api.github.com/gists/#{@name}"
|
||||
api: (uid) -> "https://api.github.com/gists/#{uid}"
|
||||
text: ->
|
||||
response = JSON.parse(@responseText).files
|
||||
return file for file of response when response.hasOwnProperty file
|
||||
@ -233,57 +316,4 @@ Linkify =
|
||||
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/
|
||||
el: ->
|
||||
$.el 'iframe',
|
||||
src: "http://paste.installgentoo.com/view/embed/#{@name}"
|
||||
|
||||
embedder: (a) ->
|
||||
return [a] unless Conf['Link Title']
|
||||
titles = {}
|
||||
|
||||
callbacks = ->
|
||||
a.textContent = switch @status
|
||||
when 200, 304
|
||||
title = "#{service.text.call @}"
|
||||
embed.setAttribute 'data-title', title
|
||||
titles[embed.name] = [title, Date.now()]
|
||||
$.set 'CachedTitles', titles
|
||||
title
|
||||
when 404
|
||||
"[#{key}] Not Found"
|
||||
when 403
|
||||
"[#{key}] Forbidden or Private"
|
||||
else
|
||||
"[#{key}] #{@status}'d"
|
||||
|
||||
for key, type of Linkify.types
|
||||
continue unless match = a.href.match type.regExp
|
||||
|
||||
embed = $.el 'a',
|
||||
name: (a.name = match[1])
|
||||
option: match[2]
|
||||
className: 'embedder'
|
||||
href: 'javascript:;'
|
||||
textContent: '(embed)'
|
||||
|
||||
embed.setAttribute 'data-service', key
|
||||
embed.setAttribute 'data-originalURL', a.href
|
||||
$.addClass a, "#{embed.getAttribute 'data-service'}"
|
||||
|
||||
$.on embed, 'click', Linkify.toggle
|
||||
|
||||
unless Conf['Embedding']
|
||||
embed.hidden = true
|
||||
|
||||
if Conf['Link Title'] and (service = type.title)
|
||||
$.get 'CachedTitles', {}, (item) ->
|
||||
titles = item['CachedTitles']
|
||||
if title = titles[match[1]]
|
||||
a.textContent = title[0]
|
||||
embed.setAttribute 'data-title', title[0]
|
||||
else
|
||||
try
|
||||
$.cache service.api.call(a), callbacks
|
||||
catch err
|
||||
a.innerHTML = "[#{key}] <span class=warning>Title Link Blocked</span> (are you using NoScript?)</a>"
|
||||
|
||||
return [a, $.tn(' '), embed]
|
||||
return [a]
|
||||
src: "http://paste.installgentoo.com/view/embed/#{@name}"
|
||||
Loading…
x
Reference in New Issue
Block a user