merge master

This commit is contained in:
James Campos 2011-09-17 19:53:11 -07:00
commit 6d25dc90e8
4 changed files with 70 additions and 66 deletions

View File

@ -6,7 +6,7 @@
// @license MIT; http://en.wikipedia.org/wiki/Mit_license // @license MIT; http://en.wikipedia.org/wiki/Mit_license
// @include http://boards.4chan.org/* // @include http://boards.4chan.org/*
// @include http://sys.4chan.org/* // @include http://sys.4chan.org/*
// @icon https://github.com/aeosynth/4chan-x/raw/gh-pages/favicon.png // @icon https://raw.github.com/aeosynth/4chan-x/gh-pages/favicon.png
// ==/UserScript== // ==/UserScript==
/* LICENSE /* LICENSE
@ -60,7 +60,7 @@
*/ */
(function() { (function() {
var $, $$, DAY, Favicon, HOUR, MINUTE, NAMESPACE, QR, SECOND, Time, anonymize, conf, config, d, expandComment, expandThread, firstRun, g, getTitle, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, main, nav, nodeInserted, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher; var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, QR, SECOND, Time, anonymize, conf, config, d, expandComment, expandThread, firstRun, g, getTitle, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, nav, nodeInserted, options, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher;
var __slice = Array.prototype.slice; var __slice = Array.prototype.slice;
config = { config = {
main: { main: {
@ -197,24 +197,12 @@
}; };
ui = { ui = {
dialog: function(id, position, html) { dialog: function(id, position, html) {
var el, left, top, _ref, _ref2; var el, saved;
el = d.createElement('div'); el = d.createElement('div');
el.className = 'reply dialog'; el.className = 'reply dialog';
el.innerHTML = html; el.innerHTML = html;
el.id = id; el.id = id;
left = position.left, top = position.top; el.style.cssText = (saved = localStorage["" + NAMESPACE + id + ".position"]) ? saved : position;
left = (_ref = localStorage["" + NAMESPACE + id + "Left"]) != null ? _ref : left;
top = (_ref2 = localStorage["" + NAMESPACE + id + "Top"]) != null ? _ref2 : top;
if (left) {
el.style.left = left;
} else {
el.style.right = 0;
}
if (top) {
el.style.top = top;
} else {
el.style.bottom = 0;
}
el.querySelector('div.move').addEventListener('mousedown', ui.dragstart, false); el.querySelector('div.move').addEventListener('mousedown', ui.dragstart, false);
return el; return el;
}, },
@ -257,8 +245,7 @@
var el, id; var el, id;
el = ui.el; el = ui.el;
id = el.id; id = el.id;
localStorage["" + NAMESPACE + id + "Left"] = el.style.left; localStorage["" + NAMESPACE + id + ".position"] = el.style.cssText;
localStorage["" + NAMESPACE + id + "Top"] = el.style.top;
d.removeEventListener('mousemove', ui.drag, false); d.removeEventListener('mousemove', ui.drag, false);
return d.removeEventListener('mouseup', ui.dragend, false); return d.removeEventListener('mouseup', ui.dragend, false);
}, },
@ -650,7 +637,7 @@
} }
}, },
parse: function(req, pathname, thread, a) { parse: function(req, pathname, thread, a) {
var body, br, link, next, quote, reply, table, tables, _i, _j, _k, _len, _len2, _len3, _ref, _ref2, _results; var body, br, href, link, next, quote, reply, table, tables, _i, _j, _k, _len, _len2, _len3, _ref, _ref2, _results;
if (req.status !== 200) { if (req.status !== 200) {
a.textContent = "" + req.status + " " + req.statusText; a.textContent = "" + req.status + " " + req.statusText;
$.unbind(a, 'click', expandThread.cb.toggle); $.unbind(a, 'click', expandThread.cb.toggle);
@ -670,8 +657,10 @@
_ref2 = $$('a.quotelink', reply); _ref2 = $$('a.quotelink', reply);
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
quote = _ref2[_j]; quote = _ref2[_j];
if (quote.getAttribute('href') === quote.hash) { if ((href = quote.getAttribute('href')) === quote.hash) {
quote.pathname = pathname; quote.pathname = pathname;
} else if (href !== quote.href) {
quote.href = "res/" + href;
} }
} }
link = $('a.quotejs', reply); link = $('a.quotejs', reply);
@ -1720,11 +1709,8 @@
html += "<div><label title='" + title + "'>" + name + "<input name='" + name + "' type=checkbox " + checked + "></label></div>"; html += "<div><label title='" + title + "'>" + name + "<input name='" + name + "' type=checkbox " + checked + "></label></div>";
} }
checked = conf['Auto Update'] ? 'checked' : ''; checked = conf['Auto Update'] ? 'checked' : '';
html += " <div><label title='Controls whether *this* thread auotmatically updates or not'>Auto Update This<input name='Auto Update This' type=checkbox " + checked + "></label></div> <div><label>Interval (s)<input name=Interval value=" + conf['Interval'] + " type=text></label></div> <div><input value='Update Now' type=button></div>"; html += " <div><label title='Controls whether *this* thread automatically updates or not'>Auto Update This<input name='Auto Update This' type=checkbox " + checked + "></label></div> <div><label>Interval (s)<input name=Interval value=" + conf['Interval'] + " type=text></label></div> <div><input value='Update Now' type=button></div>";
dialog = ui.dialog('updater', { dialog = ui.dialog('updater', 'bottom: 0; right: 0;', html);
bottom: '0',
right: '0'
}, html);
updater.count = $('#count', dialog); updater.count = $('#count', dialog);
updater.timer = $('#timer', dialog); updater.timer = $('#timer', dialog);
updater.br = $('br[clear]'); updater.br = $('br[clear]');
@ -1852,10 +1838,7 @@
init: function() { init: function() {
var favicon, html, input, inputs, _i, _len; var favicon, html, input, inputs, _i, _len;
html = '<div class=move>Thread Watcher</div>'; html = '<div class=move>Thread Watcher</div>';
watcher.dialog = ui.dialog('watcher', { watcher.dialog = ui.dialog('watcher', 'top: 50px; left: 0px;', html);
top: '50px',
left: '0px'
}, html);
$.add(d.body, watcher.dialog); $.add(d.body, watcher.dialog);
inputs = $$('.op input'); inputs = $$('.op input');
for (_i = 0, _len = inputs.length; _i < _len; _i++) { for (_i = 0, _len = inputs.length; _i < _len; _i++) {
@ -2269,7 +2252,7 @@
return $.addClass(this, 'inlined'); return $.addClass(this, 'inlined');
}, },
parse: function(req, pathname, id, threadID, inline) { parse: function(req, pathname, id, threadID, inline) {
var body, html, link, newInline, op, quote, reply, _i, _j, _len, _len2, _ref, _ref2; var body, href, html, link, newInline, op, quote, reply, _i, _j, _len, _len2, _ref, _ref2;
if (!inline.parentNode) { if (!inline.parentNode) {
return; return;
} }
@ -2297,8 +2280,10 @@
_ref2 = $$('a.quotelink', newInline); _ref2 = $$('a.quotelink', newInline);
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
quote = _ref2[_j]; quote = _ref2[_j];
if (quote.getAttribute('href') === quote.hash) { if ((href = quote.getAttribute('href')) === quote.hash) {
quote.pathname = pathname; quote.pathname = pathname;
} else if (!g.REPLY && href !== quote.href) {
quote.href = "res/" + href;
} }
} }
link = $('a.quotejs', newInline); link = $('a.quotejs', newInline);
@ -2337,7 +2322,7 @@
var el, id, qp, quote, replyID, threadID, _i, _len, _ref, _results; var el, id, qp, quote, replyID, threadID, _i, _len, _ref, _results;
qp = ui.el = $.el('div', { qp = ui.el = $.el('div', {
id: 'qp', id: 'qp',
className: 'replyhl' className: 'reply'
}); });
$.add(d.body, qp); $.add(d.body, qp);
id = this.hash.slice(1); id = this.hash.slice(1);
@ -2449,10 +2434,7 @@
threadStats.posts = 1; threadStats.posts = 1;
threadStats.images = $('.op img[md5]') ? 1 : 0; threadStats.images = $('.op img[md5]') ? 1 : 0;
html = "<div class=move><span id=postcount>" + threadStats.posts + "</span> / <span id=imagecount>" + threadStats.images + "</span></div>"; html = "<div class=move><span id=postcount>" + threadStats.posts + "</span> / <span id=imagecount>" + threadStats.images + "</span></div>";
dialog = ui.dialog('stats', { dialog = ui.dialog('stats', 'bottom: 0; left: 0;', html);
bottom: '0px',
left: '0px'
}, html);
dialog.className = 'dialog'; dialog.className = 'dialog';
threadStats.postcountEl = $('#postcount', dialog); threadStats.postcountEl = $('#postcount', dialog);
threadStats.imagecountEl = $('#imagecount', dialog); threadStats.imagecountEl = $('#imagecount', dialog);
@ -2793,10 +2775,10 @@
return $.unbind(window, 'click', firstRun.close); return $.unbind(window, 'click', firstRun.close);
} }
}; };
main = { Main = {
init: function() { init: function() {
var callback, cutoff, hiddenThreads, id, lastChecked, now, op, pathname, table, temp, timestamp, tzOffset, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _ref5; var callback, cutoff, hiddenThreads, id, lastChecked, now, op, pathname, table, temp, timestamp, tzOffset, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _ref5;
$.unbind(window, 'load', main.init); $.unbind(window, 'load', Main.init);
pathname = location.pathname.substring(1).split('/'); pathname = location.pathname.substring(1).split('/');
g.BOARD = pathname[0], temp = pathname[1]; g.BOARD = pathname[0], temp = pathname[1];
if (temp === 'res') { if (temp === 'res') {
@ -2816,6 +2798,7 @@
if (!$('#navtopr')) { if (!$('#navtopr')) {
return; return;
} }
$.bind(window, 'message', Main.message);
Favicon.init(); Favicon.init();
g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {}); g.hiddenReplies = $.get("hiddenReplies/" + g.BOARD + "/", {});
tzOffset = (new Date()).getTimezoneOffset() / 60; tzOffset = (new Date()).getTimezoneOffset() / 60;
@ -2826,6 +2809,7 @@
lastChecked = $.get('lastChecked', 0); lastChecked = $.get('lastChecked', 0);
now = Date.now(); now = Date.now();
if (lastChecked < now - 1 * DAY) { if (lastChecked < now - 1 * DAY) {
$.set('lastChecked', now);
cutoff = now - 7 * DAY; cutoff = now - 7 * DAY;
hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {});
for (id in hiddenThreads) { for (id in hiddenThreads) {
@ -2843,9 +2827,8 @@
} }
$.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads); $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads);
$.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies);
$.set('lastChecked', now);
} }
$.addStyle(main.css); $.addStyle(Main.css);
threading.init(); threading.init();
if (g.REPLY && (id = location.hash.slice(1)) && /\d/.test(id[0]) && !$.id(id)) { if (g.REPLY && (id = location.hash.slice(1)) && /\d/.test(id[0]) && !$.id(id)) {
scrollTo(0, d.body.scrollHeight); scrollTo(0, d.body.scrollHeight);
@ -2955,6 +2938,13 @@
return firstRun.init(); return firstRun.init();
} }
}, },
message: function(e) {
var data, origin;
origin = e.origin, data = e.data;
if (origin === 'http://sys.4chan.org') {
return qr.message(data);
}
},
css: '\ css: '\
/* dialog styling */\ /* dialog styling */\
div.dialog {\ div.dialog {\
@ -3090,7 +3080,7 @@
border: 1px solid;\ border: 1px solid;\
padding-bottom: 5px;\ padding-bottom: 5px;\
}\ }\
#qp input {\ #qp input, #qp .inline {\
display: none;\ display: none;\
}\ }\
.qphl {\ .qphl {\
@ -3180,8 +3170,8 @@
' '
}; };
if (d.body) { if (d.body) {
main.init(); Main.init();
} else { } else {
$.bind(window, 'load', main.init); $.bind(window, 'load', Main.init);
} }
}).call(this); }).call(this);

View File

@ -11,7 +11,7 @@ HEADER = """
// @license MIT; http://en.wikipedia.org/wiki/Mit_license // @license MIT; http://en.wikipedia.org/wiki/Mit_license
// @include http://boards.4chan.org/* // @include http://boards.4chan.org/*
// @include http://sys.4chan.org/* // @include http://sys.4chan.org/*
// @icon https://github.com/aeosynth/4chan-x/raw/gh-pages/favicon.png // @icon https://raw.github.com/aeosynth/4chan-x/gh-pages/favicon.png
// ==/UserScript== // ==/UserScript==
/* LICENSE /* LICENSE

View File

@ -1,5 +1,13 @@
master master
2.19.4
- mayhem
do not display inlined quotes within the quote preview
fix cross threads quotes in expanded threads or inlined cross quotes
default post styling for quote previews
- aeosynth
script auto updating
2.19.3 2.19.3
- mayhem - mayhem
quote inlining default styling (by xat) quote inlining default styling (by xat)

View File

@ -86,7 +86,7 @@ config =
# XXX chrome can't into `{log} = console` # XXX chrome can't into `{log} = console`
if console? if console?
# XXX scriptish - console.log.apply is not a function # XXX scriptish - console.log.apply is not a function
# https://github.com/scriptish/scriptish/issues/499 # https://github.com/scriptish/scriptish/issues/3
log = (arg) -> log = (arg) ->
console.log arg console.log arg
@ -124,11 +124,7 @@ ui =
el.className = 'reply dialog' el.className = 'reply dialog'
el.innerHTML = html el.innerHTML = html
el.id = id el.id = id
{left, top} = position el.style.cssText = if saved = localStorage["#{NAMESPACE}#{id}.position"] then saved else position
left = localStorage["#{NAMESPACE}#{id}Left"] ? left
top = localStorage["#{NAMESPACE}#{id}Top"] ? top
if left then el.style.left = left else el.style.right = 0
if top then el.style.top = top else el.style.bottom = 0
el.querySelector('div.move').addEventListener 'mousedown', ui.dragstart, false el.querySelector('div.move').addEventListener 'mousedown', ui.dragstart, false
el el
dragstart: (e) -> dragstart: (e) ->
@ -168,8 +164,7 @@ ui =
#a = (b = c.b, c).a; #a = (b = c.b, c).a;
{el} = ui {el} = ui
{id} = el {id} = el
localStorage["#{NAMESPACE}#{id}Left"] = el.style.left localStorage["#{NAMESPACE}#{id}.position"] = el.style.cssText
localStorage["#{NAMESPACE}#{id}Top"] = el.style.top
d.removeEventListener 'mousemove', ui.drag, false d.removeEventListener 'mousemove', ui.drag, false
d.removeEventListener 'mouseup', ui.dragend, false d.removeEventListener 'mouseup', ui.dragend, false
hover: (e) -> hover: (e) ->
@ -474,8 +469,10 @@ expandThread =
for reply in $$ 'td[id]', body for reply in $$ 'td[id]', body
for quote in $$ 'a.quotelink', reply for quote in $$ 'a.quotelink', reply
if quote.getAttribute('href') is quote.hash if (href = quote.getAttribute('href')) is quote.hash #add pathname to normal quotes
quote.pathname = pathname quote.pathname = pathname
else if href isnt quote.href #fix x-thread links, not x-board ones
quote.href = "res/#{href}"
link = $ 'a.quotejs', reply link = $ 'a.quotejs', reply
link.href = "res/#{thread.firstChild.id}##{reply.id}" link.href = "res/#{thread.firstChild.id}##{reply.id}"
link.nextSibling.href = "res/#{thread.firstChild.id}#q#{reply.id}" link.nextSibling.href = "res/#{thread.firstChild.id}#q#{reply.id}"
@ -1338,11 +1335,11 @@ updater =
checked = if conf['Auto Update'] then 'checked' else '' checked = if conf['Auto Update'] then 'checked' else ''
html += " html += "
<div><label title='Controls whether *this* thread auotmatically updates or not'>Auto Update This<input name='Auto Update This' type=checkbox #{checked}></label></div> <div><label title='Controls whether *this* thread automatically updates or not'>Auto Update This<input name='Auto Update This' type=checkbox #{checked}></label></div>
<div><label>Interval (s)<input name=Interval value=#{conf['Interval']} type=text></label></div> <div><label>Interval (s)<input name=Interval value=#{conf['Interval']} type=text></label></div>
<div><input value='Update Now' type=button></div>" <div><input value='Update Now' type=button></div>"
dialog = ui.dialog 'updater', bottom: '0', right: '0', html dialog = ui.dialog 'updater', 'bottom: 0; right: 0;', html
updater.count = $ '#count', dialog updater.count = $ '#count', dialog
updater.timer = $ '#timer', dialog updater.timer = $ '#timer', dialog
@ -1450,7 +1447,7 @@ updater =
watcher = watcher =
init: -> init: ->
html = '<div class=move>Thread Watcher</div>' html = '<div class=move>Thread Watcher</div>'
watcher.dialog = ui.dialog 'watcher', top: '50px', left: '0px', html watcher.dialog = ui.dialog 'watcher', 'top: 50px; left: 0px;', html
$.add d.body, watcher.dialog $.add d.body, watcher.dialog
#add watch buttons #add watch buttons
@ -1737,8 +1734,10 @@ quoteInline =
break break
newInline = quoteInline.table id, html newInline = quoteInline.table id, html
for quote in $$ 'a.quotelink', newInline for quote in $$ 'a.quotelink', newInline
if quote.getAttribute('href') is quote.hash if (href = quote.getAttribute('href')) is quote.hash #add pathname to normal quotes
quote.pathname = pathname quote.pathname = pathname
else if !g.REPLY and href isnt quote.href #fix x-thread links, not x-board ones
quote.href = "res/#{href}"
link = $ 'a.quotejs', newInline link = $ 'a.quotejs', newInline
link.href = "#{pathname}##{id}" link.href = "#{pathname}##{id}"
link.nextSibling.href = "#{pathname}#q#{id}" link.nextSibling.href = "#{pathname}#q#{id}"
@ -1761,7 +1760,7 @@ quotePreview =
mouseover: (e) -> mouseover: (e) ->
qp = ui.el = $.el 'div', qp = ui.el = $.el 'div',
id: 'qp' id: 'qp'
className: 'replyhl' className: 'reply'
$.add d.body, qp $.add d.body, qp
id = @hash[1..] id = @hash[1..]
@ -1832,7 +1831,7 @@ threadStats =
threadStats.posts = 1 threadStats.posts = 1
threadStats.images = if $ '.op img[md5]' then 1 else 0 threadStats.images = if $ '.op img[md5]' then 1 else 0
html = "<div class=move><span id=postcount>#{threadStats.posts}</span> / <span id=imagecount>#{threadStats.images}</span></div>" html = "<div class=move><span id=postcount>#{threadStats.posts}</span> / <span id=imagecount>#{threadStats.images}</span></div>"
dialog = ui.dialog 'stats', bottom: '0px', left: '0px', html dialog = ui.dialog 'stats', 'bottom: 0; left: 0;', html
dialog.className = 'dialog' dialog.className = 'dialog'
threadStats.postcountEl = $ '#postcount', dialog threadStats.postcountEl = $ '#postcount', dialog
threadStats.imagecountEl = $ '#imagecount', dialog threadStats.imagecountEl = $ '#imagecount', dialog
@ -2122,9 +2121,9 @@ firstRun =
$.rm $ '#overlay' $.rm $ '#overlay'
$.unbind window, 'click', firstRun.close $.unbind window, 'click', firstRun.close
main = Main =
init: -> init: ->
$.unbind window, 'load', main.init $.unbind window, 'load', Main.init
pathname = location.pathname.substring(1).split('/') pathname = location.pathname.substring(1).split('/')
[g.BOARD, temp] = pathname [g.BOARD, temp] = pathname
if temp is 'res' if temp is 'res'
@ -2142,6 +2141,7 @@ main =
if not $ '#navtopr' if not $ '#navtopr'
return return
$.bind window, 'message', Main.message
Favicon.init() Favicon.init()
g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {} g.hiddenReplies = $.get "hiddenReplies/#{g.BOARD}/", {}
tzOffset = (new Date()).getTimezoneOffset() / 60 tzOffset = (new Date()).getTimezoneOffset() / 60
@ -2152,6 +2152,8 @@ main =
lastChecked = $.get 'lastChecked', 0 lastChecked = $.get 'lastChecked', 0
now = Date.now() now = Date.now()
if lastChecked < now - 1*DAY if lastChecked < now - 1*DAY
$.set 'lastChecked', now
cutoff = now - 7*DAY cutoff = now - 7*DAY
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
@ -2165,9 +2167,8 @@ main =
$.set "hiddenThreads/#{g.BOARD}/", hiddenThreads $.set "hiddenThreads/#{g.BOARD}/", hiddenThreads
$.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies $.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies
$.set 'lastChecked', now
$.addStyle main.css $.addStyle Main.css
#major features #major features
threading.init() threading.init()
@ -2269,6 +2270,11 @@ main =
unless $.get 'firstrun' unless $.get 'firstrun'
firstRun.init() firstRun.init()
message: (e) ->
{origin, data} = e
if origin is 'http://sys.4chan.org'
qr.message data
css: ' css: '
/* dialog styling */ /* dialog styling */
div.dialog { div.dialog {
@ -2404,7 +2410,7 @@ main =
border: 1px solid; border: 1px solid;
padding-bottom: 5px; padding-bottom: 5px;
} }
#qp input { #qp input, #qp .inline {
display: none; display: none;
} }
.qphl { .qphl {
@ -2495,6 +2501,6 @@ main =
#XXX Opera will load early if script is saved w/o .user #XXX Opera will load early if script is saved w/o .user
if d.body if d.body
main.init() Main.init()
else else
$.bind window, 'load', main.init $.bind window, 'load', Main.init