diff --git a/LICENSE b/LICENSE
index 9ec89a5f9..4a6afc0ea 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
/*
-* appchan x - Version 2.2.2 - 2013-08-07
+* appchan x - Version 2.2.2 - 2013-08-08
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js
index a54e6a059..f1fcb88a2 100644
--- a/builds/4chan-X.user.js
+++ b/builds/4chan-X.user.js
@@ -19,7 +19,7 @@
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC
// ==/UserScript==
/*
-* 4chan X - Version 1.2.25 - 2013-08-07
+* 4chan X - Version 1.2.25 - 2013-08-08
*
* Licensed under the MIT license.
* https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
@@ -336,15 +336,6 @@
return this.indexOf(string) > -1;
};
- Array.prototype.add = function(object, position) {
- var keep;
-
- keep = this.slice(position);
- this.length = position;
- this.push(object);
- return this.pushArrays(keep);
- };
-
Array.prototype.contains = function(object) {
return this.indexOf(object) > -1;
};
@@ -361,27 +352,6 @@
return i;
};
- Array.prototype.pushArrays = function() {
- var arg, args, _i, _len;
-
- args = arguments;
- for (_i = 0, _len = args.length; _i < _len; _i++) {
- arg = args[_i];
- this.push.apply(this, arg);
- }
- return this;
- };
-
- Array.prototype.remove = function(object) {
- var index;
-
- if ((index = this.indexOf(object)) > -1) {
- return this.splice(index, 1);
- } else {
- return false;
- }
- };
-
$ = function(selector, root) {
if (root == null) {
root = d.body;
@@ -441,13 +411,22 @@
return fd;
};
- $.ajax = function(url, callbacks, opts) {
- var cred, err, form, headers, key, r, sync, type, upCallbacks, val;
+ $.extend = function(object, properties) {
+ var key, val;
- if (opts == null) {
- opts = {};
+ for (key in properties) {
+ val = properties[key];
+ object[key] = val;
}
- type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
+ };
+
+ $.ajax = function(url, options, extra) {
+ var form, headers, key, r, sync, type, upCallbacks, val;
+
+ if (extra == null) {
+ extra = {};
+ }
+ type = extra.type, headers = extra.headers, upCallbacks = extra.upCallbacks, form = extra.form, sync = extra.sync;
r = new XMLHttpRequest();
r.overrideMimeType('text/html');
type || (type = form && 'post' || 'get');
@@ -456,13 +435,8 @@
val = headers[key];
r.setRequestHeader(key, val);
}
- $.extend(r, callbacks);
+ $.extend(r, options);
$.extend(r.upload, upCallbacks);
- try {
- r.withCredentials = cred;
- } catch (_error) {
- err = _error;
- }
r.send(form);
return r;
};
@@ -1642,7 +1616,11 @@
a.dataset.only = m[1];
a.href = "//boards.4chan.org/" + board + "/";
if (m[1] === 'catalog') {
- a.href += 'catalog';
+ if (Conf['External Catalog']) {
+ a.href = CatalogLinks.external(board);
+ } else {
+ a.href += 'catalog';
+ }
$.addClass(a, 'catalog');
}
}
@@ -3679,7 +3657,7 @@
if (Conf['Quote Inlining']) {
$.on(link, 'click', QuoteInline.toggle);
if (Conf['Quote Hash Navigation']) {
- frag.pushArrays(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
+ frag.push.apply(frag, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
}
}
$.add(container, frag);
@@ -3755,9 +3733,6 @@
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
return;
}
- if (Conf['Comment Expansion']) {
- ExpandComment.callbacks.push(this.node);
- }
if (Conf['Quote Hash Navigation']) {
this.node = function() {
var link, _i, _len, _ref;
@@ -3782,6 +3757,9 @@
}
};
}
+ if (Conf['Comment Expansion']) {
+ ExpandComment.callbacks.push(this.node);
+ }
return Post.prototype.callbacks.push({
name: 'Quote Inlining',
cb: this.node
@@ -5968,7 +5946,7 @@
},
preSubmitHooks: [],
submit: function(e) {
- var callbacks, challenge, err, filetag, hook, opts, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
+ var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
if (e != null) {
e.preventDefault();
@@ -6047,7 +6025,9 @@
recaptcha_challenge_field: challenge,
recaptcha_response_field: response
};
- callbacks = {
+ options = {
+ responseType: 'document',
+ withCredentials: true,
onload: QR.response,
onerror: function() {
delete QR.req;
@@ -6055,12 +6035,11 @@
QR.cooldown.auto = false;
QR.status();
return QR.error($.el('span', {
- innerHTML: "4chan X encountered an error while posting. Please try again. \n[?]"
+ innerHTML: "4chan X encountered an error while posting. Please try again.\n[?]"
}));
}
};
- opts = {
- cred: true,
+ extra = {
form: $.formData(postData),
upCallbacks: {
onload: function() {
@@ -6075,30 +6054,29 @@
}
}
};
- QR.req = $.ajax($.id('postForm').parentNode.action, callbacks, opts);
+ QR.req = $.ajax($.id('postForm').parentNode.action, options, extra);
QR.req.uploadStartTime = Date.now();
QR.req.progress = '...';
return QR.status();
},
response: function() {
- var URL, ban, board, err, h1, isReply, m, post, postID, req, threadID, tmpDoc, _, _ref, _ref1;
+ var URL, ban, board, err, h1, isReply, m, post, postID, req, resDoc, threadID, _, _ref, _ref1;
req = QR.req;
delete QR.req;
post = QR.posts[0];
post.unlock();
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = req.response;
- if (ban = $('.banType', tmpDoc)) {
- board = $('.board', tmpDoc).innerHTML;
+ resDoc = req.response;
+ if (ban = $('.banType', resDoc)) {
+ board = $('.board', resDoc).innerHTML;
err = $.el('span', {
- innerHTML: ban.textContent.toLowerCase() === 'banned' ? ("You are banned on " + board + "! ;_;
") + "Click here to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', tmpDoc).innerHTML) + ".
") + ("Reason: " + ($('.reason', tmpDoc).innerHTML))
+ innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_;
\nClick here to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ".
\nReason: " + ($('.reason', resDoc).innerHTML)
});
- } else if (err = tmpDoc.getElementById('errmsg')) {
+ } else if (err = resDoc.getElementById('errmsg')) {
if ((_ref = $('a', err)) != null) {
_ref.target = '_blank';
}
- } else if (tmpDoc.title !== 'Post successful!') {
+ } else if (resDoc.title !== 'Post successful!') {
err = 'Connection error with sys.4chan.org.';
} else if (req.status !== 200) {
err = "Error " + req.statusText + " (" + req.status + ")";
@@ -6124,8 +6102,8 @@
QR.error(err);
return;
}
+ h1 = $('h1', resDoc);
QR.cleanNotifications();
- h1 = $('h1', tmpDoc);
if (Conf['Posting Success Notifications']) {
QR.notifications.push(new Notification('success', h1.textContent, 5));
}
@@ -6879,6 +6857,8 @@
form[post.ID] = 'delete';
link = this;
return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), {
+ responseType: 'document',
+ withCredentials: true,
onload: function() {
return DeleteLink.load(link, post, fileOnly, this.response);
},
@@ -6886,22 +6866,19 @@
return DeleteLink.error(link);
}
}, {
- cred: true,
form: $.formData(form)
});
},
- load: function(link, post, fileOnly, html) {
- var msg, s, tmpDoc;
+ load: function(link, post, fileOnly, resDoc) {
+ var msg, s;
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = html;
- if (tmpDoc.title === '4chan - Banned') {
+ if (resDoc.title === '4chan - Banned') {
s = 'Banned!';
- } else if (msg = tmpDoc.getElementById('errmsg')) {
+ } else if (msg = resDoc.getElementById('errmsg')) {
s = msg.textContent;
$.on(link, 'click', DeleteLink["delete"]);
} else {
- if (tmpDoc.title === 'Updating index...') {
+ if (resDoc.title === 'Updating index...') {
(post.origin || post).kill(fileOnly);
}
s = 'Deleted';
@@ -7930,8 +7907,7 @@
if (Conf['Unread Line']) {
Unread.setLine(posts.contains(Unread.posts[0]));
}
- Unread.read();
- return Unread.update();
+ return Unread.read();
},
addPostQuotingYou: function(post) {
var quotelink, _i, _len, _ref;
@@ -7981,32 +7957,40 @@
}
return arr.splice(0, i);
},
- read: $.debounce(50, function(e) {
- var ID, bottom, height, i, post, posts, read;
+ read: $.debounce(50, function() {
+ var ID, bottom, height, i, post, posts;
if (d.hidden || !Unread.posts.length) {
return;
}
height = doc.clientHeight;
posts = Unread.posts;
- read = [];
- i = posts.length;
- while (post = posts[--i]) {
+ i = 0;
+ while (post = posts[i]) {
bottom = post.nodes.root.getBoundingClientRect().bottom;
- if (bottom < height) {
- ID = post.ID;
- posts.remove(post);
+ if (bottom > height) {
+ i++;
+ continue;
}
+ ID = post.ID;
+ if (Conf['Quote Threading']) {
+ posts.splice(i, 1);
+ continue;
+ } else {
+ posts.splice(0, i);
+ break;
+ }
+ i++;
}
if (!ID) {
return;
}
- Unread.lastReadPost = ID;
+ if (Unread.lastReadPost < ID || !Unread.lastReadPost) {
+ Unread.lastReadPost = ID;
+ }
Unread.saveLastReadPost();
Unread.readArray(Unread.postsQuotingYou);
- if (e) {
- return Unread.update();
- }
+ return Unread.update();
}),
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
if (Unread.thread.isDead) {
@@ -8375,20 +8359,19 @@
return;
}
return Post.prototype.callbacks.push({
- name: 'Reveal Spoilers',
+ name: 'Color User IDs',
cb: this.node
});
},
- node: function(post) {
+ node: function() {
var str, uid;
- if (!(uid = $('.hand', this.nodes.uniqueID))) {
+ str = this.info.uniqueID;
+ uid = $('.hand', this.nodes.uniqueID);
+ if (!(str && uid && uid.nodeName === 'SPAN')) {
return;
}
- str = this.info.uniqueID;
- if (uid.nodeName === 'SPAN') {
- return uid.style.cssText = IDColor.apply.call(str);
- }
+ return uid.style.cssText = IDColor.css(IDColor.ids[str] || IDColor.compute(str));
},
ids: {},
compute: function(str) {
@@ -8400,11 +8383,8 @@
this.ids[str] = rgb;
return rgb;
},
- apply: function() {
- var rgb;
-
- rgb = IDColor.ids[this] || IDColor.compute(this);
- return ("background-color: rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "); color: ") + (rgb[3] ? "black; border-radius: 3px; padding: 0px 2px;" : "white; border-radius: 3px; padding: 0px 2px;");
+ css: function(rgb) {
+ return "background-color: rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "); color: " + (rgb[3] ? "black;" : "white;") + " border-radius: 3px; padding: 0px 2px;";
},
hash: function(str) {
var i, j, msg;
@@ -10367,7 +10347,7 @@
'Fourchan thingies': Fourchan,
'Emoji': Emoji,
'Color User IDs': IDColor,
- 'Remove Spoilers': RemoveSpoilers,
+ 'Reveal Spoilers': RemoveSpoilers,
'Custom CSS': CustomCSS,
'Linkify': Linkify,
'Resurrect Quotes': Quotify,
@@ -10399,7 +10379,7 @@
'Sauce': Sauce,
'Image Expansion': ImageExpand,
'Image Expansion (Menu)': ImageExpand.menu,
- 'Reveal Spoilers': RevealSpoilers,
+ 'Reveal Spoiler Thumbnails': RevealSpoilers,
'Image Loading': ImageLoader,
'Image Hover': ImageHover,
'Comment Expansion': ExpandComment,
diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js
index 2bc9afc9d..b02692677 100644
--- a/builds/appchan-x.user.js
+++ b/builds/appchan-x.user.js
@@ -18,7 +18,7 @@
// ==/UserScript==
/*
-* appchan x - Version 2.2.2 - 2013-08-07
+* appchan x - Version 2.2.2 - 2013-08-08
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@@ -2693,15 +2693,6 @@
return this.indexOf(string) > -1;
};
- Array.prototype.add = function(object, position) {
- var keep;
-
- keep = this.slice(position);
- this.length = position;
- this.push(object);
- return this.pushArrays(keep);
- };
-
Array.prototype.contains = function(object) {
return this.indexOf(object) > -1;
};
@@ -2718,27 +2709,6 @@
return i;
};
- Array.prototype.pushArrays = function() {
- var arg, args, _i, _len;
-
- args = arguments;
- for (_i = 0, _len = args.length; _i < _len; _i++) {
- arg = args[_i];
- this.push.apply(this, arg);
- }
- return this;
- };
-
- Array.prototype.remove = function(object) {
- var index;
-
- if ((index = this.indexOf(object)) > -1) {
- return this.splice(index, 1);
- } else {
- return false;
- }
- };
-
$ = function(selector, root) {
if (root == null) {
root = d.body;
@@ -2798,13 +2768,22 @@
return fd;
};
- $.ajax = function(url, callbacks, opts) {
- var cred, err, form, headers, key, r, sync, type, upCallbacks, val;
+ $.extend = function(object, properties) {
+ var key, val;
- if (opts == null) {
- opts = {};
+ for (key in properties) {
+ val = properties[key];
+ object[key] = val;
}
- type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
+ };
+
+ $.ajax = function(url, options, extra) {
+ var form, headers, key, r, sync, type, upCallbacks, val;
+
+ if (extra == null) {
+ extra = {};
+ }
+ type = extra.type, headers = extra.headers, upCallbacks = extra.upCallbacks, form = extra.form, sync = extra.sync;
r = new XMLHttpRequest();
r.overrideMimeType('text/html');
type || (type = form && 'post' || 'get');
@@ -2813,13 +2792,8 @@
val = headers[key];
r.setRequestHeader(key, val);
}
- $.extend(r, callbacks);
+ $.extend(r, options);
$.extend(r.upload, upCallbacks);
- try {
- r.withCredentials = cred;
- } catch (_error) {
- err = _error;
- }
r.send(form);
return r;
};
@@ -3966,7 +3940,11 @@
a.dataset.only = m[1];
a.href = "//boards.4chan.org/" + board + "/";
if (m[1] === 'catalog') {
- a.href += 'catalog';
+ if (Conf['External Catalog']) {
+ a.href = CatalogLinks.external(board);
+ } else {
+ a.href += 'catalog';
+ }
$.addClass(a, 'catalog');
}
}
@@ -5968,7 +5946,7 @@
if (Conf['Quote Inlining']) {
$.on(link, 'click', QuoteInline.toggle);
if (Conf['Quote Hash Navigation']) {
- frag.pushArrays(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
+ frag.push.apply(frag, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
}
}
$.add(container, frag);
@@ -6047,9 +6025,6 @@
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
return;
}
- if (Conf['Comment Expansion']) {
- ExpandComment.callbacks.push(this.node);
- }
if (Conf['Quote Hash Navigation']) {
this.node = function() {
var link, _i, _len, _ref;
@@ -6074,6 +6049,9 @@
}
};
}
+ if (Conf['Comment Expansion']) {
+ ExpandComment.callbacks.push(this.node);
+ }
return Post.prototype.callbacks.push({
name: 'Quote Inlining',
cb: this.node
@@ -8274,7 +8252,7 @@
},
preSubmitHooks: [],
submit: function(e) {
- var callbacks, challenge, err, filetag, hook, opts, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
+ var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
if (e != null) {
e.preventDefault();
@@ -8353,7 +8331,9 @@
recaptcha_challenge_field: challenge,
recaptcha_response_field: response
};
- callbacks = {
+ options = {
+ responseType: 'document',
+ withCredentials: true,
onload: QR.response,
onerror: function() {
delete QR.req;
@@ -8361,12 +8341,11 @@
QR.cooldown.auto = false;
QR.status();
return QR.error($.el('span', {
- innerHTML: "Connection error. You may have been banned.\n[?]"
+ innerHTML: "Connection error. You may have been banned.\n[?]"
}));
}
};
- opts = {
- cred: true,
+ extra = {
form: $.formData(postData),
upCallbacks: {
onload: function() {
@@ -8381,30 +8360,29 @@
}
}
};
- QR.req = $.ajax($.id('postForm').parentNode.action, callbacks, opts);
+ QR.req = $.ajax($.id('postForm').parentNode.action, options, extra);
QR.req.uploadStartTime = Date.now();
QR.req.progress = '...';
return QR.status();
},
response: function() {
- var URL, ban, board, err, h1, isReply, m, post, postID, req, threadID, tmpDoc, _, _ref, _ref1;
+ var URL, ban, board, err, h1, isReply, m, post, postID, req, resDoc, threadID, _, _ref, _ref1;
req = QR.req;
delete QR.req;
post = QR.posts[0];
post.unlock();
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = req.response;
- if (ban = $('.banType', tmpDoc)) {
- board = $('.board', tmpDoc).innerHTML;
+ resDoc = req.response;
+ if (ban = $('.banType', resDoc)) {
+ board = $('.board', resDoc).innerHTML;
err = $.el('span', {
- innerHTML: ban.textContent.toLowerCase() === 'banned' ? ("You are banned on " + board + "! ;_;
") + "Click here to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', tmpDoc).innerHTML) + ".
") + ("Reason: " + ($('.reason', tmpDoc).innerHTML))
+ innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_;
\nClick here to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ".
\nReason: " + ($('.reason', resDoc).innerHTML)
});
- } else if (err = tmpDoc.getElementById('errmsg')) {
+ } else if (err = resDoc.getElementById('errmsg')) {
if ((_ref = $('a', err)) != null) {
_ref.target = '_blank';
}
- } else if (tmpDoc.title !== 'Post successful!') {
+ } else if (resDoc.title !== 'Post successful!') {
err = 'Connection error with sys.4chan.org.';
} else if (req.status !== 200) {
err = "Error " + req.statusText + " (" + req.status + ")";
@@ -8430,8 +8408,8 @@
QR.error(err);
return;
}
+ h1 = $('h1', resDoc);
QR.cleanNotifications();
- h1 = $('h1', tmpDoc);
if (Conf['Posting Success Notifications']) {
QR.notifications.push(new Notification('success', h1.textContent, 5));
}
@@ -9212,6 +9190,8 @@
form[post.ID] = 'delete';
link = this;
return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), {
+ responseType: 'document',
+ withCredentials: true,
onload: function() {
return DeleteLink.load(link, post, fileOnly, this.response);
},
@@ -9219,22 +9199,19 @@
return DeleteLink.error(link);
}
}, {
- cred: true,
form: $.formData(form)
});
},
- load: function(link, post, fileOnly, html) {
- var msg, s, tmpDoc;
+ load: function(link, post, fileOnly, resDoc) {
+ var msg, s;
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = html;
- if (tmpDoc.title === '4chan - Banned') {
+ if (resDoc.title === '4chan - Banned') {
s = 'Banned!';
- } else if (msg = tmpDoc.getElementById('errmsg')) {
+ } else if (msg = resDoc.getElementById('errmsg')) {
s = msg.textContent;
$.on(link, 'click', DeleteLink["delete"]);
} else {
- if (tmpDoc.title === 'Updating index...') {
+ if (resDoc.title === 'Updating index...') {
(post.origin || post).kill(fileOnly);
}
s = 'Deleted';
@@ -10254,8 +10231,7 @@
if (Conf['Unread Line']) {
Unread.setLine(posts.contains(Unread.posts[0]));
}
- Unread.read();
- return Unread.update();
+ return Unread.read();
},
addPostQuotingYou: function(post) {
var quotelink, _i, _len, _ref;
@@ -10305,32 +10281,40 @@
}
return arr.splice(0, i);
},
- read: $.debounce(50, function(e) {
- var ID, bottom, height, i, post, posts, read;
+ read: $.debounce(50, function() {
+ var ID, bottom, height, i, post, posts;
if (d.hidden || !Unread.posts.length) {
return;
}
height = doc.clientHeight;
posts = Unread.posts;
- read = [];
- i = posts.length;
- while (post = posts[--i]) {
+ i = 0;
+ while (post = posts[i]) {
bottom = post.nodes.root.getBoundingClientRect().bottom;
- if (bottom < height) {
- ID = post.ID;
- posts.remove(post);
+ if (bottom > height) {
+ i++;
+ continue;
}
+ ID = post.ID;
+ if (Conf['Quote Threading']) {
+ posts.splice(i, 1);
+ continue;
+ } else {
+ posts.splice(0, i);
+ break;
+ }
+ i++;
}
if (!ID) {
return;
}
- Unread.lastReadPost = ID;
+ if (Unread.lastReadPost < ID || !Unread.lastReadPost) {
+ Unread.lastReadPost = ID;
+ }
Unread.saveLastReadPost();
Unread.readArray(Unread.postsQuotingYou);
- if (e) {
- return Unread.update();
- }
+ return Unread.update();
}),
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
if (Unread.thread.isDead) {
@@ -12261,20 +12245,19 @@
return;
}
return Post.prototype.callbacks.push({
- name: 'Reveal Spoilers',
+ name: 'Color User IDs',
cb: this.node
});
},
- node: function(post) {
+ node: function() {
var str, uid;
- if (!(uid = $('.hand', this.nodes.uniqueID))) {
+ str = this.info.uniqueID;
+ uid = $('.hand', this.nodes.uniqueID);
+ if (!(str && uid && uid.nodeName === 'SPAN')) {
return;
}
- str = this.info.uniqueID;
- if (uid.nodeName === 'SPAN') {
- return uid.style.cssText = IDColor.apply.call(str);
- }
+ return uid.style.cssText = IDColor.css(IDColor.ids[str] || IDColor.compute(str));
},
ids: {},
compute: function(str) {
@@ -12286,11 +12269,8 @@
this.ids[str] = rgb;
return rgb;
},
- apply: function() {
- var rgb;
-
- rgb = IDColor.ids[this] || IDColor.compute(this);
- return ("background-color: rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "); color: ") + (rgb[3] ? "black; border-radius: 3px; padding: 0px 2px;" : "white; border-radius: 3px; padding: 0px 2px;");
+ css: function(rgb) {
+ return "background-color: rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "); color: " + (rgb[3] ? "black;" : "white;") + " border-radius: 3px; padding: 0px 2px;";
},
hash: function(str) {
var i, j, msg;
@@ -14724,7 +14704,7 @@
'Announcement Hiding': PSAHiding,
'Fourchan thingies': Fourchan,
'Color User IDs': IDColor,
- 'Remove Spoilers': RemoveSpoilers,
+ 'Reveal Spoilers': RemoveSpoilers,
'Custom CSS': CustomCSS,
'Linkify': Linkify,
'Resurrect Quotes': Quotify,
@@ -14756,7 +14736,7 @@
'Sauce': Sauce,
'Image Expansion': ImageExpand,
'Image Expansion (Menu)': ImageExpand.menu,
- 'Reveal Spoilers': RevealSpoilers,
+ 'Reveal Spoiler Thumbnails': RevealSpoilers,
'Image Loading': ImageLoader,
'Image Hover': ImageHover,
'Comment Expansion': ExpandComment,
diff --git a/builds/crx/script.js b/builds/crx/script.js
index 4ea3212e8..96e90cffb 100644
--- a/builds/crx/script.js
+++ b/builds/crx/script.js
@@ -1,6 +1,6 @@
// Generated by CoffeeScript
/*
-* appchan x - Version 2.2.2 - 2013-08-07
+* appchan x - Version 2.2.2 - 2013-08-08
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@@ -2676,15 +2676,6 @@
return this.indexOf(string) > -1;
};
- Array.prototype.add = function(object, position) {
- var keep;
-
- keep = this.slice(position);
- this.length = position;
- this.push(object);
- return this.pushArrays(keep);
- };
-
Array.prototype.contains = function(object) {
return this.indexOf(object) > -1;
};
@@ -2701,27 +2692,6 @@
return i;
};
- Array.prototype.pushArrays = function() {
- var arg, args, _i, _len;
-
- args = arguments;
- for (_i = 0, _len = args.length; _i < _len; _i++) {
- arg = args[_i];
- this.push.apply(this, arg);
- }
- return this;
- };
-
- Array.prototype.remove = function(object) {
- var index;
-
- if ((index = this.indexOf(object)) > -1) {
- return this.splice(index, 1);
- } else {
- return false;
- }
- };
-
$ = function(selector, root) {
if (root == null) {
root = d.body;
@@ -2781,13 +2751,22 @@
return fd;
};
- $.ajax = function(url, callbacks, opts) {
- var cred, err, form, headers, key, r, sync, type, upCallbacks, val;
+ $.extend = function(object, properties) {
+ var key, val;
- if (opts == null) {
- opts = {};
+ for (key in properties) {
+ val = properties[key];
+ object[key] = val;
}
- type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
+ };
+
+ $.ajax = function(url, options, extra) {
+ var form, headers, key, r, sync, type, upCallbacks, val;
+
+ if (extra == null) {
+ extra = {};
+ }
+ type = extra.type, headers = extra.headers, upCallbacks = extra.upCallbacks, form = extra.form, sync = extra.sync;
r = new XMLHttpRequest();
r.overrideMimeType('text/html');
type || (type = form && 'post' || 'get');
@@ -2796,13 +2775,8 @@
val = headers[key];
r.setRequestHeader(key, val);
}
- $.extend(r, callbacks);
+ $.extend(r, options);
$.extend(r.upload, upCallbacks);
- try {
- r.withCredentials = cred;
- } catch (_error) {
- err = _error;
- }
r.send(form);
return r;
};
@@ -3980,7 +3954,11 @@
a.dataset.only = m[1];
a.href = "//boards.4chan.org/" + board + "/";
if (m[1] === 'catalog') {
- a.href += 'catalog';
+ if (Conf['External Catalog']) {
+ a.href = CatalogLinks.external(board);
+ } else {
+ a.href += 'catalog';
+ }
$.addClass(a, 'catalog');
}
}
@@ -5975,7 +5953,7 @@
if (Conf['Quote Inlining']) {
$.on(link, 'click', QuoteInline.toggle);
if (Conf['Quote Hash Navigation']) {
- frag.pushArrays(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
+ frag.push.apply(frag, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
}
}
$.add(container, frag);
@@ -6054,9 +6032,6 @@
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
return;
}
- if (Conf['Comment Expansion']) {
- ExpandComment.callbacks.push(this.node);
- }
if (Conf['Quote Hash Navigation']) {
this.node = function() {
var link, _i, _len, _ref;
@@ -6081,6 +6056,9 @@
}
};
}
+ if (Conf['Comment Expansion']) {
+ ExpandComment.callbacks.push(this.node);
+ }
return Post.prototype.callbacks.push({
name: 'Quote Inlining',
cb: this.node
@@ -8257,7 +8235,7 @@
},
preSubmitHooks: [],
submit: function(e) {
- var callbacks, challenge, err, filetag, hook, opts, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
+ var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
if (e != null) {
e.preventDefault();
@@ -8336,7 +8314,9 @@
recaptcha_challenge_field: challenge,
recaptcha_response_field: response
};
- callbacks = {
+ options = {
+ responseType: 'document',
+ withCredentials: true,
onload: QR.response,
onerror: function() {
delete QR.req;
@@ -8344,12 +8324,11 @@
QR.cooldown.auto = false;
QR.status();
return QR.error($.el('span', {
- innerHTML: "Connection error. You may have been banned.\n[?]"
+ innerHTML: "Connection error. You may have been banned.\n[?]"
}));
}
};
- opts = {
- cred: true,
+ extra = {
form: $.formData(postData),
upCallbacks: {
onload: function() {
@@ -8364,30 +8343,29 @@
}
}
};
- QR.req = $.ajax($.id('postForm').parentNode.action, callbacks, opts);
+ QR.req = $.ajax($.id('postForm').parentNode.action, options, extra);
QR.req.uploadStartTime = Date.now();
QR.req.progress = '...';
return QR.status();
},
response: function() {
- var URL, ban, board, err, h1, isReply, m, post, postID, req, threadID, tmpDoc, _, _ref, _ref1;
+ var URL, ban, board, err, h1, isReply, m, post, postID, req, resDoc, threadID, _, _ref, _ref1;
req = QR.req;
delete QR.req;
post = QR.posts[0];
post.unlock();
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = req.response;
- if (ban = $('.banType', tmpDoc)) {
- board = $('.board', tmpDoc).innerHTML;
+ resDoc = req.response;
+ if (ban = $('.banType', resDoc)) {
+ board = $('.board', resDoc).innerHTML;
err = $.el('span', {
- innerHTML: ban.textContent.toLowerCase() === 'banned' ? ("You are banned on " + board + "! ;_;
") + "Click here to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', tmpDoc).innerHTML) + ".
") + ("Reason: " + ($('.reason', tmpDoc).innerHTML))
+ innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_;
\nClick here to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ".
\nReason: " + ($('.reason', resDoc).innerHTML)
});
- } else if (err = tmpDoc.getElementById('errmsg')) {
+ } else if (err = resDoc.getElementById('errmsg')) {
if ((_ref = $('a', err)) != null) {
_ref.target = '_blank';
}
- } else if (tmpDoc.title !== 'Post successful!') {
+ } else if (resDoc.title !== 'Post successful!') {
err = 'Connection error with sys.4chan.org.';
} else if (req.status !== 200) {
err = "Error " + req.statusText + " (" + req.status + ")";
@@ -8413,8 +8391,8 @@
QR.error(err);
return;
}
+ h1 = $('h1', resDoc);
QR.cleanNotifications();
- h1 = $('h1', tmpDoc);
if (Conf['Posting Success Notifications']) {
QR.notifications.push(new Notification('success', h1.textContent, 5));
}
@@ -9195,6 +9173,8 @@
form[post.ID] = 'delete';
link = this;
return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), {
+ responseType: 'document',
+ withCredentials: true,
onload: function() {
return DeleteLink.load(link, post, fileOnly, this.response);
},
@@ -9202,22 +9182,19 @@
return DeleteLink.error(link);
}
}, {
- cred: true,
form: $.formData(form)
});
},
- load: function(link, post, fileOnly, html) {
- var msg, s, tmpDoc;
+ load: function(link, post, fileOnly, resDoc) {
+ var msg, s;
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = html;
- if (tmpDoc.title === '4chan - Banned') {
+ if (resDoc.title === '4chan - Banned') {
s = 'Banned!';
- } else if (msg = tmpDoc.getElementById('errmsg')) {
+ } else if (msg = resDoc.getElementById('errmsg')) {
s = msg.textContent;
$.on(link, 'click', DeleteLink["delete"]);
} else {
- if (tmpDoc.title === 'Updating index...') {
+ if (resDoc.title === 'Updating index...') {
(post.origin || post).kill(fileOnly);
}
s = 'Deleted';
@@ -10237,8 +10214,7 @@
if (Conf['Unread Line']) {
Unread.setLine(posts.contains(Unread.posts[0]));
}
- Unread.read();
- return Unread.update();
+ return Unread.read();
},
addPostQuotingYou: function(post) {
var quotelink, _i, _len, _ref;
@@ -10288,32 +10264,40 @@
}
return arr.splice(0, i);
},
- read: $.debounce(50, function(e) {
- var ID, bottom, height, i, post, posts, read;
+ read: $.debounce(50, function() {
+ var ID, bottom, height, i, post, posts;
if (d.hidden || !Unread.posts.length) {
return;
}
height = doc.clientHeight;
posts = Unread.posts;
- read = [];
- i = posts.length;
- while (post = posts[--i]) {
+ i = 0;
+ while (post = posts[i]) {
bottom = post.nodes.root.getBoundingClientRect().bottom;
- if (bottom < height) {
- ID = post.ID;
- posts.remove(post);
+ if (bottom > height) {
+ i++;
+ continue;
}
+ ID = post.ID;
+ if (Conf['Quote Threading']) {
+ posts.splice(i, 1);
+ continue;
+ } else {
+ posts.splice(0, i);
+ break;
+ }
+ i++;
}
if (!ID) {
return;
}
- Unread.lastReadPost = ID;
+ if (Unread.lastReadPost < ID || !Unread.lastReadPost) {
+ Unread.lastReadPost = ID;
+ }
Unread.saveLastReadPost();
Unread.readArray(Unread.postsQuotingYou);
- if (e) {
- return Unread.update();
- }
+ return Unread.update();
}),
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
if (Unread.thread.isDead) {
@@ -12249,20 +12233,19 @@
return;
}
return Post.prototype.callbacks.push({
- name: 'Reveal Spoilers',
+ name: 'Color User IDs',
cb: this.node
});
},
- node: function(post) {
+ node: function() {
var str, uid;
- if (!(uid = $('.hand', this.nodes.uniqueID))) {
+ str = this.info.uniqueID;
+ uid = $('.hand', this.nodes.uniqueID);
+ if (!(str && uid && uid.nodeName === 'SPAN')) {
return;
}
- str = this.info.uniqueID;
- if (uid.nodeName === 'SPAN') {
- return uid.style.cssText = IDColor.apply.call(str);
- }
+ return uid.style.cssText = IDColor.css(IDColor.ids[str] || IDColor.compute(str));
},
ids: {},
compute: function(str) {
@@ -12274,11 +12257,8 @@
this.ids[str] = rgb;
return rgb;
},
- apply: function() {
- var rgb;
-
- rgb = IDColor.ids[this] || IDColor.compute(this);
- return ("background-color: rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "); color: ") + (rgb[3] ? "black; border-radius: 3px; padding: 0px 2px;" : "white; border-radius: 3px; padding: 0px 2px;");
+ css: function(rgb) {
+ return "background-color: rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "); color: " + (rgb[3] ? "black;" : "white;") + " border-radius: 3px; padding: 0px 2px;";
},
hash: function(str) {
var i, j, msg;
@@ -14704,7 +14684,7 @@
'Announcement Hiding': PSAHiding,
'Fourchan thingies': Fourchan,
'Color User IDs': IDColor,
- 'Remove Spoilers': RemoveSpoilers,
+ 'Reveal Spoilers': RemoveSpoilers,
'Custom CSS': CustomCSS,
'Linkify': Linkify,
'Resurrect Quotes': Quotify,
@@ -14736,7 +14716,7 @@
'Sauce': Sauce,
'Image Expansion': ImageExpand,
'Image Expansion (Menu)': ImageExpand.menu,
- 'Reveal Spoilers': RevealSpoilers,
+ 'Reveal Spoiler Thumbnails': RevealSpoilers,
'Image Loading': ImageLoader,
'Image Hover': ImageHover,
'Comment Expansion': ExpandComment,
diff --git a/src/General/Header.coffee b/src/General/Header.coffee
index b715ebe5f..5ff841eba 100644
--- a/src/General/Header.coffee
+++ b/src/General/Header.coffee
@@ -144,7 +144,10 @@ Header =
a.dataset.only = m[1]
a.href = "//boards.4chan.org/#{board}/"
if m[1] is 'catalog'
- a.href += 'catalog'
+ if Conf['External Catalog']
+ a.href = CatalogLinks.external board
+ else
+ a.href += 'catalog'
$.addClass a, 'catalog'
$.addClass a, 'navSmall' if board is '@'
diff --git a/src/General/Main.coffee b/src/General/Main.coffee
index b69bbce5c..6644f4074 100644
--- a/src/General/Main.coffee
+++ b/src/General/Main.coffee
@@ -105,66 +105,66 @@ Main =
# c.time 'All initializations'
init
- 'Polyfill': Polyfill
- 'Emoji': Emoji
- 'Style': Style
- 'Mascots': MascotTools
- 'Rice': Rice
- 'Banner': Banner
- 'Announcements': GlobalMessage
- 'Archive Redirection': Redirect
- 'Header': Header
- 'Catalog Links': CatalogLinks
- 'Settings': Settings
- 'Announcement Hiding': PSAHiding
- 'Fourchan thingies': Fourchan
- 'Color User IDs': IDColor
- 'Remove Spoilers': RemoveSpoilers
- 'Custom CSS': CustomCSS
- 'Linkify': Linkify
- 'Resurrect Quotes': Quotify
- 'Filter': Filter
- 'Thread Hiding Buttons': ThreadHiding
- 'Reply Hiding Buttons': PostHiding
- 'Recursive': Recursive
- 'Strike-through Quotes': QuoteStrikeThrough
- 'Quick Reply': QR
- 'Menu': Menu
- 'Report Link': ReportLink
- 'Thread Hiding (Menu)': ThreadHiding.menu
- 'Reply Hiding (Menu)': PostHiding.menu
- 'Delete Link': DeleteLink
- 'Filter (Menu)': Filter.menu
- 'Download Link': DownloadLink
- 'Archive Link': ArchiveLink
- 'Quote Inlining': QuoteInline
- 'Quote Previewing': QuotePreview
- 'Quote Backlinks': QuoteBacklink
- 'Mark Quotes of You': QuoteYou
- 'Mark OP Quotes': QuoteOP
- 'Mark Cross-thread Quotes': QuoteCT
- 'Anonymize': Anonymize
- 'Time Formatting': Time
- 'Relative Post Dates': RelativeDates
- 'File Info Formatting': FileInfo
- 'Fappe Tyme': FappeTyme
- 'Sauce': Sauce
- 'Image Expansion': ImageExpand
- 'Image Expansion (Menu)': ImageExpand.menu
- 'Reveal Spoilers': RevealSpoilers
- 'Image Loading': ImageLoader
- 'Image Hover': ImageHover
- 'Comment Expansion': ExpandComment
- 'Thread Expansion': ExpandThread
- 'Thread Excerpt': ThreadExcerpt
- 'Favicon': Favicon
- 'Unread': Unread
- 'Quote Threading': QuoteThreading
- 'Thread Updater': ThreadUpdater
- 'Thread Stats': ThreadStats
- 'Thread Watcher': ThreadWatcher
- 'Index Navigation': Nav
- 'Keybinds': Keybinds
+ 'Polyfill': Polyfill
+ 'Emoji': Emoji
+ 'Style': Style
+ 'Mascots': MascotTools
+ 'Rice': Rice
+ 'Banner': Banner
+ 'Announcements': GlobalMessage
+ 'Archive Redirection': Redirect
+ 'Header': Header
+ 'Catalog Links': CatalogLinks
+ 'Settings': Settings
+ 'Announcement Hiding': PSAHiding
+ 'Fourchan thingies': Fourchan
+ 'Color User IDs': IDColor
+ 'Reveal Spoilers': RemoveSpoilers
+ 'Custom CSS': CustomCSS
+ 'Linkify': Linkify
+ 'Resurrect Quotes': Quotify
+ 'Filter': Filter
+ 'Thread Hiding Buttons': ThreadHiding
+ 'Reply Hiding Buttons': PostHiding
+ 'Recursive': Recursive
+ 'Strike-through Quotes': QuoteStrikeThrough
+ 'Quick Reply': QR
+ 'Menu': Menu
+ 'Report Link': ReportLink
+ 'Thread Hiding (Menu)': ThreadHiding.menu
+ 'Reply Hiding (Menu)': PostHiding.menu
+ 'Delete Link': DeleteLink
+ 'Filter (Menu)': Filter.menu
+ 'Download Link': DownloadLink
+ 'Archive Link': ArchiveLink
+ 'Quote Inlining': QuoteInline
+ 'Quote Previewing': QuotePreview
+ 'Quote Backlinks': QuoteBacklink
+ 'Mark Quotes of You': QuoteYou
+ 'Mark OP Quotes': QuoteOP
+ 'Mark Cross-thread Quotes': QuoteCT
+ 'Anonymize': Anonymize
+ 'Time Formatting': Time
+ 'Relative Post Dates': RelativeDates
+ 'File Info Formatting': FileInfo
+ 'Fappe Tyme': FappeTyme
+ 'Sauce': Sauce
+ 'Image Expansion': ImageExpand
+ 'Image Expansion (Menu)': ImageExpand.menu
+ 'Reveal Spoiler Thumbnails': RevealSpoilers
+ 'Image Loading': ImageLoader
+ 'Image Hover': ImageHover
+ 'Comment Expansion': ExpandComment
+ 'Thread Expansion': ExpandThread
+ 'Thread Excerpt': ThreadExcerpt
+ 'Favicon': Favicon
+ 'Unread': Unread
+ 'Quote Threading': QuoteThreading
+ 'Thread Updater': ThreadUpdater
+ 'Thread Stats': ThreadStats
+ 'Thread Watcher': ThreadWatcher
+ 'Index Navigation': Nav
+ 'Keybinds': Keybinds
# c.timeEnd 'All initializations'
diff --git a/src/General/lib/$.coffee b/src/General/lib/$.coffee
index 0bdf1df75..34a0e8af7 100644
--- a/src/General/lib/$.coffee
+++ b/src/General/lib/$.coffee
@@ -4,12 +4,6 @@ String::capitalize = ->
String::contains = (string) ->
@indexOf(string) > -1
-Array::add = (object, position) ->
- keep = @slice position
- @length = position
- @push object
- @pushArrays keep
-
Array::contains = (object) ->
@indexOf(object) > -1
@@ -19,18 +13,6 @@ Array::indexOf = (object) ->
return i if @[i] is object
return i
-Array::pushArrays = ->
- args = arguments
- for arg in args
- @push.apply @, arg
- return @
-
-Array::remove = (object) ->
- if (index = @indexOf object) > -1
- @splice index, 1
- else
- false
-
# loosely follows the jquery api:
# http://api.jquery.com/
# not chainable
@@ -70,24 +52,21 @@ $.formData = (form) ->
fd.append key, val
fd
-$.ajax = (url, callbacks, opts={}) ->
- {type, cred, headers, upCallbacks, form, sync} = opts
+$.extend = (object, properties) ->
+ for key, val of properties
+ object[key] = val
+ return
+
+$.ajax = (url, options, extra={}) ->
+ {type, headers, upCallbacks, form, sync} = extra
r = new XMLHttpRequest()
r.overrideMimeType 'text/html'
type or= form and 'post' or 'get'
r.open type, url, !sync
for key, val of headers
r.setRequestHeader key, val
- $.extend r, callbacks
+ $.extend r, options
$.extend r.upload, upCallbacks
- try
- # Firefox throws an error if you try
- # to set this on a synchronous XHR.
- # Only cookies from the remote domain
- # are used in a request withCredentials.
- r.withCredentials = cred
- catch err
- # do nothing
r.send form
r
diff --git a/src/Menu/DeleteLink.coffee b/src/Menu/DeleteLink.coffee
index 7f71d7f6e..1912733c6 100644
--- a/src/Menu/DeleteLink.coffee
+++ b/src/Menu/DeleteLink.coffee
@@ -55,21 +55,20 @@ DeleteLink =
link = @
$.ajax $.id('delform').action.replace("/#{g.BOARD}/", "/#{post.board}/"),
+ responseType: 'document'
+ withCredentials: true
onload: -> DeleteLink.load link, post, fileOnly, @response
onerror: -> DeleteLink.error link
,
- cred: true
form: $.formData form
- load: (link, post, fileOnly, html) ->
- tmpDoc = d.implementation.createHTMLDocument ''
- tmpDoc.documentElement.innerHTML = html
- if tmpDoc.title is '4chan - Banned' # Ban/warn check
+ load: (link, post, fileOnly, resDoc) ->
+ if resDoc.title is '4chan - Banned' # Ban/warn check
s = 'Banned!'
- else if msg = tmpDoc.getElementById 'errmsg' # error!
+ else if msg = resDoc.getElementById 'errmsg' # error!
s = msg.textContent
$.on link, 'click', DeleteLink.delete
else
- if tmpDoc.title is 'Updating index...'
+ if resDoc.title is 'Updating index...'
# We're 100% sure.
(post.origin or post).kill fileOnly
s = 'Deleted'
diff --git a/src/Miscellaneous/CatalogLinks.coffee b/src/Miscellaneous/CatalogLinks.coffee
index 2b722bcc1..4866f8c31 100644
--- a/src/Miscellaneous/CatalogLinks.coffee
+++ b/src/Miscellaneous/CatalogLinks.coffee
@@ -36,7 +36,7 @@ CatalogLinks =
continue if ['f', 'status', '4chan'].contains(board) or !board
if Conf['External Catalog']
a.href = if useCatalog
- CatalogLinks.external(board)
+ CatalogLinks.external board
else
"//boards.4chan.org/#{board}/"
else
diff --git a/src/Miscellaneous/ColorUserIDs.coffee b/src/Miscellaneous/ColorUserIDs.coffee
index ba7647686..a0b442a17 100644
--- a/src/Miscellaneous/ColorUserIDs.coffee
+++ b/src/Miscellaneous/ColorUserIDs.coffee
@@ -3,14 +3,14 @@ IDColor =
return unless Conf['Color User IDs']
Post::callbacks.push
- name: 'Reveal Spoilers'
+ name: 'Color User IDs'
cb: @node
- node: (post) ->
- return unless uid = $ '.hand', @nodes.uniqueID
+ node: ->
str = @info.uniqueID
- if uid.nodeName is 'SPAN'
- uid.style.cssText = IDColor.apply.call str
+ uid = $ '.hand', @nodes.uniqueID
+ return unless str and uid and uid.nodeName is 'SPAN'
+ uid.style.cssText = IDColor.css IDColor.ids[str] or IDColor.compute str
ids: {}
@@ -22,14 +22,13 @@ IDColor =
(hash >> 16) & 0xFF
(hash >> 8) & 0xFF
]
+
rgb[3] = ((rgb[0] * 0.299) + (rgb[1] * 0.587) + (rgb[2] * 0.114)) > 125
@ids[str] = rgb
rgb
- apply: ->
- rgb = IDColor.ids[@] or IDColor.compute @
- "background-color: rgb(#{rgb[0]},#{rgb[1]},#{rgb[2]}); color: " + if rgb[3] then "black; border-radius: 3px; padding: 0px 2px;" else "white; border-radius: 3px; padding: 0px 2px;"
+ css: (rgb) -> "background-color: rgb(#{rgb[0]},#{rgb[1]},#{rgb[2]}); color: #{if rgb[3] then "black;" else "white;"} border-radius: 3px; padding: 0px 2px;"
hash: (str) ->
msg = 0
diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee
index 5ae97a370..788b41753 100644
--- a/src/Monitoring/Unread.coffee
+++ b/src/Monitoring/Unread.coffee
@@ -86,7 +86,6 @@ Unread =
# Force line on visible threads if there were no unread posts previously.
Unread.setLine posts.contains Unread.posts[0]
Unread.read()
- Unread.update()
addPostQuotingYou: (post) ->
return unless QR.db
@@ -116,24 +115,32 @@ Unread =
break if post.ID > Unread.lastReadPost
arr.splice 0, i
- read: $.debounce 50, (e) ->
+ read: $.debounce 50, ->
return if d.hidden or !Unread.posts.length
height = doc.clientHeight
{posts} = Unread
- read = []
- i = posts.length
+ i = 0
- while post = posts[--i]
+ while post = posts[i]
{bottom} = post.nodes.root.getBoundingClientRect()
- if (bottom < height) # post is completely read
- ID = post.ID
- posts.remove post
+ if bottom > height # post isnt completely read
+ i++
+ continue
+
+ {ID} = post
+ if Conf['Quote Threading']
+ posts.splice i, 1
+ continue
+ else
+ posts.splice 0, i
+ break
+ i++
return unless ID
- Unread.lastReadPost = ID
+ Unread.lastReadPost = ID if Unread.lastReadPost < ID or !Unread.lastReadPost
Unread.saveLastReadPost()
Unread.readArray Unread.postsQuotingYou
- Unread.update() if e
+ Unread.update()
saveLastReadPost: $.debounce 2 * $.SECOND, ->
return if Unread.thread.isDead
diff --git a/src/Posting/QuickReply.coffee b/src/Posting/QuickReply.coffee
index 18104756e..cb9653e98 100644
--- a/src/Posting/QuickReply.coffee
+++ b/src/Posting/QuickReply.coffee
@@ -1069,7 +1069,9 @@ QR =
recaptcha_challenge_field: challenge
recaptcha_response_field: response
- callbacks =
+ options =
+ responseType: 'document'
+ withCredentials: true
onload: QR.response
onerror: ->
# Connection error, or
@@ -1079,9 +1081,11 @@ QR =
QR.cooldown.auto = false
QR.status()
QR.error $.el 'span',
- innerHTML: "Connection error. You may have been banned.\n[?]"
- opts =
- cred: true
+ innerHTML: """
+ Connection error. You may have been banned.
+ [?]
+ """
+ extra =
form: $.formData postData
upCallbacks:
onload: ->
@@ -1095,7 +1099,7 @@ QR =
QR.req.progress = "#{Math.round e.loaded / e.total * 100}%"
QR.status()
- QR.req = $.ajax $.id('postForm').parentNode.action, callbacks, opts
+ QR.req = $.ajax $.id('postForm').parentNode.action, options, extra
# Starting to upload might take some time.
# Provide some feedback that we're starting to submit.
QR.req.uploadStartTime = Date.now()
@@ -1109,20 +1113,23 @@ QR =
post = QR.posts[0]
post.unlock()
- tmpDoc = d.implementation.createHTMLDocument ''
- tmpDoc.documentElement.innerHTML = req.response
- if ban = $ '.banType', tmpDoc # banned/warning
- board = $('.board', tmpDoc).innerHTML
+ resDoc = req.response
+ if ban = $ '.banType', resDoc # banned/warning
+ board = $('.board', resDoc).innerHTML
err = $.el 'span', innerHTML:
if ban.textContent.toLowerCase() is 'banned'
- "You are banned on #{board}! ;_;
" +
- "Click here to see the reason."
+ """
+ You are banned on #{board}! ;_;
+ Click here to see the reason.
+ """
else
- "You were issued a warning on #{board} as #{$('.nameBlock', tmpDoc).innerHTML}.
" +
- "Reason: #{$('.reason', tmpDoc).innerHTML}"
- else if err = tmpDoc.getElementById 'errmsg' # error!
+ """
+ You were issued a warning on #{board} as #{$('.nameBlock', resDoc).innerHTML}.
+ Reason: #{$('.reason', resDoc).innerHTML}
+ """
+ else if err = resDoc.getElementById 'errmsg' # error!
$('a', err)?.target = '_blank' # duplicate image link
- else if tmpDoc.title isnt 'Post successful!'
+ else if resDoc.title isnt 'Post successful!'
err = 'Connection error with sys.4chan.org.'
else if req.status isnt 200
err = "Error #{req.statusText} (#{req.status})"
@@ -1156,8 +1163,8 @@ QR =
QR.error err
return
+ h1 = $ 'h1', resDoc
QR.cleanNotifications()
- h1 = $ 'h1', tmpDoc
if Conf['Posting Success Notifications']
QR.notifications.push new Notification 'success', h1.textContent, 5
diff --git a/src/Quotelinks/QuoteBacklink.coffee b/src/Quotelinks/QuoteBacklink.coffee
index 54bc6f6bc..37ec5642a 100644
--- a/src/Quotelinks/QuoteBacklink.coffee
+++ b/src/Quotelinks/QuoteBacklink.coffee
@@ -42,7 +42,7 @@ QuoteBacklink =
$.on link, 'mouseover', QuotePreview.mouseover
if Conf['Quote Inlining']
$.on link, 'click', QuoteInline.toggle
- frag.pushArrays QuoteInline.qiQuote link, $.hasClass link, 'filtered' if Conf['Quote Hash Navigation']
+ frag.push.apply frag, QuoteInline.qiQuote link, $.hasClass link, 'filtered' if Conf['Quote Hash Navigation']
$.add container, frag
return
secondNode: ->
diff --git a/src/Quotelinks/QuoteInline.coffee b/src/Quotelinks/QuoteInline.coffee
index 723f0c53b..95a225e38 100644
--- a/src/Quotelinks/QuoteInline.coffee
+++ b/src/Quotelinks/QuoteInline.coffee
@@ -2,9 +2,6 @@ QuoteInline =
init: ->
return if g.VIEW is 'catalog' or !Conf['Quote Inlining']
- if Conf['Comment Expansion']
- ExpandComment.callbacks.push @node
-
if Conf['Quote Hash Navigation']
@node = ->
for link in @nodes.quotelinks.concat [@nodes.backlinks...]
@@ -18,6 +15,9 @@ QuoteInline =
$.on link, 'click', QuoteInline.toggle
return
+ if Conf['Comment Expansion']
+ ExpandComment.callbacks.push @node
+
Post::callbacks.push
name: 'Quote Inlining'
cb: @node