diff --git a/Gruntfile.coffee b/Gruntfile.coffee
index c23ced9a1..f400d89a6 100644
--- a/Gruntfile.coffee
+++ b/Gruntfile.coffee
@@ -61,6 +61,7 @@ module.exports = (grunt) ->
files:
'builds/<%= pkg.name %>.meta.js': 'src/General/meta/metadata.js'
'builds/<%= pkg.name %>.user.js': [
+ 'src/General/meta/botproc.js'
'src/General/meta/metadata.js'
'src/General/meta/banner.js'
'src/General/meta/usestrict.js'
diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js
index f5ce94ae5..44df79589 100644
--- a/builds/4chan-X.user.js
+++ b/builds/4chan-X.user.js
@@ -1,3 +1,4 @@
+// Generated by CoffeeScript
// ==UserScript==
// @name 4chan X
// @version 1.2.25
@@ -430,13 +431,12 @@
fd = new FormData();
for (key in form) {
val = form[key];
- if (!val) {
- continue;
- }
- if (val.size && val.name) {
- fd.append(key, val, val.name);
- } else {
- fd.append(key, val);
+ if (val) {
+ if (val.size && val.name) {
+ fd.append(key, val, val.name);
+ } else {
+ fd.append(key, val);
+ }
}
}
return fd;
@@ -1080,7 +1080,7 @@
_ref1 = Get.allQuotelinksLinkingTo(this);
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
quotelink = _ref1[_j];
- if ($.hasClass(quotelink, 'deadlink')) {
+ if (!(!$.hasClass(quotelink, 'deadlink'))) {
continue;
}
$.add(quotelink, $.tn('\u00A0(Dead)'));
@@ -1844,6 +1844,7 @@
date: data.now,
dateUTC: data.time,
comment: data.com,
+ capReps: data.capcode_replies,
isSticky: !!data.sticky,
isClosed: !!data.closed
};
@@ -1871,9 +1872,9 @@
@license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
*/
- var a, boardID, capcode, capcodeClass, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref;
+ var a, array, boardID, capReps, capcode, capcodeClass, capcodeReplies, capcodeStart, capcodeType, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, generateCapcodeReplies, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref;
- postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, file = o.file;
+ postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capReps = o.capReps, file = o.file;
isOP = postID === threadID;
staticPath = '//static.4chan.org/image/';
if (email) {
@@ -1947,10 +1948,32 @@
tripcode = tripcode ? " " + tripcode + "" : '';
sticky = isSticky ? "
" : '';
closed = isClosed ? "
" : '';
+ capcodeReplies = '';
+ if (capReps) {
+ generateCapcodeReplies = function(capcodeType, array) {
+ return "" + ((function() {
+ switch (capcodeType) {
+ case 'admin':
+ return 'Administrator';
+ case 'mod':
+ return 'Moderator';
+ case 'developer':
+ return 'Developer';
+ }
+ })()) + " Repl" + (array.length > 1 ? 'ies' : 'y') + ": " + (array.map(function(ID) {
+ return ">>" + ID + "";
+ }).join(' ')) + "
";
+ };
+ for (capcodeType in capReps) {
+ array = capReps[capcodeType];
+ capcodeReplies += generateCapcodeReplies(capcodeType, array);
+ }
+ capcodeReplies = "
" + capcodeReplies + "";
+ }
container = $.el('div', {
id: "pc" + postID,
className: "postContainer " + (isOP ? 'op' : 'reply') + "Container",
- innerHTML: (isOP ? '' : "
>>
") + ("") + ("
") + ("
") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + ("
") + ("" + subject + " ") + ("
") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("
" + date + " ") + "
" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + "
") + '
'
+ innerHTML: (isOP ? '' : ">>
") + ("") + ("
") + ("
") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + ("
") + ("" + subject + " ") + ("
") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("
" + date + " ") + "
" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + capcodeReplies + "
") + '
'
});
_ref = $$('.quotelink', container);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -4328,6 +4351,9 @@
len = snapshot.snapshotLength;
while (++i < len) {
node = snapshot.snapshotItem(i);
+ if (node.parentElement.nodeName === "A") {
+ continue;
+ }
data = node.data;
if (Linkify.regString.test(data)) {
Linkify.regString.lastIndex = 0;
@@ -4360,7 +4386,7 @@
index = match.index;
link = match[0];
len2 = index + link.length;
- if (len - len2 === 0) {
+ if (len === len2) {
break;
}
range = document.createRange();
@@ -4393,10 +4419,7 @@
}
}
if (range.collapsed) {
- if (node.nodeName === 'WBR') {
- node = node.previousSibling;
- }
- range.setEnd(node, node.length);
+ range.setEndAfter(node);
}
return Linkify.makeLink(range, post);
},
@@ -4428,21 +4451,28 @@
}
},
embed: function(data) {
- var embed, key, link, options, uid;
+ 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', {
- name: uid,
- option: options,
className: 'embedder',
href: 'javascript:;',
textContent: '(embed)'
});
- embed.dataset.service = key;
- embed.dataset.originalurl = link.href;
- $.addClass(link, "" + embed.dataset.service);
+ _ref = {
+ key: key,
+ href: href,
+ uid: uid,
+ options: options
+ };
+ for (name in _ref) {
+ value = _ref[name];
+ embed.dataset[name] = value;
+ }
+ $.addClass(link, "" + embed.dataset.key);
$.on(embed, 'click', Linkify.cb.toggle);
- return $.after(link, [$.tn(' '), embed]);
+ $.after(link, [$.tn(' '), embed]);
},
title: function(data) {
var err, key, link, options, service, title, titles, uid;
@@ -4488,23 +4518,24 @@
embed: function(a) {
var el, style, type;
- el = (type = Linkify.types[a.dataset.service]).el.call(a);
+ el = (type = Linkify.types[a.dataset.key]).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;
+ var el, href;
+ href = a.dataset.href;
el = $.el('a', {
rel: 'nofollow noreferrer',
target: 'blank',
className: 'linkify',
- href: url = a.dataset.originalurl,
- textContent: a.dataset.title || url
+ href: href,
+ textContent: a.dataset.title || href
});
a.textContent = '(embed)';
- $.addClass(el, "" + a.dataset.service);
+ $.addClass(el, "" + a.dataset.key);
return el;
},
title: function(data) {
@@ -4532,108 +4563,13 @@
}
},
types: {
- YouTube: {
- regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
- el: function() {
- return $.el('iframe', {
- src: "//www.youtube.com/embed/" + this.name + (this.option ? '#' + this.option : '') + "?wmode=opaque"
- });
- },
- 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() {
- return JSON.parse(this.responseText).entry.title.$t;
- }
- }
- },
- Vocaroo: {
- regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
- style: 'border: 0; width: 150px; height: 45px;',
- el: function() {
- return $.el('object', {
- innerHTML: ""
- });
- }
- },
- Vimeo: {
- regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
- el: function() {
- return $.el('iframe', {
- src: "//player.vimeo.com/video/" + this.name + "?wmode=opaque"
- });
- },
- title: {
- api: function(uid) {
- return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
- },
- text: function() {
- return JSON.parse(this.responseText).title;
- }
- }
- },
- LiveLeak: {
- regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
- el: function() {
- return $.el('object', {
- innerHTML: ""
- });
- }
- },
audio: {
regExp: /(.*\.(mp3|ogg|wav))$/,
el: function() {
return $.el('audio', {
controls: 'controls',
preload: 'auto',
- src: this.name
- });
- }
- },
- image: {
- regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
- style: 'border: 0; width: auto; height: auto;',
- el: function() {
- return $.el('div', {
- innerHTML: "
"
- });
- }
- },
- SoundCloud: {
- regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
- style: 'height: auto; width: 500px; display: inline-block;',
- el: function() {
- 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/" + this.name, {
- div: div,
- onloadend: function() {
- return this.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 JSON.parse(this.responseText).title;
- }
- }
- },
- pastebin: {
- regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
- el: function() {
- var div;
-
- return div = $.el('iframe', {
- src: "http://pastebin.com/embed_iframe.php?i=" + this.name
+ src: this.dataset.uid
});
}
},
@@ -4643,7 +4579,7 @@
var div;
return div = $.el('iframe', {
- src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.name + ".js"
+ src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.dataset.uid + ".js"
});
},
title: {
@@ -4662,13 +4598,138 @@
}
}
},
+ image: {
+ regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
+ style: 'border: 0; width: auto; height: auto;',
+ el: function() {
+ return $.el('div', {
+ innerHTML: "
"
+ });
+ }
+ },
InstallGentoo: {
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/,
el: function() {
return $.el('iframe', {
- src: "http://paste.installgentoo.com/view/embed/" + this.name
+ src: "http://paste.installgentoo.com/view/embed/" + this.dataset.uid
});
}
+ },
+ LiveLeak: {
+ regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
+ el: function() {
+ return $.el('object', {
+ innerHTML: ""
+ });
+ }
+ },
+ pastebin: {
+ regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
+ el: function() {
+ var div;
+
+ return div = $.el('iframe', {
+ src: "http://pastebin.com/embed_iframe.php?i=" + this.dataset.uid
+ });
+ }
+ },
+ SoundCloud: {
+ regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
+ style: 'height: auto; width: 500px; display: inline-block;',
+ el: function() {
+ 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/" + this.dataset.uid, {
+ div: div,
+ onloadend: function() {
+ return this.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 JSON.parse(this.responseText).title;
+ }
+ }
+ },
+ TwitchTV: {
+ regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/,
+ style: "border: none; width: 640px; height: 360px;",
+ el: function() {
+ var channel, chapter, result, _;
+
+ if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(this.dataset.uid)) {
+ _ = result[0], channel = result[1], chapter = result[2];
+ return $.el('object', {
+ data: 'http://www.twitch.tv/widgets/archive_embed_player.swf',
+ innerHTML: "\n"
+ });
+ } else {
+ channel = (/(\w+)/.exec(this.dataset.uid))[0];
+ return $.el('object', {
+ data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel,
+ innerHTML: "\n\n"
+ });
+ }
+ }
+ },
+ Vocaroo: {
+ regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
+ style: 'border: 0; width: 150px; height: 45px;',
+ el: function() {
+ return $.el('object', {
+ innerHTML: ""
+ });
+ }
+ },
+ Vimeo: {
+ regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
+ el: function() {
+ return $.el('iframe', {
+ src: "//player.vimeo.com/video/" + this.dataset.uid + "?wmode=opaque"
+ });
+ },
+ title: {
+ api: function(uid) {
+ return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
+ },
+ text: function() {
+ return JSON.parse(this.responseText).title;
+ }
+ }
+ },
+ Vine: {
+ regExp: /.*(?:vine.co\/)([^#\&\?]*).*/,
+ style: 'border: none; width: 500px; height: 500px;',
+ el: function() {
+ return $.el('iframe', {
+ src: "https://vine.co/" + this.dataset.uid + "/card"
+ });
+ }
+ },
+ YouTube: {
+ regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
+ el: function() {
+ return $.el('iframe', {
+ src: "//www.youtube.com/embed/" + this.dataset.uid + (this.dataset.option ? '#' + this.dataset.option : '') + "?wmode=opaque"
+ });
+ },
+ 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() {
+ return JSON.parse(this.responseText).entry.title.$t;
+ }
+ }
}
}
};
@@ -4958,12 +5019,11 @@
list = $("#list-" + type, QR.nodes.el);
for (_i = 0, _len = arr.length; _i < _len; _i++) {
val = arr[_i];
- if (!val) {
- continue;
+ if (val) {
+ $.add(list, $.el('option', {
+ textContent: val
+ }));
}
- $.add(list, $.el('option', {
- textContent: val
- }));
}
},
getPassword: function() {
@@ -9870,14 +9930,13 @@
_ref = Config.hotkeys;
for (key in _ref) {
val = _ref[key];
- if (!(key in data.Conf)) {
- continue;
+ if (key in data.Conf) {
+ data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, function(s) {
+ return "" + (s[0].toUpperCase()) + s.slice(1);
+ }).replace(/(^|.+\+)[A-Z]$/g, function(s) {
+ return "Shift+" + s.slice(0, -1) + (s.slice(-1).toLowerCase());
+ });
}
- data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, function(s) {
- return "" + (s[0].toUpperCase()) + s.slice(1);
- }).replace(/(^|.+\+)[A-Z]$/g, function(s) {
- return "Shift+" + s.slice(0, -1) + (s.slice(-1).toLowerCase());
- });
}
data.Conf.WatchedThreads = data.WatchedThreads;
} else if (version[0] === '3') {
diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js
index 1d16d7f9c..a353d21fb 100644
--- a/builds/appchan-x.user.js
+++ b/builds/appchan-x.user.js
@@ -1,3 +1,4 @@
+// Generated by CoffeeScript
// ==UserScript==
// @name appchan x
// @version 2.2.2
@@ -2787,13 +2788,12 @@
fd = new FormData();
for (key in form) {
val = form[key];
- if (!val) {
- continue;
- }
- if (val.size && val.name) {
- fd.append(key, val, val.name);
- } else {
- fd.append(key, val);
+ if (val) {
+ if (val.size && val.name) {
+ fd.append(key, val, val.name);
+ } else {
+ fd.append(key, val);
+ }
}
}
return fd;
@@ -3437,7 +3437,7 @@
_ref1 = Get.allQuotelinksLinkingTo(this);
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
quotelink = _ref1[_j];
- if ($.hasClass(quotelink, 'deadlink')) {
+ if (!(!$.hasClass(quotelink, 'deadlink'))) {
continue;
}
$.add(quotelink, $.tn('\u00A0(Dead)'));
@@ -4140,6 +4140,7 @@
date: data.now,
dateUTC: data.time,
comment: data.com,
+ capReps: data.capcode_replies,
isSticky: !!data.sticky,
isClosed: !!data.closed
};
@@ -4167,9 +4168,9 @@
@license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
*/
- var a, boardID, capcode, capcodeClass, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref;
+ var a, array, boardID, capReps, capcode, capcodeClass, capcodeReplies, capcodeStart, capcodeType, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, generateCapcodeReplies, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref;
- postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, file = o.file;
+ postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capReps = o.capReps, file = o.file;
isOP = postID === threadID;
staticPath = '//static.4chan.org/image/';
if (email) {
@@ -4243,10 +4244,32 @@
tripcode = tripcode ? " " + tripcode + "" : '';
sticky = isSticky ? "
" : '';
closed = isClosed ? "
" : '';
+ capcodeReplies = '';
+ if (capReps) {
+ generateCapcodeReplies = function(capcodeType, array) {
+ return "" + ((function() {
+ switch (capcodeType) {
+ case 'admin':
+ return 'Administrator';
+ case 'mod':
+ return 'Moderator';
+ case 'developer':
+ return 'Developer';
+ }
+ })()) + " Repl" + (array.length > 1 ? 'ies' : 'y') + ": " + (array.map(function(ID) {
+ return ">>" + ID + "";
+ }).join(' ')) + "
";
+ };
+ for (capcodeType in capReps) {
+ array = capReps[capcodeType];
+ capcodeReplies += generateCapcodeReplies(capcodeType, array);
+ }
+ capcodeReplies = "
" + capcodeReplies + "";
+ }
container = $.el('div', {
id: "pc" + postID,
className: "postContainer " + (isOP ? 'op' : 'reply') + "Container",
- innerHTML: (isOP ? '' : ">>
") + ("") + ("
") + ("
") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + ("
") + ("" + subject + " ") + ("
") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("
" + date + " ") + "
" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + "
") + '
'
+ innerHTML: (isOP ? '' : ">>
") + ("") + ("
") + ("
") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + ("
") + ("" + subject + " ") + ("
") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("
" + date + " ") + "
" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + capcodeReplies + "
") + '
'
});
_ref = $$('.quotelink', container);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -6620,6 +6643,9 @@
len = snapshot.snapshotLength;
while (++i < len) {
node = snapshot.snapshotItem(i);
+ if (node.parentElement.nodeName === "A") {
+ continue;
+ }
data = node.data;
if (Linkify.regString.test(data)) {
Linkify.regString.lastIndex = 0;
@@ -6652,7 +6678,7 @@
index = match.index;
link = match[0];
len2 = index + link.length;
- if (len - len2 === 0) {
+ if (len === len2) {
break;
}
range = document.createRange();
@@ -6685,10 +6711,7 @@
}
}
if (range.collapsed) {
- if (node.nodeName === 'WBR') {
- node = node.previousSibling;
- }
- range.setEnd(node, node.length);
+ range.setEndAfter(node);
}
return Linkify.makeLink(range, post);
},
@@ -6720,21 +6743,28 @@
}
},
embed: function(data) {
- var embed, key, link, options, uid;
+ 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', {
- name: uid,
- option: options,
className: 'embedder',
href: 'javascript:;',
textContent: '(embed)'
});
- embed.dataset.service = key;
- embed.dataset.originalurl = link.href;
- $.addClass(link, "" + embed.dataset.service);
+ _ref = {
+ key: key,
+ href: href,
+ uid: uid,
+ options: options
+ };
+ for (name in _ref) {
+ value = _ref[name];
+ embed.dataset[name] = value;
+ }
+ $.addClass(link, "" + embed.dataset.key);
$.on(embed, 'click', Linkify.cb.toggle);
- return $.after(link, [$.tn(' '), embed]);
+ $.after(link, [$.tn(' '), embed]);
},
title: function(data) {
var err, key, link, options, service, title, titles, uid;
@@ -6780,23 +6810,24 @@
embed: function(a) {
var el, style, type;
- el = (type = Linkify.types[a.dataset.service]).el.call(a);
+ el = (type = Linkify.types[a.dataset.key]).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;
+ var el, href;
+ href = a.dataset.href;
el = $.el('a', {
rel: 'nofollow noreferrer',
target: 'blank',
className: 'linkify',
- href: url = a.dataset.originalurl,
- textContent: a.dataset.title || url
+ href: href,
+ textContent: a.dataset.title || href
});
a.textContent = '(embed)';
- $.addClass(el, "" + a.dataset.service);
+ $.addClass(el, "" + a.dataset.key);
return el;
},
title: function(data) {
@@ -6824,108 +6855,13 @@
}
},
types: {
- YouTube: {
- regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
- el: function() {
- return $.el('iframe', {
- src: "//www.youtube.com/embed/" + this.name + (this.option ? '#' + this.option : '') + "?wmode=opaque"
- });
- },
- 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() {
- return JSON.parse(this.responseText).entry.title.$t;
- }
- }
- },
- Vocaroo: {
- regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
- style: 'border: 0; width: 150px; height: 45px;',
- el: function() {
- return $.el('object', {
- innerHTML: ""
- });
- }
- },
- Vimeo: {
- regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
- el: function() {
- return $.el('iframe', {
- src: "//player.vimeo.com/video/" + this.name + "?wmode=opaque"
- });
- },
- title: {
- api: function(uid) {
- return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
- },
- text: function() {
- return JSON.parse(this.responseText).title;
- }
- }
- },
- LiveLeak: {
- regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
- el: function() {
- return $.el('object', {
- innerHTML: ""
- });
- }
- },
audio: {
regExp: /(.*\.(mp3|ogg|wav))$/,
el: function() {
return $.el('audio', {
controls: 'controls',
preload: 'auto',
- src: this.name
- });
- }
- },
- image: {
- regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
- style: 'border: 0; width: auto; height: auto;',
- el: function() {
- return $.el('div', {
- innerHTML: "
"
- });
- }
- },
- SoundCloud: {
- regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
- style: 'height: auto; width: 500px; display: inline-block;',
- el: function() {
- 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/" + this.name, {
- div: div,
- onloadend: function() {
- return this.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 JSON.parse(this.responseText).title;
- }
- }
- },
- pastebin: {
- regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
- el: function() {
- var div;
-
- return div = $.el('iframe', {
- src: "http://pastebin.com/embed_iframe.php?i=" + this.name
+ src: this.dataset.uid
});
}
},
@@ -6935,7 +6871,7 @@
var div;
return div = $.el('iframe', {
- src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.name + ".js"
+ src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.dataset.uid + ".js"
});
},
title: {
@@ -6954,13 +6890,138 @@
}
}
},
+ image: {
+ regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
+ style: 'border: 0; width: auto; height: auto;',
+ el: function() {
+ return $.el('div', {
+ innerHTML: "
"
+ });
+ }
+ },
InstallGentoo: {
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/,
el: function() {
return $.el('iframe', {
- src: "http://paste.installgentoo.com/view/embed/" + this.name
+ src: "http://paste.installgentoo.com/view/embed/" + this.dataset.uid
});
}
+ },
+ LiveLeak: {
+ regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
+ el: function() {
+ return $.el('object', {
+ innerHTML: ""
+ });
+ }
+ },
+ pastebin: {
+ regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
+ el: function() {
+ var div;
+
+ return div = $.el('iframe', {
+ src: "http://pastebin.com/embed_iframe.php?i=" + this.dataset.uid
+ });
+ }
+ },
+ SoundCloud: {
+ regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
+ style: 'height: auto; width: 500px; display: inline-block;',
+ el: function() {
+ 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/" + this.dataset.uid, {
+ div: div,
+ onloadend: function() {
+ return this.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 JSON.parse(this.responseText).title;
+ }
+ }
+ },
+ TwitchTV: {
+ regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/,
+ style: "border: none; width: 640px; height: 360px;",
+ el: function() {
+ var channel, chapter, result, _;
+
+ if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(this.dataset.uid)) {
+ _ = result[0], channel = result[1], chapter = result[2];
+ return $.el('object', {
+ data: 'http://www.twitch.tv/widgets/archive_embed_player.swf',
+ innerHTML: "\n"
+ });
+ } else {
+ channel = (/(\w+)/.exec(this.dataset.uid))[0];
+ return $.el('object', {
+ data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel,
+ innerHTML: "\n\n"
+ });
+ }
+ }
+ },
+ Vocaroo: {
+ regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
+ style: 'border: 0; width: 150px; height: 45px;',
+ el: function() {
+ return $.el('object', {
+ innerHTML: ""
+ });
+ }
+ },
+ Vimeo: {
+ regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
+ el: function() {
+ return $.el('iframe', {
+ src: "//player.vimeo.com/video/" + this.dataset.uid + "?wmode=opaque"
+ });
+ },
+ title: {
+ api: function(uid) {
+ return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
+ },
+ text: function() {
+ return JSON.parse(this.responseText).title;
+ }
+ }
+ },
+ Vine: {
+ regExp: /.*(?:vine.co\/)([^#\&\?]*).*/,
+ style: 'border: none; width: 500px; height: 500px;',
+ el: function() {
+ return $.el('iframe', {
+ src: "https://vine.co/" + this.dataset.uid + "/card"
+ });
+ }
+ },
+ YouTube: {
+ regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
+ el: function() {
+ return $.el('iframe', {
+ src: "//www.youtube.com/embed/" + this.dataset.uid + (this.dataset.option ? '#' + this.dataset.option : '') + "?wmode=opaque"
+ });
+ },
+ 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() {
+ return JSON.parse(this.responseText).entry.title.$t;
+ }
+ }
}
}
};
@@ -7242,12 +7303,11 @@
list = $("#list-" + type, QR.nodes.el);
for (_i = 0, _len = arr.length; _i < _len; _i++) {
val = arr[_i];
- if (!val) {
- continue;
+ if (val) {
+ $.add(list, $.el('option', {
+ textContent: val
+ }));
}
- $.add(list, $.el('option', {
- textContent: val
- }));
}
},
getPassword: function() {
diff --git a/builds/crx/script.js b/builds/crx/script.js
index 6470fd0e9..0c36aab39 100644
--- a/builds/crx/script.js
+++ b/builds/crx/script.js
@@ -2770,13 +2770,12 @@
fd = new FormData();
for (key in form) {
val = form[key];
- if (!val) {
- continue;
- }
- if (val.size && val.name) {
- fd.append(key, val, val.name);
- } else {
- fd.append(key, val);
+ if (val) {
+ if (val.size && val.name) {
+ fd.append(key, val, val.name);
+ } else {
+ fd.append(key, val);
+ }
}
}
return fd;
@@ -3451,7 +3450,7 @@
_ref1 = Get.allQuotelinksLinkingTo(this);
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
quotelink = _ref1[_j];
- if ($.hasClass(quotelink, 'deadlink')) {
+ if (!(!$.hasClass(quotelink, 'deadlink'))) {
continue;
}
$.add(quotelink, $.tn('\u00A0(Dead)'));
@@ -4154,6 +4153,7 @@
date: data.now,
dateUTC: data.time,
comment: data.com,
+ capReps: data.capcode_replies,
isSticky: !!data.sticky,
isClosed: !!data.closed
};
@@ -4181,9 +4181,9 @@
@license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
*/
- var a, boardID, capcode, capcodeClass, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref;
+ var a, array, boardID, capReps, capcode, capcodeClass, capcodeReplies, capcodeStart, capcodeType, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, generateCapcodeReplies, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref;
- postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, file = o.file;
+ postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capReps = o.capReps, file = o.file;
isOP = postID === threadID;
staticPath = '//static.4chan.org/image/';
if (email) {
@@ -4257,10 +4257,32 @@
tripcode = tripcode ? " " + tripcode + "" : '';
sticky = isSticky ? "
" : '';
closed = isClosed ? "
" : '';
+ capcodeReplies = '';
+ if (capReps) {
+ generateCapcodeReplies = function(capcodeType, array) {
+ return "" + ((function() {
+ switch (capcodeType) {
+ case 'admin':
+ return 'Administrator';
+ case 'mod':
+ return 'Moderator';
+ case 'developer':
+ return 'Developer';
+ }
+ })()) + " Repl" + (array.length > 1 ? 'ies' : 'y') + ": " + (array.map(function(ID) {
+ return ">>" + ID + "";
+ }).join(' ')) + "
";
+ };
+ for (capcodeType in capReps) {
+ array = capReps[capcodeType];
+ capcodeReplies += generateCapcodeReplies(capcodeType, array);
+ }
+ capcodeReplies = "
" + capcodeReplies + "";
+ }
container = $.el('div', {
id: "pc" + postID,
className: "postContainer " + (isOP ? 'op' : 'reply') + "Container",
- innerHTML: (isOP ? '' : ">>
") + ("") + ("
") + ("
") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + ("
") + ("" + subject + " ") + ("
") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("
" + date + " ") + "
" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + "
") + '
'
+ innerHTML: (isOP ? '' : ">>
") + ("") + ("
") + ("
") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + ("
") + ("" + subject + " ") + ("
") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("
" + date + " ") + "
" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + capcodeReplies + "
") + '
'
});
_ref = $$('.quotelink', container);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -6627,6 +6649,9 @@
len = snapshot.snapshotLength;
while (++i < len) {
node = snapshot.snapshotItem(i);
+ if (node.parentElement.nodeName === "A") {
+ continue;
+ }
data = node.data;
if (Linkify.regString.test(data)) {
Linkify.regString.lastIndex = 0;
@@ -6659,7 +6684,7 @@
index = match.index;
link = match[0];
len2 = index + link.length;
- if (len - len2 === 0) {
+ if (len === len2) {
break;
}
range = document.createRange();
@@ -6692,10 +6717,7 @@
}
}
if (range.collapsed) {
- if (node.nodeName === 'WBR') {
- node = node.previousSibling;
- }
- range.setEnd(node, node.length);
+ range.setEndAfter(node);
}
return Linkify.makeLink(range, post);
},
@@ -6727,21 +6749,28 @@
}
},
embed: function(data) {
- var embed, key, link, options, uid;
+ 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', {
- name: uid,
- option: options,
className: 'embedder',
href: 'javascript:;',
textContent: '(embed)'
});
- embed.dataset.service = key;
- embed.dataset.originalurl = link.href;
- $.addClass(link, "" + embed.dataset.service);
+ _ref = {
+ key: key,
+ href: href,
+ uid: uid,
+ options: options
+ };
+ for (name in _ref) {
+ value = _ref[name];
+ embed.dataset[name] = value;
+ }
+ $.addClass(link, "" + embed.dataset.key);
$.on(embed, 'click', Linkify.cb.toggle);
- return $.after(link, [$.tn(' '), embed]);
+ $.after(link, [$.tn(' '), embed]);
},
title: function(data) {
var err, key, link, options, service, title, titles, uid;
@@ -6787,23 +6816,24 @@
embed: function(a) {
var el, style, type;
- el = (type = Linkify.types[a.dataset.service]).el.call(a);
+ el = (type = Linkify.types[a.dataset.key]).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;
+ var el, href;
+ href = a.dataset.href;
el = $.el('a', {
rel: 'nofollow noreferrer',
target: 'blank',
className: 'linkify',
- href: url = a.dataset.originalurl,
- textContent: a.dataset.title || url
+ href: href,
+ textContent: a.dataset.title || href
});
a.textContent = '(embed)';
- $.addClass(el, "" + a.dataset.service);
+ $.addClass(el, "" + a.dataset.key);
return el;
},
title: function(data) {
@@ -6831,108 +6861,13 @@
}
},
types: {
- YouTube: {
- regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
- el: function() {
- return $.el('iframe', {
- src: "//www.youtube.com/embed/" + this.name + (this.option ? '#' + this.option : '') + "?wmode=opaque"
- });
- },
- 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() {
- return JSON.parse(this.responseText).entry.title.$t;
- }
- }
- },
- Vocaroo: {
- regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
- style: 'border: 0; width: 150px; height: 45px;',
- el: function() {
- return $.el('object', {
- innerHTML: ""
- });
- }
- },
- Vimeo: {
- regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
- el: function() {
- return $.el('iframe', {
- src: "//player.vimeo.com/video/" + this.name + "?wmode=opaque"
- });
- },
- title: {
- api: function(uid) {
- return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
- },
- text: function() {
- return JSON.parse(this.responseText).title;
- }
- }
- },
- LiveLeak: {
- regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
- el: function() {
- return $.el('object', {
- innerHTML: ""
- });
- }
- },
audio: {
regExp: /(.*\.(mp3|ogg|wav))$/,
el: function() {
return $.el('audio', {
controls: 'controls',
preload: 'auto',
- src: this.name
- });
- }
- },
- image: {
- regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
- style: 'border: 0; width: auto; height: auto;',
- el: function() {
- return $.el('div', {
- innerHTML: "
"
- });
- }
- },
- SoundCloud: {
- regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
- style: 'height: auto; width: 500px; display: inline-block;',
- el: function() {
- 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/" + this.name, {
- div: div,
- onloadend: function() {
- return this.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 JSON.parse(this.responseText).title;
- }
- }
- },
- pastebin: {
- regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
- el: function() {
- var div;
-
- return div = $.el('iframe', {
- src: "http://pastebin.com/embed_iframe.php?i=" + this.name
+ src: this.dataset.uid
});
}
},
@@ -6942,7 +6877,7 @@
var div;
return div = $.el('iframe', {
- src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.name + ".js"
+ src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.dataset.uid + ".js"
});
},
title: {
@@ -6961,13 +6896,138 @@
}
}
},
+ image: {
+ regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
+ style: 'border: 0; width: auto; height: auto;',
+ el: function() {
+ return $.el('div', {
+ innerHTML: "
"
+ });
+ }
+ },
InstallGentoo: {
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/,
el: function() {
return $.el('iframe', {
- src: "http://paste.installgentoo.com/view/embed/" + this.name
+ src: "http://paste.installgentoo.com/view/embed/" + this.dataset.uid
});
}
+ },
+ LiveLeak: {
+ regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
+ el: function() {
+ return $.el('object', {
+ innerHTML: ""
+ });
+ }
+ },
+ pastebin: {
+ regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
+ el: function() {
+ var div;
+
+ return div = $.el('iframe', {
+ src: "http://pastebin.com/embed_iframe.php?i=" + this.dataset.uid
+ });
+ }
+ },
+ SoundCloud: {
+ regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
+ style: 'height: auto; width: 500px; display: inline-block;',
+ el: function() {
+ 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/" + this.dataset.uid, {
+ div: div,
+ onloadend: function() {
+ return this.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 JSON.parse(this.responseText).title;
+ }
+ }
+ },
+ TwitchTV: {
+ regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/,
+ style: "border: none; width: 640px; height: 360px;",
+ el: function() {
+ var channel, chapter, result, _;
+
+ if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(this.dataset.uid)) {
+ _ = result[0], channel = result[1], chapter = result[2];
+ return $.el('object', {
+ data: 'http://www.twitch.tv/widgets/archive_embed_player.swf',
+ innerHTML: "\n"
+ });
+ } else {
+ channel = (/(\w+)/.exec(this.dataset.uid))[0];
+ return $.el('object', {
+ data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel,
+ innerHTML: "\n\n"
+ });
+ }
+ }
+ },
+ Vocaroo: {
+ regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
+ style: 'border: 0; width: 150px; height: 45px;',
+ el: function() {
+ return $.el('object', {
+ innerHTML: ""
+ });
+ }
+ },
+ Vimeo: {
+ regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
+ el: function() {
+ return $.el('iframe', {
+ src: "//player.vimeo.com/video/" + this.dataset.uid + "?wmode=opaque"
+ });
+ },
+ title: {
+ api: function(uid) {
+ return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid;
+ },
+ text: function() {
+ return JSON.parse(this.responseText).title;
+ }
+ }
+ },
+ Vine: {
+ regExp: /.*(?:vine.co\/)([^#\&\?]*).*/,
+ style: 'border: none; width: 500px; height: 500px;',
+ el: function() {
+ return $.el('iframe', {
+ src: "https://vine.co/" + this.dataset.uid + "/card"
+ });
+ }
+ },
+ YouTube: {
+ regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
+ el: function() {
+ return $.el('iframe', {
+ src: "//www.youtube.com/embed/" + this.dataset.uid + (this.dataset.option ? '#' + this.dataset.option : '') + "?wmode=opaque"
+ });
+ },
+ 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() {
+ return JSON.parse(this.responseText).entry.title.$t;
+ }
+ }
}
}
};
@@ -7250,12 +7310,11 @@
list = $("#list-" + type, QR.nodes.el);
for (_i = 0, _len = arr.length; _i < _len; _i++) {
val = arr[_i];
- if (!val) {
- continue;
+ if (val) {
+ $.add(list, $.el('option', {
+ textContent: val
+ }));
}
- $.add(list, $.el('option', {
- textContent: val
- }));
}
},
getPassword: function() {
diff --git a/src/General/Build.coffee b/src/General/Build.coffee
index 4f4453e6d..bb0903db1 100644
--- a/src/General/Build.coffee
+++ b/src/General/Build.coffee
@@ -27,6 +27,7 @@ Build =
date: data.now
dateUTC: data.time
comment: data.com
+ capReps: data.capcode_replies
# thread status
isSticky: !!data.sticky
isClosed: !!data.closed
@@ -58,7 +59,7 @@ Build =
postID, threadID, boardID
name, capcode, tripcode, uniqueID, email, subject, flagCode, flagName, date, dateUTC
isSticky, isClosed
- comment
+ comment, capReps
file
} = o
isOP = postID is threadID
@@ -176,22 +177,39 @@ Build =
else
fileHTML = ''
- tripcode =
- if tripcode
- " #{tripcode}"
- else
- ''
+ tripcode = if tripcode
+ " #{tripcode}"
+ else
+ ''
- sticky =
- if isSticky
- "
"
- else
- ''
- closed =
- if isClosed
- "
"
- else
- ''
+ sticky = if isSticky
+ "
"
+ else
+ ''
+ closed = if isClosed
+ "
"
+ else
+ ''
+
+ capcodeReplies = ''
+ if capReps
+ generateCapcodeReplies = (capcodeType, array) ->
+ "#{
+ switch capcodeType
+ when 'admin'
+ 'Administrator'
+ when 'mod'
+ 'Moderator'
+ when 'developer'
+ 'Developer'
+ } Repl#{if array.length > 1 then 'ies' else 'y'}: #{
+ array.map (ID) ->
+ ">>#{ID}"
+ .join ' '
+ }
"
+ for capcodeType, array of capReps
+ capcodeReplies += generateCapcodeReplies capcodeType, array
+ capcodeReplies = "
#{capcodeReplies}"
container = $.el 'div',
id: "pc#{postID}"
@@ -245,7 +263,7 @@ Build =
(if isOP then '' else fileHTML) +
- "#{comment or ''}
" +
+ "#{comment or ''}#{capcodeReplies}
" +
''
diff --git a/src/General/lib/$.coffee b/src/General/lib/$.coffee
index 8cf3f31b6..a9afda0bb 100644
--- a/src/General/lib/$.coffee
+++ b/src/General/lib/$.coffee
@@ -61,8 +61,7 @@ $.formData = (form) ->
if form instanceof HTMLFormElement
return new FormData form
fd = new FormData()
- for key, val of form
- continue unless val
+ for key, val of form when val
# XXX GM bug
# if val instanceof Blob
if val.size and val.name
diff --git a/src/General/lib/post.class b/src/General/lib/post.class
index 2b5c26aa4..02e9fb9a0 100644
--- a/src/General/lib/post.class
+++ b/src/General/lib/post.class
@@ -174,8 +174,7 @@ class Post
return if file
# Get quotelinks/backlinks to this post
# and paint them (Dead).
- for quotelink in Get.allQuotelinksLinkingTo @
- continue if $.hasClass quotelink, 'deadlink'
+ for quotelink in Get.allQuotelinksLinkingTo @ when not $.hasClass quotelink, 'deadlink'
$.add quotelink, $.tn '\u00A0(Dead)'
$.addClass quotelink, 'deadlink'
return
diff --git a/src/Linkification/Linkify.coffee b/src/Linkification/Linkify.coffee
index c32ec484e..ba46a0c58 100644
--- a/src/Linkification/Linkify.coffee
+++ b/src/Linkification/Linkify.coffee
@@ -44,6 +44,9 @@ Linkify =
while ++i < len
node = snapshot.snapshotItem i
+
+ continue if node.parentElement.nodeName is "A"
+
data = node.data
if Linkify.regString.test data
@@ -69,7 +72,7 @@ Linkify =
link = match[0]
len2 = index + link.length
- break if len - len2 is 0
+ break if len is len2
range = document.createRange();
range.setStart node, index
@@ -99,9 +102,7 @@ Linkify =
range.setEnd node, result.index
if range.collapsed
- if node.nodeName is 'WBR'
- node = node.previousSibling
- range.setEnd node, node.length
+ range.setEndAfter node
Linkify.makeLink range, post
@@ -137,20 +138,20 @@ Linkify =
embed: (data) ->
[key, uid, options, link] = data
+ href = link.href
embed = $.el 'a',
- name: uid
- option: options
className: 'embedder'
href: 'javascript:;'
textContent: '(embed)'
- embed.dataset.service = key
- embed.dataset.originalurl = link.href
+ for name, value of {key, href, uid, options}
+ embed.dataset[name] = value
- $.addClass link, "#{embed.dataset.service}"
+ $.addClass link, "#{embed.dataset.key}"
$.on embed, 'click', Linkify.cb.toggle
$.after link, [$.tn(' '), embed]
+ return
title: (data) ->
[key, uid, options, link] = data
@@ -190,7 +191,7 @@ Linkify =
embed: (a) ->
# We create an element to embed
- el = (type = Linkify.types[a.dataset.service]).el.call a
+ el = (type = Linkify.types[a.dataset.key]).el.call a
# Set style values.
el.style.cssText = if style = type.style
@@ -204,15 +205,16 @@ Linkify =
unembed: (a) ->
# Recreate the original link.
+ {href} = a.dataset
el = $.el 'a',
rel: 'nofollow noreferrer'
target: 'blank'
className: 'linkify'
- href: url = a.dataset.originalurl
- textContent: a.dataset.title or url
+ href: href
+ textContent: a.dataset.title or href
a.textContent = '(embed)'
- $.addClass el, "#{a.dataset.service}"
+ $.addClass el, "#{a.dataset.key}"
return el
@@ -233,51 +235,50 @@ Linkify =
"[#{key}] #{@status}'d"
types:
- YouTube:
- regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/
- el: ->
- $.el 'iframe',
- src: "//www.youtube.com/embed/#{@name}#{if @option then '#' + @option else ''}?wmode=opaque"
- title:
- 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:
- regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/
- style: 'border: 0; width: 150px; height: 45px;'
- el: ->
- $.el 'object',
- innerHTML: ""
-
- Vimeo:
- regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/
- el: ->
- $.el 'iframe',
- src: "//player.vimeo.com/video/#{@name}?wmode=opaque"
- title:
- api: (uid) -> "https://vimeo.com/api/oembed.json?url=http://vimeo.com/#{uid}"
- text: -> JSON.parse(@responseText).title
-
- LiveLeak:
- regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/
- el: ->
- $.el 'object',
- innerHTML: ""
-
audio:
- regExp: /(.*\.(mp3|ogg|wav))$/
+ regExp: /(.*\.(mp3|ogg|wav))$/
el: ->
$.el 'audio',
controls: 'controls'
preload: 'auto'
- src: @name
+ src: @dataset.uid
+
+ gist:
+ regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/
+ el: ->
+ div = $.el 'iframe',
+ # 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/#{@dataset.uid}.js"
+ title:
+ api: (uid) -> "https://api.github.com/gists/#{uid}"
+ text: ->
+ response = JSON.parse(@responseText).files
+ return file for file of response when response.hasOwnProperty file
image:
- regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/
+ regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/
style: 'border: 0; width: auto; height: auto;'
el: ->
$.el 'div',
- innerHTML: "
"
+ innerHTML: "
"
+
+ InstallGentoo:
+ regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/
+ el: ->
+ $.el 'iframe',
+ src: "http://paste.installgentoo.com/view/embed/#{@dataset.uid}"
+
+ LiveLeak:
+ regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/
+ el: ->
+ $.el 'object',
+ innerHTML: ""
+
+ pastebin:
+ regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/
+ el: ->
+ div = $.el 'iframe',
+ src: "http://pastebin.com/embed_iframe.php?i=#{@dataset.uid}"
SoundCloud:
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
@@ -287,7 +288,7 @@ Linkify =
className: "soundcloud"
name: "soundcloud"
$.ajax(
- "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{@name}"
+ "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{@dataset.uid}"
div: div
onloadend: ->
@div.innerHTML = JSON.parse(@responseText).html
@@ -297,26 +298,59 @@ Linkify =
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:
- regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/
+ TwitchTV:
+ regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/
+ style: "border: none; width: 640px; height: 360px;"
el: ->
- div = $.el 'iframe',
- src: "http://pastebin.com/embed_iframe.php?i=#{@name}"
+ if result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec @dataset.uid
+ [_, channel, chapter] = result
- gist:
- regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/
+ $.el 'object',
+ data: 'http://www.twitch.tv/widgets/archive_embed_player.swf'
+ innerHTML: """
+
+
+"""
+
+ else
+ channel = (/(\w+)/.exec @dataset.uid)[0]
+
+ $.el 'object',
+ data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=#{channel}"
+ innerHTML: """
+
+
+
+"""
+
+ Vocaroo:
+ regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/
+ style: 'border: 0; width: 150px; height: 45px;'
el: ->
- div = $.el 'iframe',
- # 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: (uid) -> "https://api.github.com/gists/#{uid}"
- text: ->
- response = JSON.parse(@responseText).files
- return file for file of response when response.hasOwnProperty file
+ $.el 'object',
+ innerHTML: ""
- InstallGentoo:
- regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/
+ Vimeo:
+ regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/
el: ->
$.el 'iframe',
- src: "http://paste.installgentoo.com/view/embed/#{@name}"
\ No newline at end of file
+ src: "//player.vimeo.com/video/#{@dataset.uid}?wmode=opaque"
+ title:
+ api: (uid) -> "https://vimeo.com/api/oembed.json?url=http://vimeo.com/#{uid}"
+ text: -> JSON.parse(@responseText).title
+
+ Vine:
+ regExp: /.*(?:vine.co\/)([^#\&\?]*).*/
+ style: 'border: none; width: 500px; height: 500px;'
+ el: ->
+ $.el 'iframe',
+ src: "https://vine.co/#{@dataset.uid}/card"
+
+ YouTube:
+ regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/
+ el: ->
+ $.el 'iframe',
+ src: "//www.youtube.com/embed/#{@dataset.uid}#{if @dataset.option then '#' + @dataset.option else ''}?wmode=opaque"
+ title:
+ 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
\ No newline at end of file
diff --git a/src/Posting/QuickReply.coffee b/src/Posting/QuickReply.coffee
index 2be479ea3..18104756e 100644
--- a/src/Posting/QuickReply.coffee
+++ b/src/Posting/QuickReply.coffee
@@ -215,9 +215,7 @@ QR =
loadPersonas: (type, arr) ->
list = $ "#list-#{type}", QR.nodes.el
- for val in arr
- # XXX Firefox displays empty