compile after merge
This commit is contained in:
parent
fd703d42ba
commit
3583ffaefd
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 4chan X - Version 1.4.1 - 2014-03-31
|
||||
* 4chan X - Version 1.4.1 - 2014-04-02
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/Spittie/4chan-x/blob/master/LICENSE
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
// ==/UserScript==
|
||||
|
||||
/*
|
||||
* 4chan X - Version 1.4.1 - 2014-03-31
|
||||
* 4chan X - Version 1.4.1 - 2014-04-02
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/Spittie/4chan-x/blob/master/LICENSE
|
||||
@ -6319,6 +6319,10 @@
|
||||
onload: QR.response,
|
||||
onerror: function(err, url, line) {
|
||||
delete QR.req;
|
||||
if (QR.captcha.isEnabled) {
|
||||
QR.captcha.destroy();
|
||||
QR.captcha.setup();
|
||||
}
|
||||
post.unlock();
|
||||
QR.cooldown.auto = false;
|
||||
QR.status();
|
||||
@ -6351,9 +6355,12 @@
|
||||
return QR.status();
|
||||
},
|
||||
response: function() {
|
||||
var URL, ban, board, captchasCount, err, h1, isReply, m, notif, post, postID, postsCount, req, resDoc, threadID, _, _ref, _ref1;
|
||||
var URL, ban, board, err, h1, isReply, m, post, postID, postsCount, req, resDoc, threadID, _, _ref, _ref1;
|
||||
req = QR.req;
|
||||
delete QR.req;
|
||||
if (QR.captcha.isEnabled) {
|
||||
QR.captcha.destroy();
|
||||
}
|
||||
post = QR.posts[0];
|
||||
post.unlock();
|
||||
resDoc = req.response;
|
||||
@ -6378,12 +6385,12 @@
|
||||
} else if (/expired/i.test(err.textContent)) {
|
||||
err = 'This CAPTCHA is no longer valid because it has expired.';
|
||||
}
|
||||
QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : err === 'Connection error with sys.4chan.org.' ? true : false;
|
||||
QR.cooldown.auto = false;
|
||||
QR.cooldown.set({
|
||||
delay: 2
|
||||
});
|
||||
} else if (err.textContent && (m = err.textContent.match(/wait\s+(\d+)\s+second/i))) {
|
||||
QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : true;
|
||||
QR.cooldown.auto = !QR.captcha.isEnabled;
|
||||
QR.cooldown.set({
|
||||
delay: m[1]
|
||||
});
|
||||
@ -6422,22 +6429,6 @@
|
||||
});
|
||||
postsCount = QR.posts.length - 1;
|
||||
QR.cooldown.auto = postsCount && isReply;
|
||||
if (QR.cooldown.auto && QR.captcha.isEnabled && (captchasCount = QR.captcha.captchas.length) < 3 && captchasCount < postsCount) {
|
||||
notif = new Notification('Quick reply warning', {
|
||||
body: "You are running low on cached captchas. Cache count: " + captchasCount + ".",
|
||||
icon: Favicon.logo
|
||||
});
|
||||
notif.onclick = function() {
|
||||
QR.open();
|
||||
QR.captcha.nodes.input.focus();
|
||||
return window.focus();
|
||||
};
|
||||
notif.onshow = function() {
|
||||
return setTimeout(function() {
|
||||
return notif.close();
|
||||
}, 7 * $.SECOND);
|
||||
};
|
||||
}
|
||||
if (!(Conf['Persistent QR'] || QR.cooldown.auto)) {
|
||||
QR.close();
|
||||
} else {
|
||||
@ -6473,12 +6464,11 @@
|
||||
|
||||
QR.captcha = {
|
||||
init: function() {
|
||||
var container, imgContainer, input;
|
||||
var imgContainer, input;
|
||||
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
|
||||
return;
|
||||
}
|
||||
container = $.id('captchaContainer');
|
||||
if (!(this.isEnabled = !!container)) {
|
||||
if (!(this.isEnabled = !!$.id('captchaContainer'))) {
|
||||
return;
|
||||
}
|
||||
if (Conf['Auto-load captcha']) {
|
||||
@ -6487,13 +6477,11 @@
|
||||
imgContainer = $.el('div', {
|
||||
className: 'captcha-img',
|
||||
title: 'Reload reCAPTCHA',
|
||||
innerHTML: '<img>',
|
||||
hidden: true
|
||||
innerHTML: '<img>'
|
||||
});
|
||||
input = $.el('input', {
|
||||
className: 'captcha-input field',
|
||||
title: 'Verification',
|
||||
placeholder: 'Focus to load reCAPTCHA',
|
||||
autocomplete: 'off',
|
||||
spellcheck: false,
|
||||
tabIndex: 45
|
||||
@ -6502,44 +6490,41 @@
|
||||
img: imgContainer.firstChild,
|
||||
input: input
|
||||
};
|
||||
$.on(input, 'focus', this.setup);
|
||||
$.on(input, 'blur', QR.focusout);
|
||||
$.on(input, 'focus', QR.focusin);
|
||||
$.addClass(QR.nodes.el, 'has-captcha');
|
||||
$.after(QR.nodes.com.parentNode, [imgContainer, input]);
|
||||
this.beforeSetup();
|
||||
return this.afterSetup();
|
||||
},
|
||||
beforeSetup: function() {
|
||||
var img, input, _ref;
|
||||
_ref = this.nodes, img = _ref.img, input = _ref.input;
|
||||
img.parentNode.hidden = true;
|
||||
input.value = '';
|
||||
input.placeholder = 'Focus to load reCAPTCHA';
|
||||
$.on(input, 'focus', this.setup);
|
||||
this.setupObserver = new MutationObserver(this.afterSetup);
|
||||
this.setupObserver.observe(container, {
|
||||
return this.setupObserver.observe($.id('captchaContainer'), {
|
||||
childList: true
|
||||
});
|
||||
return this.afterSetup();
|
||||
},
|
||||
setup: function() {
|
||||
return $.globalEval('loadRecaptcha()');
|
||||
},
|
||||
afterSetup: function() {
|
||||
var challenge, img, input, setLifetime, _ref;
|
||||
var challenge, img, input, _ref;
|
||||
if (!(challenge = $.id('recaptcha_challenge_field_holder'))) {
|
||||
return;
|
||||
}
|
||||
QR.captcha.setupObserver.disconnect();
|
||||
delete QR.captcha.setupObserver;
|
||||
setLifetime = function(e) {
|
||||
return QR.captcha.lifetime = e.detail;
|
||||
};
|
||||
$.on(window, 'captcha:timeout', setLifetime);
|
||||
$.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))');
|
||||
$.off(window, 'captcha:timeout', setLifetime);
|
||||
_ref = QR.captcha.nodes, img = _ref.img, input = _ref.input;
|
||||
img.parentNode.hidden = false;
|
||||
input.placeholder = 'Verification';
|
||||
$.off(input, 'focus', QR.captcha.setup);
|
||||
$.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha));
|
||||
$.on(img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha));
|
||||
$.get('captchas', [], function(_arg) {
|
||||
var captchas;
|
||||
captchas = _arg.captchas;
|
||||
return QR.captcha.sync(captchas);
|
||||
});
|
||||
$.sync('captchas', QR.captcha.sync);
|
||||
QR.captcha.nodes.challenge = challenge;
|
||||
new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
|
||||
childList: true,
|
||||
@ -6548,94 +6533,31 @@
|
||||
});
|
||||
return QR.captcha.load();
|
||||
},
|
||||
sync: function(captchas) {
|
||||
QR.captcha.captchas = captchas;
|
||||
return QR.captcha.count();
|
||||
destroy: function() {
|
||||
$.globalEval('Recaptcha.destroy()');
|
||||
return this.beforeSetup();
|
||||
},
|
||||
getOne: function() {
|
||||
var captcha, challenge, response;
|
||||
this.clear();
|
||||
if (captcha = this.captchas.shift()) {
|
||||
challenge = captcha.challenge, response = captcha.response;
|
||||
this.count();
|
||||
$.set('captchas', this.captchas);
|
||||
} else {
|
||||
challenge = this.nodes.img.alt;
|
||||
if (response = this.nodes.input.value) {
|
||||
this.reload();
|
||||
}
|
||||
}
|
||||
if (response) {
|
||||
response = response.trim();
|
||||
if (!/\s/.test(response)) {
|
||||
response = "" + response + " " + response;
|
||||
}
|
||||
var challenge, response;
|
||||
challenge = this.nodes.img.alt;
|
||||
response = this.nodes.input.value.trim();
|
||||
if (response && !/\s/.test(response)) {
|
||||
response = "" + response + " " + response;
|
||||
}
|
||||
return {
|
||||
challenge: challenge,
|
||||
response: response
|
||||
};
|
||||
},
|
||||
save: function() {
|
||||
var response;
|
||||
if (!(response = this.nodes.input.value.trim())) {
|
||||
return;
|
||||
}
|
||||
this.captchas.push({
|
||||
challenge: this.nodes.img.alt,
|
||||
response: response,
|
||||
timeout: this.timeout
|
||||
});
|
||||
this.count();
|
||||
this.reload();
|
||||
return $.set('captchas', this.captchas);
|
||||
},
|
||||
clear: function() {
|
||||
var captcha, i, now, _i, _len, _ref;
|
||||
if (!this.captchas.length) {
|
||||
return;
|
||||
}
|
||||
now = Date.now();
|
||||
_ref = this.captchas;
|
||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||
captcha = _ref[i];
|
||||
if (captcha.timeout > now) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!i) {
|
||||
return;
|
||||
}
|
||||
this.captchas = this.captchas.slice(i);
|
||||
this.count();
|
||||
return $.set('captchas', this.captchas);
|
||||
},
|
||||
load: function() {
|
||||
var challenge;
|
||||
if (!this.nodes.challenge.firstChild) {
|
||||
return;
|
||||
}
|
||||
this.timeout = Date.now() + this.lifetime * $.SECOND - $.MINUTE;
|
||||
challenge = this.nodes.challenge.firstChild.value;
|
||||
this.nodes.img.alt = challenge;
|
||||
this.nodes.img.src = "//www.google.com/recaptcha/api/image?c=" + challenge;
|
||||
this.nodes.input.value = null;
|
||||
return this.clear();
|
||||
},
|
||||
count: function() {
|
||||
var count;
|
||||
count = this.captchas ? this.captchas.length : 0;
|
||||
this.nodes.input.placeholder = (function() {
|
||||
switch (count) {
|
||||
case 0:
|
||||
return 'Verification (Shift + Enter to cache)';
|
||||
case 1:
|
||||
return 'Verification (1 cached captcha)';
|
||||
default:
|
||||
return "Verification (" + count + " cached captchas)";
|
||||
}
|
||||
})();
|
||||
return this.nodes.input.alt = count;
|
||||
return this.nodes.input.value = null;
|
||||
},
|
||||
reload: function(focus) {
|
||||
$.globalEval('Recaptcha.reload("t")');
|
||||
@ -6646,8 +6568,6 @@
|
||||
keydown: function(e) {
|
||||
if (e.keyCode === 8 && !this.nodes.input.value) {
|
||||
this.reload();
|
||||
} else if (e.keyCode === 13 && e.shiftKey) {
|
||||
this.save();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -6983,6 +6903,9 @@
|
||||
node.disabled = lock;
|
||||
}
|
||||
}
|
||||
if (QR.captcha.isEnabled) {
|
||||
QR.captcha.nodes.input.disabled = lock;
|
||||
}
|
||||
this.nodes.rm.style.visibility = lock ? 'hidden' : '';
|
||||
(lock ? $.off : $.on)(QR.nodes.filename.previousElementSibling, 'click', QR.openFileInput);
|
||||
this.nodes.spoiler.disabled = lock;
|
||||
@ -8647,561 +8570,6 @@
|
||||
]
|
||||
};
|
||||
|
||||
Linkify = {
|
||||
init: function() {
|
||||
var type, _i, _len, _ref;
|
||||
if (g.VIEW === 'catalog' || !Conf['Linkify']) {
|
||||
return;
|
||||
}
|
||||
this.regString = /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/])|[-a-z\d]+[.](aero|asia|biz|cat|com|coop|info|int|jobs|mobi|museum|name|net|org|post|pro|tel|travel|xxx|edu|gov|mil|[a-z]{2})(\/|(?!.))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i;
|
||||
this.types = {};
|
||||
_ref = this.ordered_types;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
type = _ref[_i];
|
||||
this.types[type.key] = type;
|
||||
}
|
||||
if (Conf['Comment Expansion']) {
|
||||
ExpandComment.callbacks.push(this.node);
|
||||
}
|
||||
if (Conf['Title Link']) {
|
||||
$.sync('CachedTitles', Linkify.titleSync);
|
||||
}
|
||||
return Post.callbacks.push({
|
||||
name: 'Linkify',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var data, el, end, endNode, i, index, items, length, link, links, node, result, saved, snapshot, space, test, word, _i, _len, _ref;
|
||||
if (this.isClone) {
|
||||
if (Conf['Embedding']) {
|
||||
i = 0;
|
||||
items = $$('.embed', this.nodes.comment);
|
||||
while (el = items[i++]) {
|
||||
$.on(el, 'click', Linkify.cb.toggle);
|
||||
if ($.hasClass(el, 'embedded')) {
|
||||
Linkify.cb.toggle.call(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
test = /[^\s'"]+/g;
|
||||
space = /[\s'"]/;
|
||||
snapshot = $.X('.//br|.//text()', this.nodes.comment);
|
||||
i = 0;
|
||||
links = [];
|
||||
while (node = snapshot.snapshotItem(i++)) {
|
||||
data = node.data;
|
||||
if (node.parentElement.nodeName === "A" || !data) {
|
||||
continue;
|
||||
}
|
||||
while (result = test.exec(data)) {
|
||||
index = result.index;
|
||||
endNode = node;
|
||||
word = result[0];
|
||||
if ((length = index + word.length) === data.length) {
|
||||
test.lastIndex = 0;
|
||||
while ((saved = snapshot.snapshotItem(i++))) {
|
||||
if (saved.nodeName === 'BR') {
|
||||
break;
|
||||
}
|
||||
endNode = saved;
|
||||
data = saved.data;
|
||||
word += data;
|
||||
length = data.length;
|
||||
if (end = space.exec(data)) {
|
||||
test.lastIndex = length = end.index;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Linkify.regString.exec(word)) {
|
||||
links.push(Linkify.makeRange(node, endNode, index, length));
|
||||
}
|
||||
if (!(test.lastIndex && node === endNode)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ref = links.reverse();
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
link = _ref[_i];
|
||||
this.nodes.links.push(Linkify.makeLink(link, this));
|
||||
link.detach();
|
||||
}
|
||||
if (!(Conf['Embedding'] || Conf['Link Title'])) {
|
||||
return;
|
||||
}
|
||||
links = this.nodes.links;
|
||||
i = 0;
|
||||
while (link = links[i++]) {
|
||||
if (data = Linkify.services(link)) {
|
||||
if (Conf['Embedding']) {
|
||||
Linkify.embed(data);
|
||||
}
|
||||
if (Conf['Link Title']) {
|
||||
Linkify.title(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
makeRange: function(startNode, endNode, startOffset, endOffset) {
|
||||
var range;
|
||||
range = document.createRange();
|
||||
range.setStart(startNode, startOffset);
|
||||
range.setEnd(endNode, endOffset);
|
||||
return range;
|
||||
},
|
||||
makeLink: function(range) {
|
||||
var a, char, i, text;
|
||||
text = range.toString();
|
||||
i = 0;
|
||||
while (/[(\[{<>]/.test(text.charAt(i))) {
|
||||
i++;
|
||||
}
|
||||
if (i) {
|
||||
text = text.slice(i);
|
||||
while (range.startOffset + i >= range.startContainer.data.length) {
|
||||
i--;
|
||||
}
|
||||
if (i) {
|
||||
range.setStart(range.startContainer, range.startOffset + i);
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
while (/[)\]}>.,]/.test(char = text.charAt(text.length - (1 + i)))) {
|
||||
if (!(/[.,]/.test(char) || (text.match(/[()\[\]{}<>]/g)).length % 2)) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i) {
|
||||
text = text.slice(0, -i);
|
||||
while (range.endOffset - i < 0) {
|
||||
i--;
|
||||
}
|
||||
if (i) {
|
||||
range.setEnd(range.endContainer, range.endOffset - i);
|
||||
}
|
||||
}
|
||||
if (!/(https?|mailto|git|magnet|ftp|irc):/.test(text)) {
|
||||
text = (/@/.test(text) ? 'mailto:' : 'http://') + text;
|
||||
}
|
||||
a = $.el('a', {
|
||||
className: 'linkify',
|
||||
rel: 'nofollow noreferrer',
|
||||
target: '_blank',
|
||||
href: text
|
||||
});
|
||||
$.add(a, range.extractContents());
|
||||
range.insertNode(a);
|
||||
return a;
|
||||
},
|
||||
services: function(link) {
|
||||
var href, match, type, _i, _len, _ref;
|
||||
href = link.href;
|
||||
_ref = Linkify.ordered_types;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
type = _ref[_i];
|
||||
if (!(match = type.regExp.exec(href))) {
|
||||
continue;
|
||||
}
|
||||
if (type.dummy) {
|
||||
return;
|
||||
}
|
||||
return [type.key, match[1], match[2], link];
|
||||
}
|
||||
},
|
||||
embed: function(data) {
|
||||
var embed, href, key, link, name, options, uid, value, _ref;
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3];
|
||||
href = link.href;
|
||||
embed = $.el('a', {
|
||||
className: 'embedder',
|
||||
href: 'javascript:;',
|
||||
textContent: '(embed)'
|
||||
});
|
||||
_ref = {
|
||||
key: key,
|
||||
href: href,
|
||||
uid: uid,
|
||||
options: options
|
||||
};
|
||||
for (name in _ref) {
|
||||
value = _ref[name];
|
||||
embed.dataset[name] = value;
|
||||
}
|
||||
embed.dataset.nodedata = link.innerHTML;
|
||||
$.addClass(link, "" + embed.dataset.key);
|
||||
$.on(embed, 'click', Linkify.cb.toggle);
|
||||
$.after(link, [$.tn(' '), embed]);
|
||||
if (Conf['Auto-embed']) {
|
||||
Linkify.cb.toggle.call(embed);
|
||||
}
|
||||
data.push(embed);
|
||||
},
|
||||
title: function(data) {
|
||||
var embed, err, key, link, options, service, title, titles, uid;
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4];
|
||||
if (!(service = Linkify.types[key].title)) {
|
||||
return;
|
||||
}
|
||||
titles = Conf['CachedTitles'];
|
||||
if (title = titles[uid]) {
|
||||
if (link) {
|
||||
link.textContent = title[0];
|
||||
}
|
||||
if (Conf['Embedding']) {
|
||||
return embed.dataset.title = title[0];
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$.cache(service.api(uid), function() {
|
||||
return title = Linkify.cb.title(this, data);
|
||||
}, {
|
||||
responseType: 'json'
|
||||
});
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
if (link) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
titleSync: function(value) {
|
||||
return Conf['CachedTitles'] = value;
|
||||
},
|
||||
cb: {
|
||||
toggle: function() {
|
||||
var string, _ref;
|
||||
_ref = $.hasClass(this, "embedded") ? ['unembed', '(embed)'] : ['embed', '(unembed)'], string = _ref[0], this.textContent = _ref[1];
|
||||
$.replace(this.previousElementSibling, Linkify.cb[string](this));
|
||||
return $.toggleClass(this, 'embedded');
|
||||
},
|
||||
embed: function(a) {
|
||||
var el, style, type;
|
||||
el = (type = Linkify.types[a.dataset.key]).el(a);
|
||||
el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px";
|
||||
return el;
|
||||
},
|
||||
unembed: function(a) {
|
||||
var el;
|
||||
el = $.el('a', {
|
||||
rel: 'nofollow noreferrer',
|
||||
target: 'blank',
|
||||
className: 'linkify',
|
||||
href: a.dataset.href,
|
||||
innerHTML: a.dataset.title || a.dataset.nodedata
|
||||
});
|
||||
$.addClass(el, a.dataset.key);
|
||||
return el;
|
||||
},
|
||||
title: function(response, data) {
|
||||
var embed, key, link, options, service, text, uid;
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4];
|
||||
service = Linkify.types[key].title;
|
||||
switch (response.status) {
|
||||
case 200:
|
||||
case 304:
|
||||
text = "" + (service.text(response.response));
|
||||
if (Conf['Embedding']) {
|
||||
embed.dataset.title = text;
|
||||
}
|
||||
break;
|
||||
case 404:
|
||||
text = "[" + key + "] Not Found";
|
||||
break;
|
||||
case 403:
|
||||
text = "[" + key + "] Forbidden or Private";
|
||||
break;
|
||||
default:
|
||||
text = "[" + key + "] " + this.status + "'d";
|
||||
}
|
||||
if (link) {
|
||||
return link.textContent = text;
|
||||
}
|
||||
}
|
||||
},
|
||||
ordered_types: [
|
||||
{
|
||||
key: 'audio',
|
||||
regExp: /(.*\.(mp3|ogg|wav))$/,
|
||||
el: function(a) {
|
||||
return $.el('audio', {
|
||||
controls: 'controls',
|
||||
preload: 'auto',
|
||||
src: a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'gist',
|
||||
regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/,
|
||||
el: function(a) {
|
||||
var div;
|
||||
return div = $.el('iframe', {
|
||||
src: "http://www.purplegene.com/script?url=https://gist.github.com/" + a.dataset.uid + ".js"
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function(uid) {
|
||||
return "https://api.github.com/gists/" + uid;
|
||||
},
|
||||
text: function(_arg) {
|
||||
var file, files;
|
||||
files = _arg.files;
|
||||
for (file in files) {
|
||||
if (files.hasOwnProperty(file)) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'image',
|
||||
regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
|
||||
style: 'border: 0; width: auto; height: auto;',
|
||||
el: function(a) {
|
||||
return $.el('div', {
|
||||
innerHTML: "<a target=_blank href='" + a.dataset.href + "'><img src='" + a.dataset.href + "'></a>"
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'InstallGentoo',
|
||||
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/,
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "http://paste.installgentoo.com/view/embed/" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'Twitter',
|
||||
regExp: /.*twitter.com\/(.+\/status\/\d+)/,
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'LiveLeak',
|
||||
regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
|
||||
el: function(a) {
|
||||
var el;
|
||||
el = $.el('iframe', {
|
||||
width: "640",
|
||||
height: "360",
|
||||
src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid,
|
||||
frameborder: "0"
|
||||
});
|
||||
el.setAttribute("allowfullscreen", "true");
|
||||
return el;
|
||||
}
|
||||
}, {
|
||||
key: 'MediaCrush',
|
||||
regExp: /.*(?:mediacru.sh\/)([0-9a-z_]+)/i,
|
||||
style: 'border: 0;',
|
||||
el: function(a) {
|
||||
var el;
|
||||
el = $.el('div');
|
||||
$.cache("https://mediacru.sh/" + a.dataset.uid + ".json", function() {
|
||||
var embed, file, files, status, type, _i, _j, _len, _len1, _ref;
|
||||
status = this.status;
|
||||
if (status !== 200 && status !== 304) {
|
||||
return div.innerHTML = "ERROR " + status;
|
||||
}
|
||||
files = this.response.files;
|
||||
_ref = ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
type = _ref[_i];
|
||||
for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
|
||||
file = files[_j];
|
||||
if (file.type === type) {
|
||||
embed = file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (embed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!embed) {
|
||||
return div.innerHTML = "ERROR: Not a valid filetype";
|
||||
}
|
||||
return el.innerHTML = (function() {
|
||||
switch (embed.type) {
|
||||
case 'video/mp4':
|
||||
case 'video/ogv':
|
||||
return "<video autoplay loop>\n <source src=\"https://mediacru.sh/" + a.dataset.uid + ".mp4\" type=\"video/mp4;\">\n <source src=\"https://mediacru.sh/" + a.dataset.uid + ".ogv\" type=\"video/ogg; codecs='theora, vorbis'\">\n</video>";
|
||||
case 'image/png':
|
||||
case 'image/gif':
|
||||
case 'image/jpeg':
|
||||
return "<a target=_blank href='" + a.dataset.href + "'><img src='https://mediacru.sh/" + file.file + "'></a>";
|
||||
case 'image/svg':
|
||||
case 'image/svg+xml':
|
||||
return "<embed src='https://mediacru.sh/" + file.file + "' type='image/svg+xml' />";
|
||||
case 'audio/mpeg':
|
||||
return "<audio controls><source src='https://mediacru.sh/" + file.file + "'></audio>";
|
||||
default:
|
||||
return "ERROR: No valid filetype.";
|
||||
}
|
||||
})();
|
||||
});
|
||||
return el;
|
||||
}
|
||||
}, {
|
||||
key: 'pastebin',
|
||||
regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
|
||||
el: function(a) {
|
||||
var div;
|
||||
return div = $.el('iframe', {
|
||||
src: "http://pastebin.com/embed_iframe.php?i=" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'gfycat',
|
||||
regExp: /.*gfycat.com\/(?:iframe\/)?(\S*)/,
|
||||
el: function(a) {
|
||||
var div;
|
||||
return div = $.el('iframe', {
|
||||
src: "http://gfycat.com/iframe/" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'SoundCloud',
|
||||
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
|
||||
style: 'height: auto; width: 500px; display: inline-block;',
|
||||
el: function(a) {
|
||||
var div;
|
||||
div = $.el('div', {
|
||||
className: "soundcloud",
|
||||
name: "soundcloud"
|
||||
});
|
||||
$.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + a.dataset.uid, {
|
||||
onloadend: function() {
|
||||
return div.innerHTML = JSON.parse(this.responseText).html;
|
||||
}
|
||||
}, false);
|
||||
return div;
|
||||
},
|
||||
title: {
|
||||
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 _.title;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'StrawPoll',
|
||||
regExp: /strawpoll\.me\/(?:embed_\d+\/)?(\d+)/,
|
||||
style: 'border: 0; width: 600px; height: 406px;',
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "http://strawpoll.me/embed_1/" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'TwitchTV',
|
||||
regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/,
|
||||
style: "border: none; width: 640px; height: 360px;",
|
||||
el: function(a) {
|
||||
var channel, chapter, result, _;
|
||||
if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(a.dataset.uid)) {
|
||||
_ = result[0], channel = result[1], chapter = result[2];
|
||||
return $.el('object', {
|
||||
data: 'http://www.twitch.tv/widgets/archive_embed_player.swf',
|
||||
innerHTML: "<param name='allowFullScreen' value='true' />\n<param name='flashvars' value='channel=" + channel + "&start_volume=25&auto_play=false" + (chapter ? "&chapter_id=" + chapter : "") + "' />"
|
||||
});
|
||||
} else {
|
||||
channel = (/(\w+)/.exec(a.dataset.uid))[0];
|
||||
return $.el('object', {
|
||||
data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel,
|
||||
innerHTML: "<param name=\"allowFullScreen\" value=\"true\" />\n<param name=\"movie\" value=\"http://www.twitch.tv/widgets/live_embed_player.swf\" />\n<param name=\"flashvars\" value=\"hostname=www.twitch.tv&channel=" + channel + "&auto_play=true&start_volume=25\" />"
|
||||
});
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'Vocaroo',
|
||||
regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
|
||||
style: 'border: 0; width: 150px; height: 45px;',
|
||||
el: function(a) {
|
||||
return $.el('object', {
|
||||
innerHTML: "<embed src='http://vocaroo.com/player.swf?playMediaID=" + (a.dataset.uid.replace(/^i\//, '')) + "&autoplay=0' wmode='opaque' width='150' height='45' pluginspage='http://get.adobe.com/flashplayer/' type='application/x-shockwave-flash'></embed>"
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'Vimeo',
|
||||
regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "//player.vimeo.com/video/" + a.dataset.uid + "?wmode=opaque"
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function(uid) {
|
||||
return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
|
||||
},
|
||||
text: function(_) {
|
||||
return _.title;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'Vine',
|
||||
regExp: /.*(?:vine.co\/)([^#\&\?]*).*/,
|
||||
style: 'border: none; width: 500px; height: 500px;',
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "https://vine.co/" + a.dataset.uid + "/card"
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'YouTube',
|
||||
regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
|
||||
el: function(a) {
|
||||
var el;
|
||||
el = $.el('iframe', {
|
||||
src: "//www.youtube.com/embed/" + a.dataset.uid + (a.dataset.option ? '#' + a.dataset.option : '') + "?wmode=opaque"
|
||||
});
|
||||
el.setAttribute("allowfullscreen", "true");
|
||||
return el;
|
||||
},
|
||||
title: {
|
||||
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(data) {
|
||||
return data.entry.title.$t;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'Loopvid',
|
||||
regExp: /.*loopvid.appspot.com\/.*/,
|
||||
dummy: true
|
||||
}, {
|
||||
key: 'MediaFire',
|
||||
regExp: /.*mediafire.com\/.*/,
|
||||
dummy: true
|
||||
}, {
|
||||
key: 'video',
|
||||
regExp: /(.*\.(ogv|webm|mp4))$/,
|
||||
el: function(a) {
|
||||
return $.el('video', {
|
||||
controls: 'controls',
|
||||
preload: 'auto',
|
||||
src: a.dataset.uid
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
ArchiveLink = {
|
||||
init: function() {
|
||||
var div, entry, type, _i, _len, _ref;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Generated by CoffeeScript
|
||||
/*
|
||||
* 4chan X - Version 1.4.1 - 2014-03-31
|
||||
* 4chan X - Version 1.4.1 - 2014-04-02
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/Spittie/4chan-x/blob/master/LICENSE
|
||||
@ -6344,6 +6344,10 @@
|
||||
onload: QR.response,
|
||||
onerror: function(err, url, line) {
|
||||
delete QR.req;
|
||||
if (QR.captcha.isEnabled) {
|
||||
QR.captcha.destroy();
|
||||
QR.captcha.setup();
|
||||
}
|
||||
post.unlock();
|
||||
QR.cooldown.auto = false;
|
||||
QR.status();
|
||||
@ -6376,9 +6380,12 @@
|
||||
return QR.status();
|
||||
},
|
||||
response: function() {
|
||||
var URL, ban, board, captchasCount, err, h1, isReply, m, notif, post, postID, postsCount, req, resDoc, threadID, _, _ref, _ref1;
|
||||
var URL, ban, board, err, h1, isReply, m, post, postID, postsCount, req, resDoc, threadID, _, _ref, _ref1;
|
||||
req = QR.req;
|
||||
delete QR.req;
|
||||
if (QR.captcha.isEnabled) {
|
||||
QR.captcha.destroy();
|
||||
}
|
||||
post = QR.posts[0];
|
||||
post.unlock();
|
||||
resDoc = req.response;
|
||||
@ -6403,12 +6410,12 @@
|
||||
} else if (/expired/i.test(err.textContent)) {
|
||||
err = 'This CAPTCHA is no longer valid because it has expired.';
|
||||
}
|
||||
QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : err === 'Connection error with sys.4chan.org.' ? true : false;
|
||||
QR.cooldown.auto = false;
|
||||
QR.cooldown.set({
|
||||
delay: 2
|
||||
});
|
||||
} else if (err.textContent && (m = err.textContent.match(/wait\s+(\d+)\s+second/i))) {
|
||||
QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : true;
|
||||
QR.cooldown.auto = !QR.captcha.isEnabled;
|
||||
QR.cooldown.set({
|
||||
delay: m[1]
|
||||
});
|
||||
@ -6447,22 +6454,6 @@
|
||||
});
|
||||
postsCount = QR.posts.length - 1;
|
||||
QR.cooldown.auto = postsCount && isReply;
|
||||
if (QR.cooldown.auto && QR.captcha.isEnabled && (captchasCount = QR.captcha.captchas.length) < 3 && captchasCount < postsCount) {
|
||||
notif = new Notification('Quick reply warning', {
|
||||
body: "You are running low on cached captchas. Cache count: " + captchasCount + ".",
|
||||
icon: Favicon.logo
|
||||
});
|
||||
notif.onclick = function() {
|
||||
QR.open();
|
||||
QR.captcha.nodes.input.focus();
|
||||
return window.focus();
|
||||
};
|
||||
notif.onshow = function() {
|
||||
return setTimeout(function() {
|
||||
return notif.close();
|
||||
}, 7 * $.SECOND);
|
||||
};
|
||||
}
|
||||
if (!(Conf['Persistent QR'] || QR.cooldown.auto)) {
|
||||
QR.close();
|
||||
} else {
|
||||
@ -6498,12 +6489,11 @@
|
||||
|
||||
QR.captcha = {
|
||||
init: function() {
|
||||
var container, imgContainer, input;
|
||||
var imgContainer, input;
|
||||
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
|
||||
return;
|
||||
}
|
||||
container = $.id('captchaContainer');
|
||||
if (!(this.isEnabled = !!container)) {
|
||||
if (!(this.isEnabled = !!$.id('captchaContainer'))) {
|
||||
return;
|
||||
}
|
||||
if (Conf['Auto-load captcha']) {
|
||||
@ -6512,13 +6502,11 @@
|
||||
imgContainer = $.el('div', {
|
||||
className: 'captcha-img',
|
||||
title: 'Reload reCAPTCHA',
|
||||
innerHTML: '<img>',
|
||||
hidden: true
|
||||
innerHTML: '<img>'
|
||||
});
|
||||
input = $.el('input', {
|
||||
className: 'captcha-input field',
|
||||
title: 'Verification',
|
||||
placeholder: 'Focus to load reCAPTCHA',
|
||||
autocomplete: 'off',
|
||||
spellcheck: false,
|
||||
tabIndex: 45
|
||||
@ -6527,44 +6515,41 @@
|
||||
img: imgContainer.firstChild,
|
||||
input: input
|
||||
};
|
||||
$.on(input, 'focus', this.setup);
|
||||
$.on(input, 'blur', QR.focusout);
|
||||
$.on(input, 'focus', QR.focusin);
|
||||
$.addClass(QR.nodes.el, 'has-captcha');
|
||||
$.after(QR.nodes.com.parentNode, [imgContainer, input]);
|
||||
this.beforeSetup();
|
||||
return this.afterSetup();
|
||||
},
|
||||
beforeSetup: function() {
|
||||
var img, input, _ref;
|
||||
_ref = this.nodes, img = _ref.img, input = _ref.input;
|
||||
img.parentNode.hidden = true;
|
||||
input.value = '';
|
||||
input.placeholder = 'Focus to load reCAPTCHA';
|
||||
$.on(input, 'focus', this.setup);
|
||||
this.setupObserver = new MutationObserver(this.afterSetup);
|
||||
this.setupObserver.observe(container, {
|
||||
return this.setupObserver.observe($.id('captchaContainer'), {
|
||||
childList: true
|
||||
});
|
||||
return this.afterSetup();
|
||||
},
|
||||
setup: function() {
|
||||
return $.globalEval('loadRecaptcha()');
|
||||
},
|
||||
afterSetup: function() {
|
||||
var challenge, img, input, setLifetime, _ref;
|
||||
var challenge, img, input, _ref;
|
||||
if (!(challenge = $.id('recaptcha_challenge_field_holder'))) {
|
||||
return;
|
||||
}
|
||||
QR.captcha.setupObserver.disconnect();
|
||||
delete QR.captcha.setupObserver;
|
||||
setLifetime = function(e) {
|
||||
return QR.captcha.lifetime = e.detail;
|
||||
};
|
||||
$.on(window, 'captcha:timeout', setLifetime);
|
||||
$.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))');
|
||||
$.off(window, 'captcha:timeout', setLifetime);
|
||||
_ref = QR.captcha.nodes, img = _ref.img, input = _ref.input;
|
||||
img.parentNode.hidden = false;
|
||||
input.placeholder = 'Verification';
|
||||
$.off(input, 'focus', QR.captcha.setup);
|
||||
$.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha));
|
||||
$.on(img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha));
|
||||
$.get('captchas', [], function(_arg) {
|
||||
var captchas;
|
||||
captchas = _arg.captchas;
|
||||
return QR.captcha.sync(captchas);
|
||||
});
|
||||
$.sync('captchas', QR.captcha.sync);
|
||||
QR.captcha.nodes.challenge = challenge;
|
||||
new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
|
||||
childList: true,
|
||||
@ -6573,94 +6558,31 @@
|
||||
});
|
||||
return QR.captcha.load();
|
||||
},
|
||||
sync: function(captchas) {
|
||||
QR.captcha.captchas = captchas;
|
||||
return QR.captcha.count();
|
||||
destroy: function() {
|
||||
$.globalEval('Recaptcha.destroy()');
|
||||
return this.beforeSetup();
|
||||
},
|
||||
getOne: function() {
|
||||
var captcha, challenge, response;
|
||||
this.clear();
|
||||
if (captcha = this.captchas.shift()) {
|
||||
challenge = captcha.challenge, response = captcha.response;
|
||||
this.count();
|
||||
$.set('captchas', this.captchas);
|
||||
} else {
|
||||
challenge = this.nodes.img.alt;
|
||||
if (response = this.nodes.input.value) {
|
||||
this.reload();
|
||||
}
|
||||
}
|
||||
if (response) {
|
||||
response = response.trim();
|
||||
if (!/\s/.test(response)) {
|
||||
response = "" + response + " " + response;
|
||||
}
|
||||
var challenge, response;
|
||||
challenge = this.nodes.img.alt;
|
||||
response = this.nodes.input.value.trim();
|
||||
if (response && !/\s/.test(response)) {
|
||||
response = "" + response + " " + response;
|
||||
}
|
||||
return {
|
||||
challenge: challenge,
|
||||
response: response
|
||||
};
|
||||
},
|
||||
save: function() {
|
||||
var response;
|
||||
if (!(response = this.nodes.input.value.trim())) {
|
||||
return;
|
||||
}
|
||||
this.captchas.push({
|
||||
challenge: this.nodes.img.alt,
|
||||
response: response,
|
||||
timeout: this.timeout
|
||||
});
|
||||
this.count();
|
||||
this.reload();
|
||||
return $.set('captchas', this.captchas);
|
||||
},
|
||||
clear: function() {
|
||||
var captcha, i, now, _i, _len, _ref;
|
||||
if (!this.captchas.length) {
|
||||
return;
|
||||
}
|
||||
now = Date.now();
|
||||
_ref = this.captchas;
|
||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||
captcha = _ref[i];
|
||||
if (captcha.timeout > now) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!i) {
|
||||
return;
|
||||
}
|
||||
this.captchas = this.captchas.slice(i);
|
||||
this.count();
|
||||
return $.set('captchas', this.captchas);
|
||||
},
|
||||
load: function() {
|
||||
var challenge;
|
||||
if (!this.nodes.challenge.firstChild) {
|
||||
return;
|
||||
}
|
||||
this.timeout = Date.now() + this.lifetime * $.SECOND - $.MINUTE;
|
||||
challenge = this.nodes.challenge.firstChild.value;
|
||||
this.nodes.img.alt = challenge;
|
||||
this.nodes.img.src = "//www.google.com/recaptcha/api/image?c=" + challenge;
|
||||
this.nodes.input.value = null;
|
||||
return this.clear();
|
||||
},
|
||||
count: function() {
|
||||
var count;
|
||||
count = this.captchas ? this.captchas.length : 0;
|
||||
this.nodes.input.placeholder = (function() {
|
||||
switch (count) {
|
||||
case 0:
|
||||
return 'Verification (Shift + Enter to cache)';
|
||||
case 1:
|
||||
return 'Verification (1 cached captcha)';
|
||||
default:
|
||||
return "Verification (" + count + " cached captchas)";
|
||||
}
|
||||
})();
|
||||
return this.nodes.input.alt = count;
|
||||
return this.nodes.input.value = null;
|
||||
},
|
||||
reload: function(focus) {
|
||||
$.globalEval('Recaptcha.reload("t")');
|
||||
@ -6671,8 +6593,6 @@
|
||||
keydown: function(e) {
|
||||
if (e.keyCode === 8 && !this.nodes.input.value) {
|
||||
this.reload();
|
||||
} else if (e.keyCode === 13 && e.shiftKey) {
|
||||
this.save();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -7002,6 +6922,9 @@
|
||||
node.disabled = lock;
|
||||
}
|
||||
}
|
||||
if (QR.captcha.isEnabled) {
|
||||
QR.captcha.nodes.input.disabled = lock;
|
||||
}
|
||||
this.nodes.rm.style.visibility = lock ? 'hidden' : '';
|
||||
(lock ? $.off : $.on)(QR.nodes.filename.previousElementSibling, 'click', QR.openFileInput);
|
||||
this.nodes.spoiler.disabled = lock;
|
||||
@ -8644,561 +8567,6 @@
|
||||
]
|
||||
};
|
||||
|
||||
Linkify = {
|
||||
init: function() {
|
||||
var type, _i, _len, _ref;
|
||||
if (g.VIEW === 'catalog' || !Conf['Linkify']) {
|
||||
return;
|
||||
}
|
||||
this.regString = /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/])|[-a-z\d]+[.](aero|asia|biz|cat|com|coop|info|int|jobs|mobi|museum|name|net|org|post|pro|tel|travel|xxx|edu|gov|mil|[a-z]{2})(\/|(?!.))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i;
|
||||
this.types = {};
|
||||
_ref = this.ordered_types;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
type = _ref[_i];
|
||||
this.types[type.key] = type;
|
||||
}
|
||||
if (Conf['Comment Expansion']) {
|
||||
ExpandComment.callbacks.push(this.node);
|
||||
}
|
||||
if (Conf['Title Link']) {
|
||||
$.sync('CachedTitles', Linkify.titleSync);
|
||||
}
|
||||
return Post.callbacks.push({
|
||||
name: 'Linkify',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var data, el, end, endNode, i, index, items, length, link, links, node, result, saved, snapshot, space, test, word, _i, _len, _ref;
|
||||
if (this.isClone) {
|
||||
if (Conf['Embedding']) {
|
||||
i = 0;
|
||||
items = $$('.embed', this.nodes.comment);
|
||||
while (el = items[i++]) {
|
||||
$.on(el, 'click', Linkify.cb.toggle);
|
||||
if ($.hasClass(el, 'embedded')) {
|
||||
Linkify.cb.toggle.call(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
test = /[^\s'"]+/g;
|
||||
space = /[\s'"]/;
|
||||
snapshot = $.X('.//br|.//text()', this.nodes.comment);
|
||||
i = 0;
|
||||
links = [];
|
||||
while (node = snapshot.snapshotItem(i++)) {
|
||||
data = node.data;
|
||||
if (node.parentElement.nodeName === "A" || !data) {
|
||||
continue;
|
||||
}
|
||||
while (result = test.exec(data)) {
|
||||
index = result.index;
|
||||
endNode = node;
|
||||
word = result[0];
|
||||
if ((length = index + word.length) === data.length) {
|
||||
test.lastIndex = 0;
|
||||
while ((saved = snapshot.snapshotItem(i++))) {
|
||||
if (saved.nodeName === 'BR') {
|
||||
break;
|
||||
}
|
||||
endNode = saved;
|
||||
data = saved.data;
|
||||
word += data;
|
||||
length = data.length;
|
||||
if (end = space.exec(data)) {
|
||||
test.lastIndex = length = end.index;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Linkify.regString.exec(word)) {
|
||||
links.push(Linkify.makeRange(node, endNode, index, length));
|
||||
}
|
||||
if (!(test.lastIndex && node === endNode)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ref = links.reverse();
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
link = _ref[_i];
|
||||
this.nodes.links.push(Linkify.makeLink(link, this));
|
||||
link.detach();
|
||||
}
|
||||
if (!(Conf['Embedding'] || Conf['Link Title'])) {
|
||||
return;
|
||||
}
|
||||
links = this.nodes.links;
|
||||
i = 0;
|
||||
while (link = links[i++]) {
|
||||
if (data = Linkify.services(link)) {
|
||||
if (Conf['Embedding']) {
|
||||
Linkify.embed(data);
|
||||
}
|
||||
if (Conf['Link Title']) {
|
||||
Linkify.title(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
makeRange: function(startNode, endNode, startOffset, endOffset) {
|
||||
var range;
|
||||
range = document.createRange();
|
||||
range.setStart(startNode, startOffset);
|
||||
range.setEnd(endNode, endOffset);
|
||||
return range;
|
||||
},
|
||||
makeLink: function(range) {
|
||||
var a, char, i, text;
|
||||
text = range.toString();
|
||||
i = 0;
|
||||
while (/[(\[{<>]/.test(text.charAt(i))) {
|
||||
i++;
|
||||
}
|
||||
if (i) {
|
||||
text = text.slice(i);
|
||||
while (range.startOffset + i >= range.startContainer.data.length) {
|
||||
i--;
|
||||
}
|
||||
if (i) {
|
||||
range.setStart(range.startContainer, range.startOffset + i);
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
while (/[)\]}>.,]/.test(char = text.charAt(text.length - (1 + i)))) {
|
||||
if (!(/[.,]/.test(char) || (text.match(/[()\[\]{}<>]/g)).length % 2)) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i) {
|
||||
text = text.slice(0, -i);
|
||||
while (range.endOffset - i < 0) {
|
||||
i--;
|
||||
}
|
||||
if (i) {
|
||||
range.setEnd(range.endContainer, range.endOffset - i);
|
||||
}
|
||||
}
|
||||
if (!/(https?|mailto|git|magnet|ftp|irc):/.test(text)) {
|
||||
text = (/@/.test(text) ? 'mailto:' : 'http://') + text;
|
||||
}
|
||||
a = $.el('a', {
|
||||
className: 'linkify',
|
||||
rel: 'nofollow noreferrer',
|
||||
target: '_blank',
|
||||
href: text
|
||||
});
|
||||
$.add(a, range.extractContents());
|
||||
range.insertNode(a);
|
||||
return a;
|
||||
},
|
||||
services: function(link) {
|
||||
var href, match, type, _i, _len, _ref;
|
||||
href = link.href;
|
||||
_ref = Linkify.ordered_types;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
type = _ref[_i];
|
||||
if (!(match = type.regExp.exec(href))) {
|
||||
continue;
|
||||
}
|
||||
if (type.dummy) {
|
||||
return;
|
||||
}
|
||||
return [type.key, match[1], match[2], link];
|
||||
}
|
||||
},
|
||||
embed: function(data) {
|
||||
var embed, href, key, link, name, options, uid, value, _ref;
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3];
|
||||
href = link.href;
|
||||
embed = $.el('a', {
|
||||
className: 'embedder',
|
||||
href: 'javascript:;',
|
||||
textContent: '(embed)'
|
||||
});
|
||||
_ref = {
|
||||
key: key,
|
||||
href: href,
|
||||
uid: uid,
|
||||
options: options
|
||||
};
|
||||
for (name in _ref) {
|
||||
value = _ref[name];
|
||||
embed.dataset[name] = value;
|
||||
}
|
||||
embed.dataset.nodedata = link.innerHTML;
|
||||
$.addClass(link, "" + embed.dataset.key);
|
||||
$.on(embed, 'click', Linkify.cb.toggle);
|
||||
$.after(link, [$.tn(' '), embed]);
|
||||
if (Conf['Auto-embed']) {
|
||||
Linkify.cb.toggle.call(embed);
|
||||
}
|
||||
data.push(embed);
|
||||
},
|
||||
title: function(data) {
|
||||
var embed, err, key, link, options, service, title, titles, uid;
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4];
|
||||
if (!(service = Linkify.types[key].title)) {
|
||||
return;
|
||||
}
|
||||
titles = Conf['CachedTitles'];
|
||||
if (title = titles[uid]) {
|
||||
if (link) {
|
||||
link.textContent = title[0];
|
||||
}
|
||||
if (Conf['Embedding']) {
|
||||
return embed.dataset.title = title[0];
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$.cache(service.api(uid), function() {
|
||||
return title = Linkify.cb.title(this, data);
|
||||
}, {
|
||||
responseType: 'json'
|
||||
});
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
if (link) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
titleSync: function(value) {
|
||||
return Conf['CachedTitles'] = value;
|
||||
},
|
||||
cb: {
|
||||
toggle: function() {
|
||||
var string, _ref;
|
||||
_ref = $.hasClass(this, "embedded") ? ['unembed', '(embed)'] : ['embed', '(unembed)'], string = _ref[0], this.textContent = _ref[1];
|
||||
$.replace(this.previousElementSibling, Linkify.cb[string](this));
|
||||
return $.toggleClass(this, 'embedded');
|
||||
},
|
||||
embed: function(a) {
|
||||
var el, style, type;
|
||||
el = (type = Linkify.types[a.dataset.key]).el(a);
|
||||
el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px";
|
||||
return el;
|
||||
},
|
||||
unembed: function(a) {
|
||||
var el;
|
||||
el = $.el('a', {
|
||||
rel: 'nofollow noreferrer',
|
||||
target: 'blank',
|
||||
className: 'linkify',
|
||||
href: a.dataset.href,
|
||||
innerHTML: a.dataset.title || a.dataset.nodedata
|
||||
});
|
||||
$.addClass(el, a.dataset.key);
|
||||
return el;
|
||||
},
|
||||
title: function(response, data) {
|
||||
var embed, key, link, options, service, text, uid;
|
||||
key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4];
|
||||
service = Linkify.types[key].title;
|
||||
switch (response.status) {
|
||||
case 200:
|
||||
case 304:
|
||||
text = "" + (service.text(response.response));
|
||||
if (Conf['Embedding']) {
|
||||
embed.dataset.title = text;
|
||||
}
|
||||
break;
|
||||
case 404:
|
||||
text = "[" + key + "] Not Found";
|
||||
break;
|
||||
case 403:
|
||||
text = "[" + key + "] Forbidden or Private";
|
||||
break;
|
||||
default:
|
||||
text = "[" + key + "] " + this.status + "'d";
|
||||
}
|
||||
if (link) {
|
||||
return link.textContent = text;
|
||||
}
|
||||
}
|
||||
},
|
||||
ordered_types: [
|
||||
{
|
||||
key: 'audio',
|
||||
regExp: /(.*\.(mp3|ogg|wav))$/,
|
||||
el: function(a) {
|
||||
return $.el('audio', {
|
||||
controls: 'controls',
|
||||
preload: 'auto',
|
||||
src: a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'gist',
|
||||
regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/,
|
||||
el: function(a) {
|
||||
var div;
|
||||
return div = $.el('iframe', {
|
||||
src: "http://www.purplegene.com/script?url=https://gist.github.com/" + a.dataset.uid + ".js"
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function(uid) {
|
||||
return "https://api.github.com/gists/" + uid;
|
||||
},
|
||||
text: function(_arg) {
|
||||
var file, files;
|
||||
files = _arg.files;
|
||||
for (file in files) {
|
||||
if (files.hasOwnProperty(file)) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'image',
|
||||
regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
|
||||
style: 'border: 0; width: auto; height: auto;',
|
||||
el: function(a) {
|
||||
return $.el('div', {
|
||||
innerHTML: "<a target=_blank href='" + a.dataset.href + "'><img src='" + a.dataset.href + "'></a>"
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'InstallGentoo',
|
||||
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/,
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "http://paste.installgentoo.com/view/embed/" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'Twitter',
|
||||
regExp: /.*twitter.com\/(.+\/status\/\d+)/,
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'LiveLeak',
|
||||
regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
|
||||
el: function(a) {
|
||||
var el;
|
||||
el = $.el('iframe', {
|
||||
width: "640",
|
||||
height: "360",
|
||||
src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid,
|
||||
frameborder: "0"
|
||||
});
|
||||
el.setAttribute("allowfullscreen", "true");
|
||||
return el;
|
||||
}
|
||||
}, {
|
||||
key: 'MediaCrush',
|
||||
regExp: /.*(?:mediacru.sh\/)([0-9a-z_]+)/i,
|
||||
style: 'border: 0;',
|
||||
el: function(a) {
|
||||
var el;
|
||||
el = $.el('div');
|
||||
$.cache("https://mediacru.sh/" + a.dataset.uid + ".json", function() {
|
||||
var embed, file, files, status, type, _i, _j, _len, _len1, _ref;
|
||||
status = this.status;
|
||||
if (status !== 200 && status !== 304) {
|
||||
return div.innerHTML = "ERROR " + status;
|
||||
}
|
||||
files = this.response.files;
|
||||
_ref = ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg'];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
type = _ref[_i];
|
||||
for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
|
||||
file = files[_j];
|
||||
if (file.type === type) {
|
||||
embed = file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (embed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!embed) {
|
||||
return div.innerHTML = "ERROR: Not a valid filetype";
|
||||
}
|
||||
return el.innerHTML = (function() {
|
||||
switch (embed.type) {
|
||||
case 'video/mp4':
|
||||
case 'video/ogv':
|
||||
return "<video autoplay loop>\n <source src=\"https://mediacru.sh/" + a.dataset.uid + ".mp4\" type=\"video/mp4;\">\n <source src=\"https://mediacru.sh/" + a.dataset.uid + ".ogv\" type=\"video/ogg; codecs='theora, vorbis'\">\n</video>";
|
||||
case 'image/png':
|
||||
case 'image/gif':
|
||||
case 'image/jpeg':
|
||||
return "<a target=_blank href='" + a.dataset.href + "'><img src='https://mediacru.sh/" + file.file + "'></a>";
|
||||
case 'image/svg':
|
||||
case 'image/svg+xml':
|
||||
return "<embed src='https://mediacru.sh/" + file.file + "' type='image/svg+xml' />";
|
||||
case 'audio/mpeg':
|
||||
return "<audio controls><source src='https://mediacru.sh/" + file.file + "'></audio>";
|
||||
default:
|
||||
return "ERROR: No valid filetype.";
|
||||
}
|
||||
})();
|
||||
});
|
||||
return el;
|
||||
}
|
||||
}, {
|
||||
key: 'pastebin',
|
||||
regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
|
||||
el: function(a) {
|
||||
var div;
|
||||
return div = $.el('iframe', {
|
||||
src: "http://pastebin.com/embed_iframe.php?i=" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'gfycat',
|
||||
regExp: /.*gfycat.com\/(?:iframe\/)?(\S*)/,
|
||||
el: function(a) {
|
||||
var div;
|
||||
return div = $.el('iframe', {
|
||||
src: "http://gfycat.com/iframe/" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'SoundCloud',
|
||||
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
|
||||
style: 'height: auto; width: 500px; display: inline-block;',
|
||||
el: function(a) {
|
||||
var div;
|
||||
div = $.el('div', {
|
||||
className: "soundcloud",
|
||||
name: "soundcloud"
|
||||
});
|
||||
$.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + a.dataset.uid, {
|
||||
onloadend: function() {
|
||||
return div.innerHTML = JSON.parse(this.responseText).html;
|
||||
}
|
||||
}, false);
|
||||
return div;
|
||||
},
|
||||
title: {
|
||||
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 _.title;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'StrawPoll',
|
||||
regExp: /strawpoll\.me\/(?:embed_\d+\/)?(\d+)/,
|
||||
style: 'border: 0; width: 600px; height: 406px;',
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "http://strawpoll.me/embed_1/" + a.dataset.uid
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'TwitchTV',
|
||||
regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/,
|
||||
style: "border: none; width: 640px; height: 360px;",
|
||||
el: function(a) {
|
||||
var channel, chapter, result, _;
|
||||
if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(a.dataset.uid)) {
|
||||
_ = result[0], channel = result[1], chapter = result[2];
|
||||
return $.el('object', {
|
||||
data: 'http://www.twitch.tv/widgets/archive_embed_player.swf',
|
||||
innerHTML: "<param name='allowFullScreen' value='true' />\n<param name='flashvars' value='channel=" + channel + "&start_volume=25&auto_play=false" + (chapter ? "&chapter_id=" + chapter : "") + "' />"
|
||||
});
|
||||
} else {
|
||||
channel = (/(\w+)/.exec(a.dataset.uid))[0];
|
||||
return $.el('object', {
|
||||
data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel,
|
||||
innerHTML: "<param name=\"allowFullScreen\" value=\"true\" />\n<param name=\"movie\" value=\"http://www.twitch.tv/widgets/live_embed_player.swf\" />\n<param name=\"flashvars\" value=\"hostname=www.twitch.tv&channel=" + channel + "&auto_play=true&start_volume=25\" />"
|
||||
});
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'Vocaroo',
|
||||
regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
|
||||
style: 'border: 0; width: 150px; height: 45px;',
|
||||
el: function(a) {
|
||||
return $.el('object', {
|
||||
innerHTML: "<embed src='http://vocaroo.com/player.swf?playMediaID=" + (a.dataset.uid.replace(/^i\//, '')) + "&autoplay=0' wmode='opaque' width='150' height='45' pluginspage='http://get.adobe.com/flashplayer/' type='application/x-shockwave-flash'></embed>"
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'Vimeo',
|
||||
regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "//player.vimeo.com/video/" + a.dataset.uid + "?wmode=opaque"
|
||||
});
|
||||
},
|
||||
title: {
|
||||
api: function(uid) {
|
||||
return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
|
||||
},
|
||||
text: function(_) {
|
||||
return _.title;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'Vine',
|
||||
regExp: /.*(?:vine.co\/)([^#\&\?]*).*/,
|
||||
style: 'border: none; width: 500px; height: 500px;',
|
||||
el: function(a) {
|
||||
return $.el('iframe', {
|
||||
src: "https://vine.co/" + a.dataset.uid + "/card"
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'YouTube',
|
||||
regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
|
||||
el: function(a) {
|
||||
var el;
|
||||
el = $.el('iframe', {
|
||||
src: "//www.youtube.com/embed/" + a.dataset.uid + (a.dataset.option ? '#' + a.dataset.option : '') + "?wmode=opaque"
|
||||
});
|
||||
el.setAttribute("allowfullscreen", "true");
|
||||
return el;
|
||||
},
|
||||
title: {
|
||||
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(data) {
|
||||
return data.entry.title.$t;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'Loopvid',
|
||||
regExp: /.*loopvid.appspot.com\/.*/,
|
||||
dummy: true
|
||||
}, {
|
||||
key: 'MediaFire',
|
||||
regExp: /.*mediafire.com\/.*/,
|
||||
dummy: true
|
||||
}, {
|
||||
key: 'video',
|
||||
regExp: /(.*\.(ogv|webm|mp4))$/,
|
||||
el: function(a) {
|
||||
return $.el('video', {
|
||||
controls: 'controls',
|
||||
preload: 'auto',
|
||||
src: a.dataset.uid
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
ArchiveLink = {
|
||||
init: function() {
|
||||
var div, entry, type, _i, _len, _ref;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user