Merge branch 'master' of https://github.com/MayhemYDG/4chan-x
This commit is contained in:
commit
0df748d1e6
180
4chan_x.user.js
180
4chan_x.user.js
@ -148,11 +148,11 @@
|
|||||||
filesize: [''].join('\n'),
|
filesize: [''].join('\n'),
|
||||||
md5: [''].join('\n')
|
md5: [''].join('\n')
|
||||||
},
|
},
|
||||||
sauces: ['http://iqdb.org/?url=$1', 'http://www.google.com/searchbyimage?image_url=$1', '#http://tineye.com/search?url=$1', '#http://saucenao.com/search.php?db=999&url=$1', '#http://3d.iqdb.org/?url=$1', '#http://regex.info/exif.cgi?imgurl=$2', '# uploaders:', '#http://imgur.com/upload?url=$2', '#http://omploader.org/upload?url1=$2', '# "View Same" in archives:', '#http://archive.foolz.us/a/image/$3/', '#http://archive.installgentoo.net/g/image/$3'].join('\n'),
|
sauces: ['http://iqdb.org/?url=$1', 'http://www.google.com/searchbyimage?image_url=$1', '#http://tineye.com/search?url=$1', '#http://saucenao.com/search.php?db=999&url=$1', '#http://3d.iqdb.org/?url=$1', '#http://regex.info/exif.cgi?imgurl=$2', '# uploaders:', '#http://imgur.com/upload?url=$2', '#http://omploader.org/upload?url1=$2', '# "View Same" in archives:', '#http://archive.foolz.us/$4/image/$3/', '#http://archive.installgentoo.net/$4/image/$3'].join('\n'),
|
||||||
time: '%m/%d/%y(%a)%H:%M',
|
time: '%m/%d/%y(%a)%H:%M',
|
||||||
backlink: '>>%id',
|
backlink: '>>%id',
|
||||||
fileInfoR: '%l, %s, %r',
|
fileInfoR: '%l (%s, %r)',
|
||||||
fileInfoT: '%l, %s, %r',
|
fileInfoT: '%l (%s, %r)',
|
||||||
favicon: 'ferongr',
|
favicon: 'ferongr',
|
||||||
hotkeys: {
|
hotkeys: {
|
||||||
openOptions: ['ctrl+o', 'Open Options'],
|
openOptions: ['ctrl+o', 'Open Options'],
|
||||||
@ -584,7 +584,11 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (hl) {
|
if (hl) {
|
||||||
$.addClass(root, hl);
|
if (isOP) {
|
||||||
|
$.addClass(root, hl);
|
||||||
|
} else {
|
||||||
|
$.addClass(root.parentNode, hl);
|
||||||
|
}
|
||||||
if (isOP && top && !g.REPLY) {
|
if (isOP && top && !g.REPLY) {
|
||||||
thisThread = root.parentNode;
|
thisThread = root.parentNode;
|
||||||
if (firstThread = $('div[class=op]')) {
|
if (firstThread = $('div[class=op]')) {
|
||||||
@ -660,8 +664,10 @@
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
dimensions: function(root) {
|
dimensions: function(root) {
|
||||||
var span;
|
var match, span;
|
||||||
if (span = $('.filesize', root)) return span.textContent.match(/\d+x\d+/)[0];
|
if ((span = $('.filesize', root)) && (match = span.textContent.match(/\d+x\d+/))) {
|
||||||
|
return match[0];
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
filesize: function(root) {
|
filesize: function(root) {
|
||||||
@ -1698,7 +1704,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
dialog: function() {
|
dialog: function() {
|
||||||
var e, fileInput, input, mimeTypes, name, spoiler, ta, thread, threads, _i, _j, _len, _len2, _ref, _ref2;
|
var e, event, fileInput, input, mimeTypes, name, spoiler, ta, thread, threads, _i, _j, _k, _len, _len2, _len3, _ref, _ref2, _ref3;
|
||||||
qr.el = ui.dialog('qr', 'top:0;right:0;', '\
|
qr.el = ui.dialog('qr', 'top:0;right:0;', '\
|
||||||
<div class=move>\
|
<div class=move>\
|
||||||
Quick Reply <input type=checkbox id=autohide title=Auto-hide>\
|
Quick Reply <input type=checkbox id=autohide title=Auto-hide>\
|
||||||
@ -1774,12 +1780,13 @@
|
|||||||
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
|
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
|
||||||
name = _ref2[_j];
|
name = _ref2[_j];
|
||||||
input = $("[name=" + name + "]", qr.el);
|
input = $("[name=" + name + "]", qr.el);
|
||||||
$.on(input, 'keyup', function() {
|
_ref3 = ['textInput', 'keyup', 'change', 'paste'];
|
||||||
return qr.selected[this.name] = this.value;
|
for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
|
||||||
});
|
event = _ref3[_k];
|
||||||
$.on(input, 'change', function() {
|
$.on(input, event, function() {
|
||||||
return qr.selected[this.name] = this.value;
|
return qr.selected[this.name] = this.value;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$.sync('qr.persona', function(persona) {
|
$.sync('qr.persona', function(persona) {
|
||||||
var key, val, _results;
|
var key, val, _results;
|
||||||
@ -1856,7 +1863,7 @@
|
|||||||
mode: 'regist',
|
mode: 'regist',
|
||||||
pwd: (m = d.cookie.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : $('[name=pwd]').value,
|
pwd: (m = d.cookie.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : $('[name=pwd]').value,
|
||||||
recaptcha_challenge_field: challenge,
|
recaptcha_challenge_field: challenge,
|
||||||
recaptcha_response_field: response
|
recaptcha_response_field: response + ' '
|
||||||
};
|
};
|
||||||
qr.status({
|
qr.status({
|
||||||
progress: '...'
|
progress: '...'
|
||||||
@ -2119,10 +2126,11 @@
|
|||||||
<div>\
|
<div>\
|
||||||
<div class=warning><code>Sauce</code> is disabled.</div>\
|
<div class=warning><code>Sauce</code> is disabled.</div>\
|
||||||
Lines starting with a <code>#</code> will be ignored.\
|
Lines starting with a <code>#</code> will be ignored.\
|
||||||
<ul>These variables will be replaced by the corresponding url:\
|
<ul>These parameters will be replaced by their corresponding values:\
|
||||||
<li>$1: Thumbnail.</li>\
|
<li>$1: Thumbnail url.</li>\
|
||||||
<li>$2: Full image.</li>\
|
<li>$2: Full image url.</li>\
|
||||||
<li>$3: MD5 hash.</li>\
|
<li>$3: MD5 hash.</li>\
|
||||||
|
<li>$4: Current board.</li>\
|
||||||
</ul>\
|
</ul>\
|
||||||
<textarea name=sauces id=sauces></textarea>\
|
<textarea name=sauces id=sauces></textarea>\
|
||||||
</div>\
|
</div>\
|
||||||
@ -2173,7 +2181,7 @@
|
|||||||
<li><input type=text name=fileInfoT> : <span id=fileInfoTPreview></span></li>\
|
<li><input type=text name=fileInfoT> : <span id=fileInfoTPreview></span></li>\
|
||||||
<li>Link: %l (lowercase L)</li>\
|
<li>Link: %l (lowercase L)</li>\
|
||||||
<li>Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)</li>\
|
<li>Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)</li>\
|
||||||
<li>Resolution: %r (Displays PDF on /po/, for PDF\'s)</li>\
|
<li>Resolution: %r (Displays PDF on /po/, for PDFs)</li>\
|
||||||
Reply File Info Formatting\
|
Reply File Info Formatting\
|
||||||
<li><input type=text name=fileInfoR> : <span id=fileInfoRPreview></span></li>\
|
<li><input type=text name=fileInfoR> : <span id=fileInfoRPreview></span></li>\
|
||||||
<li>All thread formatters also work for reply formatting.</li>\
|
<li>All thread formatters also work for reply formatting.</li>\
|
||||||
@ -2312,16 +2320,19 @@
|
|||||||
return $.id('backlinkPreview').textContent = conf['backlink'].replace(/%id/, '123456789');
|
return $.id('backlinkPreview').textContent = conf['backlink'].replace(/%id/, '123456789');
|
||||||
},
|
},
|
||||||
fileInfo: function() {
|
fileInfo: function() {
|
||||||
FileInfo.ffType = this.name === 'fileInfoR' ? 0 : 1;
|
var type;
|
||||||
|
type = this.name === 'fileInfoR' ? 0 : 1;
|
||||||
FileInfo.data = {
|
FileInfo.data = {
|
||||||
link: '<a href="javascript:;">1329791824.png</a>',
|
link: '<a href="javascript:;">1329791824.png</a>',
|
||||||
size: 996,
|
size: 996,
|
||||||
unit: 'KB',
|
unit: 'KB',
|
||||||
resolution: '1366x768',
|
resolution: '1366x768',
|
||||||
filename: 'Untitled.png'
|
fullname: '[a.f.k.] Sayonara Zetsubou Sensei - 09.avi_snapshot_03.34_[2011.02.20_06.58.00].jpg',
|
||||||
|
shortname: '[a.f.k.] Sayonara Zetsubou Sen(...).jpg',
|
||||||
|
type: type
|
||||||
};
|
};
|
||||||
FileInfo.funks = FileInfo.setFormats();
|
FileInfo.setFormats();
|
||||||
return $.id("" + this.name + "Preview").innerHTML = FileInfo.funks[FileInfo.ffType](FileInfo);
|
return $.id("" + this.name + "Preview").innerHTML = FileInfo.funks[type](FileInfo);
|
||||||
},
|
},
|
||||||
favicon: function() {
|
favicon: function() {
|
||||||
Favicon["switch"]();
|
Favicon["switch"]();
|
||||||
@ -2765,14 +2776,16 @@
|
|||||||
funk: function(link) {
|
funk: function(link) {
|
||||||
var domain, href;
|
var domain, href;
|
||||||
domain = link.match(/(\w+)\.\w+\//)[1];
|
domain = link.match(/(\w+)\.\w+\//)[1];
|
||||||
href = link.replace(/(\$\d)/, function(fragment) {
|
href = link.replace(/(\$\d)/g, function(parameter) {
|
||||||
switch (fragment) {
|
switch (parameter) {
|
||||||
case '$1':
|
case '$1':
|
||||||
return "http://thumbs.4chan.org' + img.pathname.replace(/src(\\/\\d+).+$/, 'thumb$1s.jpg') + '";
|
return "http://thumbs.4chan.org' + img.pathname.replace(/src(\\/\\d+).+$/, 'thumb$1s.jpg') + '";
|
||||||
case '$2':
|
case '$2':
|
||||||
return "' + img.href + '";
|
return "' + img.href + '";
|
||||||
case '$3':
|
case '$3':
|
||||||
return "' + img.firstChild.getAttribute('md5').replace(/\=*$/, '') + '";
|
return "' + img.firstChild.getAttribute('md5').replace(/\=*$/, '') + '";
|
||||||
|
case '$4':
|
||||||
|
return g.BOARD;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
href = Function('img', "return '" + href + "'");
|
href = Function('img', "return '" + href + "'");
|
||||||
@ -2819,7 +2832,7 @@
|
|||||||
Time.foo();
|
Time.foo();
|
||||||
chanOffset = 5 - new Date().getTimezoneOffset() / 60;
|
chanOffset = 5 - new Date().getTimezoneOffset() / 60;
|
||||||
if ($.isDST()) chanOffset--;
|
if ($.isDST()) chanOffset--;
|
||||||
this.parse = Date.parse('10/11/11(Tue)18:53' === 1318351980000) ? function(node) {
|
this.parse = Date.parse('10/11/11(Tue)18:53') === 1318351980000 ? function(node) {
|
||||||
return new Date(Date.parse(node.textContent) + chanOffset * HOUR);
|
return new Date(Date.parse(node.textContent) + chanOffset * HOUR);
|
||||||
} : function(node) {
|
} : function(node) {
|
||||||
var day, hour, min, month, year, _, _ref;
|
var day, hour, min, month, year, _, _ref;
|
||||||
@ -2834,7 +2847,7 @@
|
|||||||
node: function(root) {
|
node: function(root) {
|
||||||
var node, time;
|
var node, time;
|
||||||
if (root.className === 'inline') return;
|
if (root.className === 'inline') return;
|
||||||
node = $('.posttime', root);
|
node = $('.posttime', root) || $('span[id]', root).previousSibling;
|
||||||
Time.date = Time.parse(node);
|
Time.date = Time.parse(node);
|
||||||
time = $.el('time', {
|
time = $.el('time', {
|
||||||
textContent: ' ' + Time.funk(Time) + ' '
|
textContent: ' ' + Time.funk(Time) + ' '
|
||||||
@ -2921,49 +2934,47 @@
|
|||||||
FileInfo = {
|
FileInfo = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (g.BOARD === 'f') return;
|
if (g.BOARD === 'f') return;
|
||||||
FileInfo.ffConf = ['fileInfoR', 'fileInfoT'];
|
this.setFormats();
|
||||||
FileInfo.ffMtrs = [/%([BKlLMnNrs])/g, /%([BKlMrs])/g];
|
|
||||||
FileInfo.ffRgex = [/File:\s(<a.+<\/a>)-\((?:Spoiler Image,\s)?([\d\.]+)\s([BKM]{1,2}),\s(\d+x\d+|PDF),\s<span\stitle=\"([^\"]+)\">/, /File:\s(<a.+<\/a>)-\((?:Spoiler Image,\s)?([\d\.]+)\s([BKM]{1,2}),\s(\d+x\d+|PDF)\)/];
|
|
||||||
this.parse = function(node) {
|
|
||||||
var filename, link, resolution, size, unit, _, _ref;
|
|
||||||
FileInfo.ffType = node.childNodes.length > 3 ? 0 : 1;
|
|
||||||
_ref = node.innerHTML.match(FileInfo.ffRgex[FileInfo.ffType]), _ = _ref[0], link = _ref[1], size = _ref[2], unit = _ref[3], resolution = _ref[4], filename = _ref[5];
|
|
||||||
return {
|
|
||||||
link: link,
|
|
||||||
size: size,
|
|
||||||
unit: unit,
|
|
||||||
resolution: resolution,
|
|
||||||
filename: filename
|
|
||||||
};
|
|
||||||
};
|
|
||||||
FileInfo.funks = FileInfo.setFormats();
|
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(root) {
|
||||||
var node;
|
var fullname, link, node, regexp, resolution, shortname, size, type, unit, _, _ref;
|
||||||
if (root.className === 'inline' || !(node = $('.filesize', root))) return;
|
if (root.className === 'inline' || !(node = $('.filesize', root))) return;
|
||||||
FileInfo.data = FileInfo.parse(node);
|
type = node.childElementCount === 2 ? 0 : 1;
|
||||||
return node.innerHTML = FileInfo.funks[FileInfo.ffType](FileInfo) + ' ';
|
regexp = type ? /^File: (<.+>)-\((?:Spoiler Image, )?([\d\.]+) (\w+), (\d+x\d+|PDF)/ : /^File: (<.+>)-\((?:Spoiler Image, )?([\d\.]+) (\w+), (\d+x\d+|PDF), <span title="(.+)">([^<]+)/;
|
||||||
|
_ref = node.innerHTML.match(regexp), _ = _ref[0], link = _ref[1], size = _ref[2], unit = _ref[3], resolution = _ref[4], fullname = _ref[5], shortname = _ref[6];
|
||||||
|
FileInfo.data = {
|
||||||
|
link: link,
|
||||||
|
size: size,
|
||||||
|
unit: unit,
|
||||||
|
resolution: resolution,
|
||||||
|
fullname: fullname,
|
||||||
|
shortname: shortname,
|
||||||
|
type: type
|
||||||
|
};
|
||||||
|
return node.innerHTML = FileInfo.funks[type](FileInfo);
|
||||||
},
|
},
|
||||||
setFormats: function() {
|
setFormats: function() {
|
||||||
var code, i, _results;
|
var code, format, funks, i, param;
|
||||||
_results = [];
|
funks = [];
|
||||||
for (i = 0; i <= 1; i++) {
|
for (i = 0; i <= 1; i++) {
|
||||||
code = conf[FileInfo.ffConf[i]].replace(FileInfo.ffMtrs[i], function(s, c) {
|
format = i ? conf['fileInfoT'] : conf['fileInfoR'];
|
||||||
|
param = i ? /%([BKlMrs])/g : /%([BKlLMnNrs])/g;
|
||||||
|
code = format.replace(param, function(s, c) {
|
||||||
if (c in FileInfo.formatters) {
|
if (c in FileInfo.formatters) {
|
||||||
return "' + FileInfo.formatters." + c + "() + '";
|
return "' + f.formatters." + c + "() + '";
|
||||||
} else {
|
} else {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_results.push(Function('FileInfo', "return '" + code + "'"));
|
funks.push(Function('f', "return '" + code + "'"));
|
||||||
}
|
}
|
||||||
return _results;
|
return this.funks = funks;
|
||||||
},
|
},
|
||||||
convertUnit: function(unitT) {
|
convertUnit: function(unitT) {
|
||||||
var i, size, unitF, units;
|
var i, size, unitF, units;
|
||||||
size = FileInfo.data.size;
|
size = this.data.size;
|
||||||
unitF = FileInfo.data.unit;
|
unitF = this.data.unit;
|
||||||
if (unitF !== unitT) {
|
if (unitF !== unitT) {
|
||||||
units = ['B', 'KB', 'MB'];
|
units = ['B', 'KB', 'MB'];
|
||||||
i = units.indexOf(unitF) - units.indexOf(unitT);
|
i = units.indexOf(unitF) - units.indexOf(unitT);
|
||||||
@ -2984,41 +2995,40 @@
|
|||||||
return "" + size + " " + unitT;
|
return "" + size + " " + unitT;
|
||||||
},
|
},
|
||||||
formatters: {
|
formatters: {
|
||||||
|
l: function() {
|
||||||
|
if (FileInfo.data.type === 0) {
|
||||||
|
return FileInfo.data.link.replace(/>\d+\.\w+</, ">" + (this.n()) + "<");
|
||||||
|
} else {
|
||||||
|
return FileInfo.data.link;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
L: function() {
|
||||||
|
return FileInfo.data.link.replace(/>\d+\.\w+</, ">" + FileInfo.data.fullname + "<");
|
||||||
|
},
|
||||||
|
n: function() {
|
||||||
|
if (FileInfo.data.fullname === FileInfo.data.shortname) {
|
||||||
|
return FileInfo.data.fullname;
|
||||||
|
} else {
|
||||||
|
return "<span class=filename><span class=fnfull>" + FileInfo.data.fullname + "</span><span class=fntrunc>" + FileInfo.data.shortname + "</span></span>";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
N: function() {
|
||||||
|
return FileInfo.data.fullname;
|
||||||
|
},
|
||||||
|
s: function() {
|
||||||
|
return "" + FileInfo.data.size + " " + FileInfo.data.unit;
|
||||||
|
},
|
||||||
B: function() {
|
B: function() {
|
||||||
return FileInfo.convertUnit('B');
|
return FileInfo.convertUnit('B');
|
||||||
},
|
},
|
||||||
K: function() {
|
K: function() {
|
||||||
return FileInfo.convertUnit('KB');
|
return FileInfo.convertUnit('KB');
|
||||||
},
|
},
|
||||||
l: function() {
|
|
||||||
if (FileInfo.ffType === 0) {
|
|
||||||
return FileInfo.data.link.replace(/>\d+\.\w+</, '>' + FileInfo.formatters.n() + '<');
|
|
||||||
} else {
|
|
||||||
return FileInfo.data.link;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
L: function() {
|
|
||||||
return FileInfo.data.link.replace(/>\d+\.\w+</, '>' + FileInfo.data.filename + '<');
|
|
||||||
},
|
|
||||||
M: function() {
|
M: function() {
|
||||||
return FileInfo.convertUnit('MB');
|
return FileInfo.convertUnit('MB');
|
||||||
},
|
},
|
||||||
n: function() {
|
|
||||||
var ext;
|
|
||||||
if ((ext = FileInfo.data.filename.lastIndexOf('.')) > 38) {
|
|
||||||
return '<span class=fnfull>' + FileInfo.data.filename + '</span><span class=fntrunc>' + FileInfo.data.filename.substr(0, 32) + ' (...)' + FileInfo.data.filename.substr(ext) + '</span>';
|
|
||||||
} else {
|
|
||||||
return FileInfo.data.filename;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
N: function() {
|
|
||||||
return FileInfo.data.filename;
|
|
||||||
},
|
|
||||||
r: function() {
|
r: function() {
|
||||||
return FileInfo.data.resolution;
|
return FileInfo.data.resolution;
|
||||||
},
|
|
||||||
s: function() {
|
|
||||||
return "" + FileInfo.data.size + " " + FileInfo.data.unit;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -3556,10 +3566,16 @@
|
|||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(root) {
|
||||||
var src, thumb;
|
var img, src, thumb;
|
||||||
if (root.hidden || !(thumb = $('img[md5]', root))) return;
|
if (root.hidden || !(thumb = $('img[md5]', root))) return;
|
||||||
src = thumb.parentNode.href;
|
src = thumb.parentNode.href;
|
||||||
if (/gif$/.test(src) && !/spoiler/.test(src)) return thumb.src = src;
|
if (/gif$/.test(src) && !/spoiler/.test(src)) {
|
||||||
|
img = $.el('img');
|
||||||
|
$.on(img, 'load', function() {
|
||||||
|
return thumb.src = src;
|
||||||
|
});
|
||||||
|
return img.src = src;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4120,7 +4136,8 @@ td.replyhider {\
|
|||||||
float: left;\
|
float: left;\
|
||||||
pointer-events: none;\
|
pointer-events: none;\
|
||||||
}\
|
}\
|
||||||
.filesize a:not(:hover) .fnfull, .filesize a:hover .fntrunc {\
|
.filename:hover > .fntrunc,\
|
||||||
|
.filename:not(:hover) > .fnfull {\
|
||||||
display: none;\
|
display: none;\
|
||||||
}\
|
}\
|
||||||
img[md5], img[md5] + img {\
|
img[md5], img[md5] + img {\
|
||||||
@ -4262,7 +4279,8 @@ td > .filesize > img[md5] {\
|
|||||||
.filetitle, .replytitle, .postername, .commentpostername, .postertrip {\
|
.filetitle, .replytitle, .postername, .commentpostername, .postertrip {\
|
||||||
background: none;\
|
background: none;\
|
||||||
}\
|
}\
|
||||||
.filter_highlight {\
|
.filter_highlight.op,\
|
||||||
|
.filter_highlight > td[id] {\
|
||||||
box-shadow: -5px 0 rgba(255,0,0,0.5);\
|
box-shadow: -5px 0 rgba(255,0,0,0.5);\
|
||||||
}\
|
}\
|
||||||
.filtered {\
|
.filtered {\
|
||||||
|
|||||||
@ -10,6 +10,7 @@ master
|
|||||||
Fix stubs if poster has unique ID.
|
Fix stubs if poster has unique ID.
|
||||||
- Mayhem
|
- Mayhem
|
||||||
You can now filter or highlight admin/mod posts.
|
You can now filter or highlight admin/mod posts.
|
||||||
|
New sauce parameter. $4: Current board.
|
||||||
|
|
||||||
2.27.1
|
2.27.1
|
||||||
- Mayhem
|
- Mayhem
|
||||||
|
|||||||
148
script.coffee
148
script.coffee
@ -104,13 +104,13 @@ config =
|
|||||||
'#http://imgur.com/upload?url=$2'
|
'#http://imgur.com/upload?url=$2'
|
||||||
'#http://omploader.org/upload?url1=$2'
|
'#http://omploader.org/upload?url1=$2'
|
||||||
'# "View Same" in archives:'
|
'# "View Same" in archives:'
|
||||||
'#http://archive.foolz.us/a/image/$3/'
|
'#http://archive.foolz.us/$4/image/$3/'
|
||||||
'#http://archive.installgentoo.net/g/image/$3'
|
'#http://archive.installgentoo.net/$4/image/$3'
|
||||||
].join '\n'
|
].join '\n'
|
||||||
time: '%m/%d/%y(%a)%H:%M'
|
time: '%m/%d/%y(%a)%H:%M'
|
||||||
backlink: '>>%id'
|
backlink: '>>%id'
|
||||||
fileInfoR: '%l, %s, %r'
|
fileInfoR: '%l (%s, %r)'
|
||||||
fileInfoT: '%l, %s, %r'
|
fileInfoT: '%l (%s, %r)'
|
||||||
favicon: 'ferongr'
|
favicon: 'ferongr'
|
||||||
hotkeys:
|
hotkeys:
|
||||||
openOptions: ['ctrl+o', 'Open Options']
|
openOptions: ['ctrl+o', 'Open Options']
|
||||||
@ -509,7 +509,10 @@ filter =
|
|||||||
else unless regexp.test value
|
else unless regexp.test value
|
||||||
return false
|
return false
|
||||||
if hl
|
if hl
|
||||||
$.addClass root, hl
|
if isOP
|
||||||
|
$.addClass root, hl
|
||||||
|
else
|
||||||
|
$.addClass root.parentNode, hl
|
||||||
if isOP and top and not g.REPLY
|
if isOP and top and not g.REPLY
|
||||||
# Put the highlighted OPs' threads on top of the board pages...
|
# Put the highlighted OPs' threads on top of the board pages...
|
||||||
thisThread = root.parentNode
|
thisThread = root.parentNode
|
||||||
@ -571,8 +574,8 @@ filter =
|
|||||||
return file.title
|
return file.title
|
||||||
false
|
false
|
||||||
dimensions: (root) ->
|
dimensions: (root) ->
|
||||||
if span = $ '.filesize', root
|
if (span = $ '.filesize', root) and match = span.textContent.match /\d+x\d+/
|
||||||
return span.textContent.match(/\d+x\d+/)[0]
|
return match[0]
|
||||||
return false
|
return false
|
||||||
filesize: (root) ->
|
filesize: (root) ->
|
||||||
if img = $ 'img[md5]', root
|
if img = $ 'img[md5]', root
|
||||||
@ -1411,8 +1414,8 @@ qr =
|
|||||||
# save selected reply's data
|
# save selected reply's data
|
||||||
for name in ['name', 'email', 'sub', 'com']
|
for name in ['name', 'email', 'sub', 'com']
|
||||||
input = $ "[name=#{name}]", qr.el
|
input = $ "[name=#{name}]", qr.el
|
||||||
$.on input, 'keyup', -> qr.selected[@name] = @value
|
for event in ['textInput', 'keyup', 'change', 'paste']
|
||||||
$.on input, 'change', -> qr.selected[@name] = @value
|
$.on input, event, -> qr.selected[@name] = @value
|
||||||
# sync between tabs
|
# sync between tabs
|
||||||
$.sync 'qr.persona', (persona) ->
|
$.sync 'qr.persona', (persona) ->
|
||||||
return unless qr.el.hidden
|
return unless qr.el.hidden
|
||||||
@ -1490,7 +1493,7 @@ qr =
|
|||||||
mode: 'regist'
|
mode: 'regist'
|
||||||
pwd: if m = d.cookie.match(/4chan_pass=([^;]+)/) then decodeURIComponent m[1] else $('[name=pwd]').value
|
pwd: if m = d.cookie.match(/4chan_pass=([^;]+)/) then decodeURIComponent m[1] else $('[name=pwd]').value
|
||||||
recaptcha_challenge_field: challenge
|
recaptcha_challenge_field: challenge
|
||||||
recaptcha_response_field: response
|
recaptcha_response_field: response + ' '
|
||||||
|
|
||||||
# Starting to upload might take some time.
|
# Starting to upload might take some time.
|
||||||
# Provide some feedback that we're starting to submit.
|
# Provide some feedback that we're starting to submit.
|
||||||
@ -1720,10 +1723,11 @@ options =
|
|||||||
<div>
|
<div>
|
||||||
<div class=warning><code>Sauce</code> is disabled.</div>
|
<div class=warning><code>Sauce</code> is disabled.</div>
|
||||||
Lines starting with a <code>#</code> will be ignored.
|
Lines starting with a <code>#</code> will be ignored.
|
||||||
<ul>These variables will be replaced by the corresponding url:
|
<ul>These parameters will be replaced by their corresponding values:
|
||||||
<li>$1: Thumbnail.</li>
|
<li>$1: Thumbnail url.</li>
|
||||||
<li>$2: Full image.</li>
|
<li>$2: Full image url.</li>
|
||||||
<li>$3: MD5 hash.</li>
|
<li>$3: MD5 hash.</li>
|
||||||
|
<li>$4: Current board.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<textarea name=sauces id=sauces></textarea>
|
<textarea name=sauces id=sauces></textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -1774,7 +1778,7 @@ options =
|
|||||||
<li><input type=text name=fileInfoT> : <span id=fileInfoTPreview></span></li>
|
<li><input type=text name=fileInfoT> : <span id=fileInfoTPreview></span></li>
|
||||||
<li>Link: %l (lowercase L)</li>
|
<li>Link: %l (lowercase L)</li>
|
||||||
<li>Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)</li>
|
<li>Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)</li>
|
||||||
<li>Resolution: %r (Displays PDF on /po/, for PDF\'s)</li>
|
<li>Resolution: %r (Displays PDF on /po/, for PDFs)</li>
|
||||||
Reply File Info Formatting
|
Reply File Info Formatting
|
||||||
<li><input type=text name=fileInfoR> : <span id=fileInfoRPreview></span></li>
|
<li><input type=text name=fileInfoR> : <span id=fileInfoRPreview></span></li>
|
||||||
<li>All thread formatters also work for reply formatting.</li>
|
<li>All thread formatters also work for reply formatting.</li>
|
||||||
@ -1900,15 +1904,17 @@ options =
|
|||||||
backlink: ->
|
backlink: ->
|
||||||
$.id('backlinkPreview').textContent = conf['backlink'].replace /%id/, '123456789'
|
$.id('backlinkPreview').textContent = conf['backlink'].replace /%id/, '123456789'
|
||||||
fileInfo: ->
|
fileInfo: ->
|
||||||
FileInfo.ffType = if @name is 'fileInfoR' then 0 else 1
|
type = if @name is 'fileInfoR' then 0 else 1
|
||||||
FileInfo.data =
|
FileInfo.data =
|
||||||
link : '<a href="javascript:;">1329791824.png</a>'
|
link: '<a href="javascript:;">1329791824.png</a>'
|
||||||
size : 996
|
size: 996
|
||||||
unit : 'KB'
|
unit: 'KB'
|
||||||
resolution: '1366x768'
|
resolution: '1366x768'
|
||||||
filename : 'Untitled.png'
|
fullname: '[a.f.k.] Sayonara Zetsubou Sensei - 09.avi_snapshot_03.34_[2011.02.20_06.58.00].jpg'
|
||||||
FileInfo.funks = FileInfo.setFormats()
|
shortname: '[a.f.k.] Sayonara Zetsubou Sen(...).jpg'
|
||||||
$.id("#{@name}Preview").innerHTML = FileInfo.funks[FileInfo.ffType] FileInfo
|
type: type
|
||||||
|
FileInfo.setFormats()
|
||||||
|
$.id("#{@name}Preview").innerHTML = FileInfo.funks[type] FileInfo
|
||||||
favicon: ->
|
favicon: ->
|
||||||
Favicon.switch()
|
Favicon.switch()
|
||||||
unread.update true
|
unread.update true
|
||||||
@ -2279,14 +2285,16 @@ sauce =
|
|||||||
|
|
||||||
funk: (link) ->
|
funk: (link) ->
|
||||||
domain = link.match(/(\w+)\.\w+\//)[1]
|
domain = link.match(/(\w+)\.\w+\//)[1]
|
||||||
href = link.replace /(\$\d)/, (fragment) ->
|
href = link.replace /(\$\d)/g, (parameter) ->
|
||||||
switch fragment
|
switch parameter
|
||||||
when '$1'
|
when '$1'
|
||||||
"http://thumbs.4chan.org' + img.pathname.replace(/src(\\/\\d+).+$/, 'thumb$1s.jpg') + '"
|
"http://thumbs.4chan.org' + img.pathname.replace(/src(\\/\\d+).+$/, 'thumb$1s.jpg') + '"
|
||||||
when '$2'
|
when '$2'
|
||||||
"' + img.href + '"
|
"' + img.href + '"
|
||||||
when '$3'
|
when '$3'
|
||||||
"' + img.firstChild.getAttribute('md5').replace(/\=*$/, '') + '"
|
"' + img.firstChild.getAttribute('md5').replace(/\=*$/, '') + '"
|
||||||
|
when '$4'
|
||||||
|
g.BOARD
|
||||||
href = Function 'img', "return '#{href}'"
|
href = Function 'img', "return '#{href}'"
|
||||||
(img) ->
|
(img) ->
|
||||||
$.el 'a',
|
$.el 'a',
|
||||||
@ -2321,7 +2329,7 @@ Time =
|
|||||||
chanOffset-- if $.isDST()
|
chanOffset-- if $.isDST()
|
||||||
|
|
||||||
@parse =
|
@parse =
|
||||||
if Date.parse '10/11/11(Tue)18:53' is 1318351980000
|
if Date.parse('10/11/11(Tue)18:53') is 1318351980000
|
||||||
(node) -> new Date Date.parse(node.textContent) + chanOffset*HOUR
|
(node) -> new Date Date.parse(node.textContent) + chanOffset*HOUR
|
||||||
else # Firefox and Opera do not parse 4chan's time format correctly
|
else # Firefox and Opera do not parse 4chan's time format correctly
|
||||||
(node) ->
|
(node) ->
|
||||||
@ -2335,7 +2343,8 @@ Time =
|
|||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (root) ->
|
||||||
return if root.className is 'inline'
|
return if root.className is 'inline'
|
||||||
node = $ '.posttime', root
|
# .posttime exists on every board except /f/
|
||||||
|
node = $('.posttime', root) or $('span[id]', root).previousSibling
|
||||||
Time.date = Time.parse node
|
Time.date = Time.parse node
|
||||||
time = $.el 'time',
|
time = $.el 'time',
|
||||||
textContent: ' ' + Time.funk(Time) + ' '
|
textContent: ' ' + Time.funk(Time) + ' '
|
||||||
@ -2391,40 +2400,45 @@ Time =
|
|||||||
FileInfo =
|
FileInfo =
|
||||||
init: ->
|
init: ->
|
||||||
return if g.BOARD is 'f'
|
return if g.BOARD is 'f'
|
||||||
FileInfo.ffConf = [ 'fileInfoR', 'fileInfoT' ]
|
@setFormats()
|
||||||
FileInfo.ffMtrs = [ /%([BKlLMnNrs])/g, /%([BKlMrs])/g ]
|
|
||||||
FileInfo.ffRgex = [ /File:\s(<a.+<\/a>)-\((?:Spoiler Image,\s)?([\d\.]+)\s([BKM]{1,2}),\s(\d+x\d+|PDF),\s<span\stitle=\"([^\"]+)\">/,
|
|
||||||
/File:\s(<a.+<\/a>)-\((?:Spoiler Image,\s)?([\d\.]+)\s([BKM]{1,2}),\s(\d+x\d+|PDF)\)/ ]
|
|
||||||
@parse = (node) ->
|
|
||||||
FileInfo.ffType = if node.childNodes.length > 3 then 0 else 1
|
|
||||||
[_, link, size, unit, resolution, filename] =
|
|
||||||
node.innerHTML.match FileInfo.ffRgex[FileInfo.ffType]
|
|
||||||
link : link
|
|
||||||
size : size
|
|
||||||
unit : unit
|
|
||||||
resolution: resolution
|
|
||||||
filename : filename
|
|
||||||
|
|
||||||
FileInfo.funks = FileInfo.setFormats()
|
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (root) ->
|
||||||
return if root.className is 'inline' or not node = $ '.filesize', root
|
return if root.className is 'inline' or not node = $ '.filesize', root
|
||||||
FileInfo.data = FileInfo.parse node
|
type = if node.childElementCount is 2 then 0 else 1
|
||||||
node.innerHTML = FileInfo.funks[FileInfo.ffType](FileInfo) + ' '
|
regexp =
|
||||||
|
if type
|
||||||
|
/^File: (<.+>)-\((?:Spoiler Image, )?([\d\.]+) (\w+), (\d+x\d+|PDF)/
|
||||||
|
else
|
||||||
|
/^File: (<.+>)-\((?:Spoiler Image, )?([\d\.]+) (\w+), (\d+x\d+|PDF), <span title="(.+)">([^<]+)/
|
||||||
|
[_, link, size, unit, resolution, fullname, shortname] =
|
||||||
|
node.innerHTML.match regexp
|
||||||
|
FileInfo.data =
|
||||||
|
link: link
|
||||||
|
size: size
|
||||||
|
unit: unit
|
||||||
|
resolution: resolution
|
||||||
|
fullname: fullname
|
||||||
|
shortname: shortname
|
||||||
|
type: type
|
||||||
|
node.innerHTML = FileInfo.funks[type] FileInfo
|
||||||
setFormats: ->
|
setFormats: ->
|
||||||
|
funks = []
|
||||||
for i in [0..1]
|
for i in [0..1]
|
||||||
code = conf[FileInfo.ffConf[i]].replace FileInfo.ffMtrs[i], (s, c) ->
|
format = if i then conf['fileInfoT'] else conf['fileInfoR']
|
||||||
|
param = if i then /%([BKlMrs])/g else /%([BKlLMnNrs])/g
|
||||||
|
code = format.replace param, (s, c) ->
|
||||||
if c of FileInfo.formatters
|
if c of FileInfo.formatters
|
||||||
"' + FileInfo.formatters.#{c}() + '"
|
"' + f.formatters.#{c}() + '"
|
||||||
else
|
else
|
||||||
s
|
s
|
||||||
Function 'FileInfo', "return '#{code}'"
|
funks.push Function 'f', "return '#{code}'"
|
||||||
|
@funks = funks
|
||||||
convertUnit: (unitT) ->
|
convertUnit: (unitT) ->
|
||||||
size = FileInfo.data.size
|
size = @data.size
|
||||||
unitF = FileInfo.data.unit
|
unitF = @data.unit
|
||||||
if unitF isnt unitT
|
if unitF isnt unitT
|
||||||
units = [ 'B', 'KB', 'MB' ]
|
units = ['B', 'KB', 'MB']
|
||||||
i = units.indexOf(unitF) - units.indexOf(unitT)
|
i = units.indexOf(unitF) - units.indexOf unitT
|
||||||
unitT = 'Bytes' if unitT is 'B'
|
unitT = 'Bytes' if unitT is 'B'
|
||||||
if i > 0
|
if i > 0
|
||||||
size *= 1024 while i-- > 0
|
size *= 1024 while i-- > 0
|
||||||
@ -2434,21 +2448,23 @@ FileInfo =
|
|||||||
size = size.toFixed 2
|
size = size.toFixed 2
|
||||||
"#{size} #{unitT}"
|
"#{size} #{unitT}"
|
||||||
formatters:
|
formatters:
|
||||||
|
l: ->
|
||||||
|
if FileInfo.data.type is 0
|
||||||
|
FileInfo.data.link.replace />\d+\.\w+</, ">#{@n()}<"
|
||||||
|
else
|
||||||
|
FileInfo.data.link
|
||||||
|
L: -> FileInfo.data.link.replace />\d+\.\w+</, ">#{FileInfo.data.fullname}<"
|
||||||
|
n: ->
|
||||||
|
if FileInfo.data.fullname is FileInfo.data.shortname
|
||||||
|
FileInfo.data.fullname
|
||||||
|
else
|
||||||
|
"<span class=filename><span class=fnfull>#{FileInfo.data.fullname}</span><span class=fntrunc>#{FileInfo.data.shortname}</span></span>"
|
||||||
|
N: -> FileInfo.data.fullname
|
||||||
|
s: -> "#{FileInfo.data.size} #{FileInfo.data.unit}"
|
||||||
B: -> FileInfo.convertUnit 'B'
|
B: -> FileInfo.convertUnit 'B'
|
||||||
K: -> FileInfo.convertUnit 'KB'
|
K: -> FileInfo.convertUnit 'KB'
|
||||||
l: -> if FileInfo.ffType is 0
|
|
||||||
FileInfo.data.link.replace />\d+\.\w+</, '>' + FileInfo.formatters.n() + '<'
|
|
||||||
else
|
|
||||||
FileInfo.data.link
|
|
||||||
L: -> FileInfo.data.link.replace />\d+\.\w+</, '>' + FileInfo.data.filename + '<'
|
|
||||||
M: -> FileInfo.convertUnit 'MB'
|
M: -> FileInfo.convertUnit 'MB'
|
||||||
n: -> if (ext = FileInfo.data.filename.lastIndexOf '.') > 38
|
|
||||||
'<span class=fnfull>' + FileInfo.data.filename + '</span><span class=fntrunc>' + FileInfo.data.filename.substr(0, 32) + ' (...)' + FileInfo.data.filename.substr(ext) + '</span>'
|
|
||||||
else
|
|
||||||
FileInfo.data.filename
|
|
||||||
N: -> FileInfo.data.filename
|
|
||||||
r: -> FileInfo.data.resolution
|
r: -> FileInfo.data.resolution
|
||||||
s: -> "#{FileInfo.data.size} #{FileInfo.data.unit}"
|
|
||||||
|
|
||||||
getTitle = (thread) ->
|
getTitle = (thread) ->
|
||||||
el = $ '.filetitle', thread
|
el = $ '.filetitle', thread
|
||||||
@ -2862,7 +2878,11 @@ imgGif =
|
|||||||
return if root.hidden or !thumb = $ 'img[md5]', root
|
return if root.hidden or !thumb = $ 'img[md5]', root
|
||||||
src = thumb.parentNode.href
|
src = thumb.parentNode.href
|
||||||
if /gif$/.test(src) and !/spoiler/.test src
|
if /gif$/.test(src) and !/spoiler/.test src
|
||||||
thumb.src = src
|
img = $.el 'img'
|
||||||
|
$.on img, 'load', ->
|
||||||
|
# Replace the thumbnail once the GIF has finished loading.
|
||||||
|
thumb.src = src
|
||||||
|
img.src = src
|
||||||
|
|
||||||
imgExpand =
|
imgExpand =
|
||||||
init: ->
|
init: ->
|
||||||
@ -3411,7 +3431,8 @@ td.replyhider {
|
|||||||
float: left;
|
float: left;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.filesize a:not(:hover) .fnfull, .filesize a:hover .fntrunc {
|
.filename:hover > .fntrunc,
|
||||||
|
.filename:not(:hover) > .fnfull {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
img[md5], img[md5] + img {
|
img[md5], img[md5] + img {
|
||||||
@ -3553,7 +3574,8 @@ td > .filesize > img[md5] {
|
|||||||
.filetitle, .replytitle, .postername, .commentpostername, .postertrip {
|
.filetitle, .replytitle, .postername, .commentpostername, .postertrip {
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
.filter_highlight {
|
.filter_highlight.op,
|
||||||
|
.filter_highlight > td[id] {
|
||||||
box-shadow: -5px 0 rgba(255,0,0,0.5);
|
box-shadow: -5px 0 rgba(255,0,0,0.5);
|
||||||
}
|
}
|
||||||
.filtered {
|
.filtered {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user